Package org.jruby.ir.operands

Examples of org.jruby.ir.operands.Variable


        }

        if ((cvarScope != null) && cvarScope.isNonSingletonClassBody()) {
            return new ScopeModule(cvarScope);
        } else {
            Variable tmp = s.getNewTemporaryVariable();
            s.addInstr(new GetClassVarContainerModuleInstr(tmp, s.getCurrentScopeVariable(), declContext ? null : getSelf(s)));
            return tmp;
        }
    }
View Full Code Here


        s.addInstr(new ConstMissingInstr(constVal, startingModule, name));
        s.addInstr(new LabelInstr(foundLabel));
    }

    private Operand searchConstInInheritanceHierarchy(IRScope s, Operand startingModule, String name) {
        Variable constVal = s.getNewTemporaryVariable();
        genInheritanceSearchInstrs(s, startingModule, constVal, s.getNewLabel(), true, name);
        return constVal;
    }
View Full Code Here

        return constVal;
    }

    private Operand searchConst(IRScope s, IRScope startingScope, String name) {
        boolean noPrivateConstants = (s != startingScope);
        Variable v = s.getNewTemporaryVariable();
/**
* SSS FIXME: Go back to a single instruction for now.
*
* Do not split search into lexical-search, inheritance-search, and const-missing instrs.
*
 
View Full Code Here

            Operand module = build(leftNode, s);
            return searchConstInInheritanceHierarchy(s, module, name);
        } else if (iVisited instanceof Colon2MethodNode) {
            Colon2MethodNode c2mNode = (Colon2MethodNode)iVisited;
            List<Operand> args       = setupCallArgs(null, s);
            Variable      callResult = s.getNewTemporaryVariable();
            Instr         callInstr  = CallInstr.create(callResult, new MethAddr(c2mNode.getName()),
                    null, args.toArray(new Operand[args.size()]), null);
            s.addInstr(callInstr);
            return callResult;
        } else {
View Full Code Here

    private Operand protectCodeWithRescue(IRScope m, CodeBlock protectedCode, Object[] protectedCodeArgs, CodeBlock rescueBlock, Object[] rescueBlockArgs) {
        // This effectively mimics a begin-rescue-end code block
        // Except this catches all exceptions raised by the protected code

        Variable rv = m.getNewTemporaryVariable();
        Label rBeginLabel = m.getNewLabel();
        Label rEndLabel   = m.getNewLabel();
        Label rescueLabel = m.getNewLabel();

        // Protected region code
        m.addInstr(new LabelInstr(rBeginLabel));
        m.addInstr(new ExceptionRegionStartMarkerInstr(rBeginLabel, rEndLabel, null, rescueLabel));
        Object v1 = protectedCode.run(protectedCodeArgs); // YIELD: Run the protected code block
        m.addInstr(new CopyInstr(rv, (Operand)v1));
        m.addInstr(new JumpInstr(rEndLabel));
        m.addInstr(new ExceptionRegionEndMarkerInstr());

        // SSS FIXME: Create an 'Exception' operand type to eliminate the constant lookup below
        // We could preload a set of constant objects that are preloaded at boot time and use them
        // directly in IR when we know there is no lookup involved.
        //
        // new Operand type: CachedClass(String name)?
        //
        // Some candidates: Exception, StandardError, Fixnum, Object, Boolean, etc.
        // So, when they are referenced, they are fetched directly from the runtime object
        // which probably already has cached references to these constants.
        //
        // But, unsure if this caching is safe ... so, just an idea here for now.

        // Rescue code
        Label caughtLabel = m.getNewLabel();
        Variable exc = m.getNewTemporaryVariable();
        Variable excType = m.getNewTemporaryVariable();

        // Receive 'exc' and verify that 'exc' is of ruby-type 'Exception'
        m.addInstr(new LabelInstr(rescueLabel));
        m.addInstr(new ReceiveExceptionInstr(exc));
        m.addInstr(new InheritanceSearchConstInstr(excType, new ObjectClass(), "Exception", false));
View Full Code Here

        }
    }

    protected Variable buildDefnCheckIfThenPaths(IRScope s, Label undefLabel, Operand defVal) {
        Label defLabel = s.getNewLabel();
        Variable tmpVar = getValueInTemporaryVariable(s, defVal);
        s.addInstr(new JumpInstr(defLabel));
        s.addInstr(new LabelInstr(undefLabel));
        s.addInstr(new CopyInstr(tmpVar, manager.getNil()));
        s.addInstr(new LabelInstr(defLabel));
        return tmpVar;
View Full Code Here

            case SELFNODE:
                return new StringLiteral("self");
            case CONSTNODE: {
                Label defLabel = s.getNewLabel();
                Label doneLabel = s.getNewLabel();
                Variable tmpVar  = s.getNewTemporaryVariable();
                String constName = ((ConstNode) node).getName();
                s.addInstr(new LexicalSearchConstInstr(tmpVar, startingSearchScope(s), constName));
                s.addInstr(BNEInstr.create(tmpVar, UndefinedValue.UNDEFINED, defLabel));
                s.addInstr(new InheritanceSearchConstInstr(tmpVar, findContainerModule(s), constName, false)); // SSS FIXME: should this be the current-module var or something else?
                s.addInstr(BNEInstr.create(tmpVar, UndefinedValue.UNDEFINED, defLabel));
                s.addInstr(new CopyInstr(tmpVar, manager.getNil()));
                s.addInstr(new JumpInstr(doneLabel));
                s.addInstr(new LabelInstr(defLabel));
                s.addInstr(new CopyInstr(tmpVar, new StringLiteral("constant")));
                s.addInstr(new LabelInstr(doneLabel));
                return tmpVar;
            }
            case GLOBALVARNODE:
                return buildDefinitionCheck(s, new GlobalIsDefinedInstr(s.getNewTemporaryVariable(), new StringLiteral(((GlobalVarNode) node).getName())), "global-variable");
            case INSTVARNODE:
                return buildDefinitionCheck(s, new HasInstanceVarInstr(s.getNewTemporaryVariable(), getSelf(s), new StringLiteral(((InstVarNode) node).getName())), "instance-variable");
            case YIELDNODE:
                return buildDefinitionCheck(s, new BlockGivenInstr(s.getNewTemporaryVariable()), "yield");
            case BACKREFNODE:
                return buildDefinitionCheck(s, new BackrefIsMatchDataInstr(s.getNewTemporaryVariable()), "$" + ((BackRefNode) node).getType());
            case NTHREFNODE: {
            // SSS FIXME: Is there a reason to do this all with low-level IR?
            // Can't this all be folded into a Java method that would be part
            // of the runtime library, which then can be used by buildDefinitionCheck method above?
            // This runtime library would be used both by the interpreter & the compiled code!

                /* -------------------------------------------------------------------------------------
                 * We have to generate IR for this:
                 *    v = backref; (!(v instanceof RubyMatchData) || v.group(n).nil?) ? nil : "$#{n}"
                 *
                 * which happens to be identical to: (where nthRef implicitly fetches backref again!)
                 *    v = backref; (!(v instanceof RubyMatchData) || nthRef(n).nil?) ? nil : "$#{n}"
                 *
                 * I am using the second form since it let us encode it in fewer IR instructions.
                 * But, note that this second form is not as clean as the first one plus it fetches backref twice!
                 * ------------------------------------------------------------------------------------- */
                int n = ((NthRefNode) node).getMatchNumber();
                Label undefLabel = s.getNewLabel();
                Variable tmpVar = s.getNewTemporaryVariable();
                s.addInstr(new BackrefIsMatchDataInstr(tmpVar));
                s.addInstr(BEQInstr.create(tmpVar, manager.getFalse(), undefLabel));
                // SSS FIXME:
                // - Can/should I use BEQInstr(new NthRef(n), manager.getNil(), undefLabel)? instead of .nil? & compare with flag?
                // - Or, even create a new IsNilInstr and NotNilInstr to represent optimized scenarios where
                //   the nil? method is not monkey-patched?
                // This matters because if String.nil? is monkey-patched, the two sequences can behave differently.
                s.addInstr(CallInstr.create(tmpVar, new MethAddr("nil?"), new NthRef(n), NO_ARGS, null));
                s.addInstr(BEQInstr.create(tmpVar, manager.getTrue(), undefLabel));
                return buildDefnCheckIfThenPaths(s, undefLabel, new StringLiteral("$" + n));
            }
            case COLON3NODE:
            case COLON2NODE: {
            // SSS FIXME: Is there a reason to do this all with low-level IR?
            // Can't this all be folded into a Java method that would be part
            // of the runtime library, which then can be used by buildDefinitionCheck method above?
            // This runtime library would be used both by the interpreter & the compiled code!

                final Colon3Node iVisited = (Colon3Node) node;
                final String name = iVisited.getName();

                // store previous exception for restoration if we rescue something
                Variable errInfo = s.getNewTemporaryVariable();
                s.addInstr(new GetErrorInfoInstr(errInfo));

                CodeBlock protectedCode = new CodeBlock() {
                    public Operand run(Object[] args) {
                        IRScope s    = (IRScope)args[0];
                        Node    n    = (Node)args[1];
                        String  name = (String)args[2];
                        Operand v    = (n instanceof Colon2Node) ? build(((Colon2Node)n).getLeftNode(), s) : new ObjectClass();

                        Variable tmpVar = s.getNewTemporaryVariable();
                        s.addInstr(new GetDefinedConstantOrMethodInstr(tmpVar, v, new StringLiteral(name)));
                        return tmpVar;
                    }
                };

                // rescue block
                CodeBlock rescueBlock = new CodeBlock() {
                    public Operand run(Object[] args) {
                        // Nothing to do -- ignore the exception, and restore stashed error info!
                        IRScope  m  = (IRScope)args[0];
                        m.addInstr(new RestoreErrorInfoInstr((Operand) args[1]));
                        return manager.getNil();
                    }
                };

                // Try verifying definition, and if we get an JumpException exception, process it with the rescue block above
                return protectCodeWithRescue(s, protectedCode, new Object[]{s, iVisited, name}, rescueBlock, new Object[] {s, errInfo});
            }
            case FCALLNODE: {
                /* ------------------------------------------------------------------
                 * Generate IR for:
                 *    r = self/receiver
                 *    mc = r.metaclass
                 *    return mc.methodBound(meth) ? buildGetArgumentDefn(..) : false
                 * ----------------------------------------------------------------- */
                Label undefLabel = s.getNewLabel();
                Variable tmpVar = s.getNewTemporaryVariable();
                StringLiteral mName = new StringLiteral(((FCallNode)node).getName());
                s.addInstr(new IsMethodBoundInstr(tmpVar, getSelf(s), mName));
                s.addInstr(BEQInstr.create(tmpVar, manager.getFalse(), undefLabel));
                Operand argsCheckDefn = buildGetArgumentDefinition(((FCallNode) node).getArgsNode(), s, "method");
                return buildDefnCheckIfThenPaths(s, undefLabel, argsCheckDefn);
            }
            case VCALLNODE:
                return buildDefinitionCheck(s, new IsMethodBoundInstr(s.getNewTemporaryVariable(), getSelf(s), new StringLiteral(((VCallNode) node).getName())), "method");
            case CALLNODE: {
            // SSS FIXME: Is there a reason to do this all with low-level IR?
            // Can't this all be folded into a Java method that would be part
            // of the runtime library?

                Label    undefLabel = s.getNewLabel();
                CallNode iVisited = (CallNode) node;
                Operand  receiverDefn = buildGetDefinition(iVisited.getReceiverNode(), s);
                s.addInstr(BEQInstr.create(receiverDefn, manager.getNil(), undefLabel));

                // protected main block
                CodeBlock protectedCode = new CodeBlock() {
                    public Operand run(Object[] args) {
                        IRScope  s          = (IRScope)args[0];
                        CallNode iVisited   = (CallNode)args[1];
                        String   methodName = iVisited.getName();
                        Variable tmpVar     = s.getNewTemporaryVariable();
                        Operand  receiver   = build(iVisited.getReceiverNode(), s);
                        s.addInstr(new MethodDefinedInstr(tmpVar, receiver, new StringLiteral(methodName)));
                        return buildDefnCheckIfThenPaths(s, (Label)args[2], tmpVar);
                    }
                };

                // rescue block
                CodeBlock rescueBlock = new CodeBlock() {
                    public Operand run(Object[] args) { return manager.getNil(); } // Nothing to do if we got an exception
                };

                // Try verifying definition, and if we get an exception, throw it out, and return nil
                return protectCodeWithRescue(s, protectedCode, new Object[]{s, iVisited, undefLabel}, rescueBlock, null);
            }
            case CLASSVARNODE: {
            // SSS FIXME: Is there a reason to do this all with low-level IR?
            // Can't this all be folded into a Java method that would be part
            // of the runtime library, which would be used both by the interpreter & the compiled code!

                /* --------------------------------------------------------------------------
                 * Generate IR for this ruby pseudo-code:
                 *   cm = tc.getCurrentScope.getStaticScope.getModule || self.metaclass
                 *   cm.isClassVarDefined ? "class variable" : nil
                 * ------------------------------------------------------------------------------ */
                ClassVarNode iVisited = (ClassVarNode) node;
                Operand cm = classVarDefinitionContainer(s);
                return buildDefinitionCheck(s, new ClassVarIsDefinedInstr(s.getNewTemporaryVariable(), cm, new StringLiteral(iVisited.getName())), "class variable");
            }
            case ATTRASSIGNNODE: {
                Label  undefLabel = s.getNewLabel();
                AttrAssignNode iVisited = (AttrAssignNode) node;
                Operand receiverDefn = buildGetDefinition(iVisited.getReceiverNode(), s);
                s.addInstr(BEQInstr.create(receiverDefn, manager.getNil(), undefLabel));

                // protected main block
                CodeBlock protectedCode = new CodeBlock() {
                    public Operand run(Object[] args) {
                        /* --------------------------------------------------------------------------
                         * This basically combines checks from CALLNODE and FCALLNODE
                         *
                         * Generate IR for this sequence
                         *
                         *    1. r  = receiver
                         *    2. mc = r.metaClass
                         *    3. v  = mc.getVisibility(methodName)
                         *    4. f  = !v || v.isPrivate? || (v.isProtected? && receiver/self?.kindof(mc.getRealClass))
                         *    5. return !f && mc.methodBound(attrmethod) ? buildGetArgumentDefn(..) : false
                         *
                         * Hide the complexity of instrs 2-4 into a verifyMethodIsPublicAccessible call
                         * which can executely entirely in Java-land.  No reason to expose the guts in IR.
                         * ------------------------------------------------------------------------------ */
                        IRScope s = (IRScope)args[0];
                        AttrAssignNode iVisited = (AttrAssignNode)args[1];
                        Label undefLabel = (Label)args[2];
                        StringLiteral attrMethodName = new StringLiteral(iVisited.getName());
                        Variable tmpVar     = s.getNewTemporaryVariable();
                        Operand  receiver   = build(iVisited.getReceiverNode(), s);
                        s.addInstr(new MethodIsPublicInstr(tmpVar, receiver, attrMethodName));
                        s.addInstr(BEQInstr.create(tmpVar, manager.getFalse(), undefLabel));
                        s.addInstr(new IsMethodBoundInstr(tmpVar, getSelf(s), attrMethodName));
                        s.addInstr(BEQInstr.create(tmpVar, manager.getFalse(), undefLabel));
                        Operand argsCheckDefn = buildGetArgumentDefinition(((AttrAssignNode) node).getArgsNode(), s, "assignment");
                        return buildDefnCheckIfThenPaths(s, undefLabel, argsCheckDefn);
                    }
                };

                // rescue block
                CodeBlock rescueBlock = new CodeBlock() {
                    public Operand run(Object[] args) { return manager.getNil(); } // Nothing to do if we got an exception
                };

                // Try verifying definition, and if we get an JumpException exception, process it with the rescue block above
                return protectCodeWithRescue(s, protectedCode, new Object[]{s, iVisited, undefLabel}, rescueBlock, null);
            }
            case ZSUPERNODE:
                return buildDefinitionCheck(s, new SuperMethodBoundInstr(s.getNewTemporaryVariable(), getSelf(s)), "super");
            case SUPERNODE: {
                Label undefLabel = s.getNewLabel();
                Variable tmpVar  = s.getNewTemporaryVariable();
                s.addInstr(new SuperMethodBoundInstr(tmpVar, getSelf(s)));
                s.addInstr(BEQInstr.create(tmpVar, manager.getFalse(), undefLabel));
                Operand superDefnVal = buildGetArgumentDefinition(((SuperNode) node).getArgsNode(), s, "super");
                return buildDefnCheckIfThenPaths(s, undefLabel, superDefnVal);
            }
View Full Code Here

        // SSS: Looks like we receive the arg in buildBlockArgsAssignment via the IterNode
        // We won't get here for argument receives!  So, buildDasgn is called for
        // assignments to block variables within a block.  As far as the IR is concerned,
        // this is just a simple copy
        int depth = dasgnNode.getDepth();
        Variable arg = s.getLocalVariable(dasgnNode.getName(), depth);
        Operand  value = build(dasgnNode.getValueNode(), s);
        s.addInstr(new CopyInstr(arg, value));
        return value;

        // IMPORTANT: The return value of this method is value, not arg!
View Full Code Here

        for (int j = 0; j < opt; j++, argIndex++) {
            // Jump to 'l' if this arg is not null.  If null, fall through and build the default value!
            Label l = s.getNewLabel();
            LocalAsgnNode n = (LocalAsgnNode)optArgs.get(j);
            String argName = n.getName();
            Variable av = s.getLocalVariable(argName, 0);
            if (s instanceof IRMethod) ((IRMethod)s).addArgDesc("opt", argName);
            s.addInstr(new ReceiveOptArgInstr18(av, argIndex));
            s.addInstr(BNEInstr.create(av, UndefinedValue.UNDEFINED, l)); // if 'av' is not undefined, go to default
            build(n, s);
            s.addInstr(new LabelInstr(l));
View Full Code Here

        // Receive block
        receiveMethodClosureArg(argsNode, s);
    }

    private void receiveMethodClosureArg(ArgsNode argsNode, IRScope s) {
        Variable blockVar = null;
        if (argsNode.getBlock() != null) {
            String blockArgName = argsNode.getBlock().getName();
            blockVar = s.getLocalVariable(blockArgName, 0);
            if (s instanceof IRMethod) ((IRMethod)s).addArgDesc("block", blockArgName);
            s.addInstr(new ReceiveClosureInstr(blockVar));
        }

        // SSS FIXME: This instruction is only needed if there is an yield instr somewhere!
        // In addition, store the block argument in an implicit block variable
        Variable implicitBlockArg = s.getImplicitBlockArg();
        if (blockVar == null) s.addInstr(new ReceiveClosureInstr(implicitBlockArg));
        else s.addInstr(new CopyInstr(implicitBlockArg, blockVar));
    }
View Full Code Here

TOP

Related Classes of org.jruby.ir.operands.Variable

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.