private InterpreterContext buildLambdaInner(LambdaNode node) { prepareImplicitState(); // recv_self, add frame block, etc) addCurrentScopeAndModule(); // %current_scope/%current_module receiveBlockArgs(node); Operand closureRetVal = node.getBody() == null ? manager.getNil() : build(node.getBody()); // can be U_NIL if the node is an if node with returns in both branches. if (closureRetVal != U_NIL) addInstr(new ReturnInstr(closureRetVal)); handleBreakAndReturnsInLambdas(); return scope.allocateInterpreterContext(instructions); }
private Operand buildOperand(Node node, IRScope s) throws NotCompilableException { switch (node.getNodeType()) { case ALIASNODE: return buildAlias((AliasNode) node, s); case ANDNODE: return buildAnd((AndNode) node, s); case ARGSCATNODE: return buildArgsCat((ArgsCatNode) node, s); case ARGSPUSHNODE: return buildArgsPush((ArgsPushNode) node, s); case ARRAYNODE: return buildArray(node, s); case ATTRASSIGNNODE: return buildAttrAssign((AttrAssignNode) node, s); case BACKREFNODE: return buildBackref((BackRefNode) node, s); case BEGINNODE: return buildBegin((BeginNode) node, s); case BIGNUMNODE: return buildBignum((BignumNode) node, s); case BLOCKNODE: return buildBlock((BlockNode) node, s); case BREAKNODE: return buildBreak((BreakNode) node, s); case CALLNODE: return buildCall((CallNode) node, s); case CASENODE: return buildCase((CaseNode) node, s); case CLASSNODE: return buildClass((ClassNode) node, s); case CLASSVARNODE: return buildClassVar((ClassVarNode) node, s); case CLASSVARASGNNODE: return buildClassVarAsgn((ClassVarAsgnNode) node, s); case CLASSVARDECLNODE: return buildClassVarDecl((ClassVarDeclNode) node, s); case COLON2NODE: return buildColon2((Colon2Node) node, s); case COLON3NODE: return buildColon3((Colon3Node) node, s); case CONSTDECLNODE: return buildConstDecl((ConstDeclNode) node, s); case CONSTNODE: return searchConst(s, s, ((ConstNode) node).getName()); case DASGNNODE: return buildDAsgn((DAsgnNode) node, s); case DEFINEDNODE: return buildGetDefinitionBase(((DefinedNode) node).getExpressionNode(), s); case DEFNNODE: return buildDefn((MethodDefNode) node, s); case DEFSNODE: return buildDefs((DefsNode) node, s); case DOTNODE: return buildDot((DotNode) node, s); case DREGEXPNODE: return buildDRegexp((DRegexpNode) node, s); case DSTRNODE: return buildDStr((DStrNode) node, s);
protected Operand buildWithOrder(Node node, boolean preserveOrder) { Operand value = build(node); // We need to preserve order in cases (like in presence of assignments) except that immutable // literals can never change value so we can still emit these out of order. return preserveOrder && !(value instanceof ImmutableLiteral) ? copyAndReturnValue(value) : value; }
public Operand buildMultipleAsgn(MultipleAsgnNode multipleAsgnNode, IRScope s) { Operand values = build(multipleAsgnNode.getValueNode(), s); Variable ret = getValueInTemporaryVariable(s, values); buildMultipleAsgnAssignment(multipleAsgnNode, s, null, ret); return ret; }
public Operand buildMultipleAsgn19(MultipleAsgnNode multipleAsgnNode) { Node valueNode = multipleAsgnNode.getValueNode(); Operand values = build(valueNode); Variable ret = getValueInTemporaryVariable(values); if (valueNode instanceof ArrayNode) { buildMultipleAsgn19Assignment(multipleAsgnNode, null, ret); } else { Variable tmp = createTemporaryVariable(); addInstr(new ToAryInstr(tmp, ret)); buildMultipleAsgn19Assignment(multipleAsgnNode, null, tmp); } return ret; }
switch (node.getNodeType()) { case ATTRASSIGNNODE: v = createTemporaryVariable(); receiveBlockArg(v, argsArray, argIndex, isSplat); buildAttrAssignAssignment(node, v); break; case DASGNNODE: { DAsgnNode dynamicAsgn = (DAsgnNode) node; v = getBlockArgVariable(dynamicAsgn.getName(), dynamicAsgn.getDepth()); receiveBlockArg(v, argsArray, argIndex, isSplat); break; v = createTemporaryVariable(); receiveBlockArg(v, argsArray, argIndex, isSplat); addInstr(new PutClassVariableInstr(classVarDefinitionContainer(), ((ClassVarAsgnNode)node).getName(), v)); break; case CONSTDECLNODE: v = createTemporaryVariable(); receiveBlockArg(v, argsArray, argIndex, isSplat); buildConstDeclAssignment((ConstDeclNode) node, v); break; case GLOBALASGNNODE: v = createTemporaryVariable(); receiveBlockArg(v, argsArray, argIndex, isSplat); addInstr(new PutGlobalVarInstr(((GlobalAsgnNode)node).getName(), v)); break; case INSTASGNNODE: v = createTemporaryVariable(); receiveBlockArg(v, argsArray, argIndex, isSplat);
case ATTRASSIGNNODE: v = s.getNewTemporaryVariable(); receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); buildAttrAssignAssignment(node, s, v); break; case DASGNNODE: { DAsgnNode dynamicAsgn = (DAsgnNode) node; v = getBlockArgVariable((IRClosure)s, dynamicAsgn.getName(), dynamicAsgn.getDepth()); receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); break; receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); s.addInstr(new PutClassVariableInstr(classVarDefinitionContainer(s), ((ClassVarAsgnNode)node).getName(), v)); break; case CLASSVARDECLNODE: v = s.getNewTemporaryVariable(); receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); s.addInstr(new PutClassVariableInstr(classVarDeclarationContainer(s), ((ClassVarDeclNode)node).getName(), v)); break; case CONSTDECLNODE: v = s.getNewTemporaryVariable(); receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); buildConstDeclAssignment((ConstDeclNode) node, s, v); break; case GLOBALASGNNODE: v = s.getNewTemporaryVariable(); receiveBlockArg(s, v, argsArray, argIndex, isClosureArg, isSplat); s.addInstr(new PutGlobalVarInstr(((GlobalAsgnNode)node).getName(), v)); break;
public void buildAssignment(Node node, Variable rhsVal) { switch (node.getNodeType()) { case ATTRASSIGNNODE: buildAttrAssignAssignment(node, rhsVal); break; case CLASSVARASGNNODE: addInstr(new PutClassVariableInstr(classVarDefinitionContainer(), ((ClassVarAsgnNode)node).getName(), rhsVal)); break; case CONSTDECLNODE: buildConstDeclAssignment((ConstDeclNode) node, rhsVal); break; case DASGNNODE: { DAsgnNode variable = (DAsgnNode) node; int depth = variable.getDepth(); addInstr(new CopyInstr(getLocalVariable(variable.getName(), depth), rhsVal)); break; addInstr(new PutGlobalVarInstr(((GlobalAsgnNode)node).getName(), rhsVal)); break; case INSTASGNNODE: addInstr(new PutFieldInstr(buildSelf(), ((InstAsgnNode)node).getName(), rhsVal)); break; case LOCALASGNNODE: { LocalAsgnNode localVariable = (LocalAsgnNode) node; int depth = localVariable.getDepth(); addInstr(new CopyInstr(getLocalVariable(localVariable.getName(), depth), rhsVal)); break; throw new NotCompilableException("Shouldn't get here; zeroarg does not do assignment: " + node);
public void buildAssignment(Node node, IRScope s, Variable rhsVal) { switch (node.getNodeType()) { case ATTRASSIGNNODE: buildAttrAssignAssignment(node, s, rhsVal); break; case CLASSVARASGNNODE: s.addInstr(new PutClassVariableInstr(classVarDefinitionContainer(s), ((ClassVarAsgnNode)node).getName(), rhsVal)); break; case CLASSVARDECLNODE: s.addInstr(new PutClassVariableInstr(classVarDeclarationContainer(s), ((ClassVarDeclNode)node).getName(), rhsVal)); break; case CONSTDECLNODE: buildConstDeclAssignment((ConstDeclNode) node, s, rhsVal); break; case DASGNNODE: { case INSTASGNNODE: s.addInstr(new PutFieldInstr(getSelf(s), ((InstAsgnNode)node).getName(), rhsVal)); break; case LOCALASGNNODE: { throw new NotCompilableException("Shouldn't get here; zeroarg does not do assignment: " + node); default: buildVersionSpecificAssignment(node, s, rhsVal);
public Operand buildBlock(BlockNode node) { Operand retVal = null; for (Node child : node.children()) { retVal = build(child); } // Value of the last expression in the block return retVal; }
public Operand buildFor(ForNode forNode) { Variable result = createTemporaryVariable(); Operand receiver = build(forNode.getIterNode()); Operand forBlock = buildForIter(forNode); CallInstr callInstr = new CallInstr(scope, CallType.NORMAL, result, manager.runtime.newSymbol(CommonByteLists.EACH), receiver, NO_ARGS, forBlock, scope.maybeUsingRefinements()); receiveBreakException(forBlock, callInstr); return result; }
public Operand buildOpAsgnAnd(OpAsgnAndNode andNode) { Label l = getNewLabel(); Operand v1 = build(andNode.getFirstNode()); Variable result = getValueInTemporaryVariable(v1); addInstr(createBranch(v1, manager.getFalse(), l)); Operand v2 = build(andNode.getSecondNode()); // This does the assignment! addInstr(new CopyInstr(result, v2)); addInstr(new LabelInstr(l)); return result; }
public Operand buildSClass(SClassNode sclassNode) { Operand receiver = build(sclassNode.getReceiverNode()); // FIXME: metaclass name should be a bytelist IRModuleBody body = new IRMetaClassBody(manager, scope, manager.getMetaClassName(), sclassNode.getLine(), sclassNode.getScope()); Variable sClassVar = addResultInstr(new DefineMetaClassInstr(createTemporaryVariable(), receiver, body)); // sclass bodies inherit the block of their containing method Variable processBodyResult = addResultInstr(new ProcessModuleBodyInstr(createTemporaryVariable(), sClassVar, scope.getYieldClosureVariable())); newIRBuilder(manager, body).buildModuleOrClassBody(sclassNode.getBodyNode(), sclassNode.getLine(), sclassNode.getEndLine()); return processBodyResult; }
private InterpreterContext buildRootInner(RootNode rootNode) { needsCodeCoverage = rootNode.needsCoverage(); prepareImplicitState(); // recv_self, add frame block, etc) addCurrentScopeAndModule(); // %current_scope/%current_module // Build IR for the tree and return the result of the expression tree addInstr(new ReturnInstr(build(rootNode.getBodyNode()))); scope.computeScopeFlagsEarly(instructions); // Root scope can receive returns now, so we add non-local return logic if necessary (2.5+) if (scope.canReceiveNonlocalReturns()) handleNonlocalReturnInMethod(); return scope.allocateInterpreterContext(instructions); }
public Operand buildYield(YieldNode node, Variable result) { if (scope instanceof IRScriptBody) throwSyntaxError(node, "Invalid yield"); boolean unwrap = true; Node argNode = node.getArgsNode(); // Get rid of one level of array wrapping if (argNode != null && (argNode instanceof ArrayNode) && ((ArrayNode)argNode).size() == 1) { argNode = ((ArrayNode)argNode).getLast(); unwrap = false; } Variable ret = result == null ? createTemporaryVariable() : result; if (argNode instanceof ArrayNode && unwrap) { addInstr(new YieldInstr(ret, scope.getYieldClosureVariable(), buildArray((ArrayNode)argNode, true), unwrap)); } else { addInstr(new YieldInstr(ret, scope.getYieldClosureVariable(), build(argNode), unwrap)); } return ret; }
public Operand buildArgsPush(final ArgsPushNode node) { Operand lhs = build(node.getFirstNode()); Operand rhs = build(node.getSecondNode()); return addResultInstr(new BuildCompoundArrayInstr(createTemporaryVariable(), lhs, rhs, true)); }
public Operand buildAttrAssignAssignment(Node node, Operand value) { final AttrAssignNode attrAssignNode = (AttrAssignNode) node; Operand obj = build(attrAssignNode.getReceiverNode()); Operand[] args = setupCallArgs(attrAssignNode.getArgsNode()); args = addArg(args, value); addInstr(AttrAssignInstr.create(scope, obj, attrAssignNode.getName(), args, scope.maybeUsingRefinements())); return value; }
public Operand buildColon2(final Colon2Node colon2) { Node lhs = colon2.getLeftNode(); // Colon2ImplicitNode - (module|class) Foo. Weird, but it is a wrinkle of AST inheritance. if (lhs == null) return searchConst(colon2.getName()); // Colon2ConstNode (Left::name) return searchModuleForConst(build(lhs), colon2.getName()); }
public Operand buildClassVarAsgn(final ClassVarAsgnNode classVarAsgnNode) { Operand val = build(classVarAsgnNode.getValueNode()); addInstr(new PutClassVariableInstr(classVarDefinitionContainer(), classVarAsgnNode.getName(), val)); return val; }