public IRClosure cloneForInlining(CloneInfo ii) { IRClosure clonedClosure; IRScope lexicalParent = ii.getScope(); if (ii instanceof SimpleCloneInfo && !((SimpleCloneInfo)ii).isEnsureBlockCloneMode()) { clonedClosure = new IRClosure(this, lexicalParent, closureId, getName()); } else { int id = lexicalParent.getNextClosureId(); ByteList fullName = lexicalParent.getName().getBytes().dup(); fullName.append(CLOSURE_CLONE); fullName.append(new Integer(id).toString().getBytes()); clonedClosure = new IRClosure(this, lexicalParent, id, getManager().runtime.newSymbol(fullName)); } // WrappedIRClosure should always have a single unique IRClosure in them so we should // not end up adding n copies of the same closure as distinct clones... lexicalParent.addClosure(clonedClosure); return cloneForInlining(ii, clonedClosure); }
public IRClosure cloneForClonedInstr(InlinerInfo ii) { IRClosure clonedClosure = new IRClosure(this, ii.getNewLexicalParentForClosure()); clonedClosure.isForLoopBody = this.isForLoopBody; clonedClosure.nestingDepth = this.nestingDepth; clonedClosure.parameterList = this.parameterList; // Create a new inliner info object ii = ii.cloneForCloningClosure(clonedClosure); // clone the cfg, and all instructions clonedClosure.setCFG(getCFG().cloneForCloningClosure(clonedClosure, ii)); return clonedClosure; }
public IRClosure cloneForClonedInstr(InlinerInfo ii) { IRClosure clonedClosure = new IRClosure(this, ii.getNewLexicalParentForClosure()); clonedClosure.isForLoopBody = this.isForLoopBody; clonedClosure.nestingDepth = this.nestingDepth; clonedClosure.parameterList = this.parameterList; // Create a new inliner info object ii = ii.cloneForCloningClosure(clonedClosure); // clone the cfg, and all instructions clonedClosure.setCFG(getCFG().cloneForCloningClosure(clonedClosure, ii)); return clonedClosure; }
public IRClosure cloneForInlining(CloneInfo ii) { IRClosure clonedClosure; IRScope lexicalParent = ii.getScope(); if (ii instanceof SimpleCloneInfo && !((SimpleCloneInfo)ii).isEnsureBlockCloneMode()) { clonedClosure = new IRClosure(this, lexicalParent, closureId, getName()); } else { int id = lexicalParent.getNextClosureId(); ByteList fullName = lexicalParent.getName().getBytes().dup(); fullName.append(CLOSURE_CLONE); fullName.append(new Integer(id).toString().getBytes()); clonedClosure = new IRClosure(this, lexicalParent, id, getManager().runtime.newSymbol(fullName)); } // WrappedIRClosure should always have a single unique IRClosure in them so we should // not end up adding n copies of the same closure as distinct clones... lexicalParent.addClosure(clonedClosure); return cloneForInlining(ii, clonedClosure); }
public Operand buildIter(final IterNode iterNode) { IRClosure closure = new IRClosure(manager, scope, iterNode.getLine(), iterNode.getScope(), Signature.from(iterNode), needsCodeCoverage); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, closure).buildIterInner(iterNode); return new WrappedIRClosure(buildSelf(), closure); }
public Operand buildIter(final IterNode iterNode) { IRClosure closure = new IRClosure(manager, scope, iterNode.getLine(), iterNode.getScope(), Signature.from(iterNode), needsCodeCoverage); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, closure).buildIterInner(iterNode); return new WrappedIRClosure(buildSelf(), closure); }
public static IRScope createScope(IRManager manager, IRScopeType type, RubySymbol name, int line, IRScope lexicalParent, Signature signature, StaticScope staticScope) { switch (type) { case CLASS_BODY: return new IRClassBody(manager, lexicalParent, name, line, staticScope); case METACLASS_BODY: return new IRMetaClassBody(manager, lexicalParent, manager.getMetaClassName(), line, staticScope); case INSTANCE_METHOD: return new IRMethod(manager, lexicalParent, null, name, true, line, staticScope, false); case CLASS_METHOD: return new IRMethod(manager, lexicalParent, null, name, false, line, staticScope, false); case MODULE_BODY: return new IRModuleBody(manager, lexicalParent, name, line, staticScope); case SCRIPT_BODY: return new IRScriptBody(manager, name, staticScope); case FOR: return new IRFor(manager, lexicalParent, line, staticScope, signature); case CLOSURE: return new IRClosure(manager, lexicalParent, line, staticScope, signature); case EVAL_SCRIPT: // SSS FIXME: This is broken right now -- the isModuleEval arg has to be persisted and then read back. return new IREvalScript(manager, lexicalParent, lexicalParent.getFileName(), line, staticScope, EvalType.NONE); } throw new RuntimeException("No such scope type: " + type); } }
public static IRScope createScope(IRManager manager, IRScopeType type, RubySymbol name, int line, IRScope lexicalParent, Signature signature, StaticScope staticScope) { switch (type) { case CLASS_BODY: return new IRClassBody(manager, lexicalParent, name, line, staticScope); case METACLASS_BODY: return new IRMetaClassBody(manager, lexicalParent, manager.getMetaClassName(), line, staticScope); case INSTANCE_METHOD: return new IRMethod(manager, lexicalParent, null, name, true, line, staticScope, false); case CLASS_METHOD: return new IRMethod(manager, lexicalParent, null, name, false, line, staticScope, false); case MODULE_BODY: return new IRModuleBody(manager, lexicalParent, name, line, staticScope); case SCRIPT_BODY: return new IRScriptBody(manager, name, staticScope); case FOR: return new IRFor(manager, lexicalParent, line, staticScope, signature); case CLOSURE: return new IRClosure(manager, lexicalParent, line, staticScope, signature); case EVAL_SCRIPT: // SSS FIXME: This is broken right now -- the isModuleEval arg has to be persisted and then read back. return new IREvalScript(manager, lexicalParent, lexicalParent.getFileName(), line, staticScope, EvalType.NONE); } throw new RuntimeException("No such scope type: " + type); } }
public Operand buildLambda(LambdaNode node) { IRClosure closure = new IRClosure(manager, scope, node.getLine(), node.getScope(), Signature.from(node), needsCodeCoverage); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, closure).buildLambdaInner(node); Variable lambda = createTemporaryVariable(); WrappedIRClosure lambdaBody = new WrappedIRClosure(closure.getSelf(), closure); addInstr(new BuildLambdaInstr(lambda, lambdaBody, scope.getFile(), node.getLine())); return lambda; }
public Operand buildLambda(LambdaNode node) { IRClosure closure = new IRClosure(manager, scope, node.getLine(), node.getScope(), Signature.from(node), needsCodeCoverage); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, closure).buildLambdaInner(node); Variable lambda = createTemporaryVariable(); WrappedIRClosure lambdaBody = new WrappedIRClosure(closure.getSelf(), closure); addInstr(new BuildLambdaInstr(lambda, lambdaBody, scope.getFile(), node.getLine())); return lambda; }
public Operand buildPostExe(PostExeNode postExeNode) { IRScope topLevel = scope.getRootLexicalScope(); IRScope nearestLVarScope = scope.getNearestTopLocalVariableScope(); IRClosure endClosure = new IRClosure(manager, scope, postExeNode.getLine(), nearestLVarScope.getStaticScope(), Signature.from(postExeNode), CommonByteLists._END_, true); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, endClosure).buildPrePostExeInner(postExeNode.getBodyNode()); // Add an instruction in 's' to record the end block in the 'topLevel' scope. // SSS FIXME: IR support for end-blocks that access vars in non-toplevel-scopes // might be broken currently. We could either fix it or consider dropping support // for END blocks altogether or only support them in the toplevel. Not worth the pain. addInstr(new RecordEndBlockInstr(topLevel, new WrappedIRClosure(buildSelf(), endClosure))); return manager.getNil(); }
public Operand buildPostExe(PostExeNode postExeNode) { IRScope topLevel = scope.getRootLexicalScope(); IRScope nearestLVarScope = scope.getNearestTopLocalVariableScope(); IRClosure endClosure = new IRClosure(manager, scope, postExeNode.getLine(), nearestLVarScope.getStaticScope(), Signature.from(postExeNode), CommonByteLists._END_, true); // Create a new nested builder to ensure this gets its own IR builder state like the ensure block stack newIRBuilder(manager, endClosure).buildPrePostExeInner(postExeNode.getBodyNode()); // Add an instruction in 's' to record the end block in the 'topLevel' scope. // SSS FIXME: IR support for end-blocks that access vars in non-toplevel-scopes // might be broken currently. We could either fix it or consider dropping support // for END blocks altogether or only support them in the toplevel. Not worth the pain. addInstr(new RecordEndBlockInstr(topLevel, new WrappedIRClosure(buildSelf(), endClosure))); return manager.getNil(); }
public Operand buildPostExe(PostExeNode postExeNode, IRScope s) { IRClosure endClosure = new IRClosure(manager, s, false, postExeNode.getPosition().getStartLine(), postExeNode.getScope(), Arity.procArityOf(postExeNode.getVarNode()), postExeNode.getArgumentType(), !is1_9() && !is2_0()); // Set up %current_scope and %current_module endClosure.addInstr(new CopyInstr(endClosure.getCurrentScopeVariable(), new CurrentScope(endClosure))); endClosure.addInstr(new CopyInstr(endClosure.getCurrentModuleVariable(), new ScopeModule(endClosure))); build(postExeNode.getBodyNode(), endClosure); // Add an instruction to record the end block at runtime s.addInstr(new RecordEndBlockInstr(s, endClosure)); return manager.getNil(); }
public Operand buildPreExe(PreExeNode preExeNode, IRScope s) { IRClosure beginClosure = new IRClosure(manager, s, false, preExeNode.getPosition().getStartLine(), preExeNode.getScope(), Arity.procArityOf(preExeNode.getVarNode()), preExeNode.getArgumentType(), !is1_9() && !is2_0()); // Set up %current_scope and %current_module beginClosure.addInstr(new CopyInstr(beginClosure.getCurrentScopeVariable(), new CurrentScope(beginClosure))); beginClosure.addInstr(new CopyInstr(beginClosure.getCurrentModuleVariable(), new ScopeModule(beginClosure))); build(preExeNode.getBodyNode(), beginClosure); // Record the begin block at IR build time s.getTopLevelScope().recordBeginBlock(beginClosure); return manager.getNil(); }
public Operand buildPostExe(PostExeNode postExeNode, IRScope s) { IRClosure endClosure = new IRClosure(manager, s, false, postExeNode.getPosition().getStartLine(), postExeNode.getScope(), Arity.procArityOf(postExeNode.getVarNode()), postExeNode.getArgumentType(), !is1_9() && !is2_0()); // Set up %current_scope and %current_module endClosure.addInstr(new CopyInstr(endClosure.getCurrentScopeVariable(), new CurrentScope(endClosure))); endClosure.addInstr(new CopyInstr(endClosure.getCurrentModuleVariable(), new ScopeModule(endClosure))); build(postExeNode.getBodyNode(), endClosure); // Add an instruction to record the end block at runtime s.addInstr(new RecordEndBlockInstr(s, endClosure)); return manager.getNil(); }
public Operand buildPreExe(PreExeNode preExeNode, IRScope s) { IRClosure beginClosure = new IRClosure(manager, s, false, preExeNode.getPosition().getStartLine(), preExeNode.getScope(), Arity.procArityOf(preExeNode.getVarNode()), preExeNode.getArgumentType(), !is1_9() && !is2_0()); // Set up %current_scope and %current_module beginClosure.addInstr(new CopyInstr(beginClosure.getCurrentScopeVariable(), new CurrentScope(beginClosure))); beginClosure.addInstr(new CopyInstr(beginClosure.getCurrentModuleVariable(), new ScopeModule(beginClosure))); build(preExeNode.getBodyNode(), beginClosure); // Record the begin block at IR build time s.getTopLevelScope().recordBeginBlock(beginClosure); return manager.getNil(); }
public Operand buildLambda(LambdaNode node, IRScope s) { IRClosure closure = new IRClosure(manager, s, false, node.getPosition().getStartLine(), node.getScope(), Arity.procArityOf(node.getArgs()), node.getArgumentType(), true); s.addClosure(closure); // Create a new nested builder to ensure this gets its own IR builder state // like the ensure block stack IRBuilder closureBuilder = newIRBuilder(manager); // Receive self closure.addInstr(new ReceiveSelfInstr(getSelf(closure))); // args closureBuilder.receiveBlockArgs(node, closure); closureBuilder.receiveBlockClosureArg(node.getBlockVarNode(), closure); Operand closureRetVal = node.getBody() == null ? manager.getNil() : closureBuilder.build(node.getBody(), closure); // can be U_NIL if the node is an if node with returns in both branches. if (closureRetVal != U_NIL) closure.addInstr(new ReturnInstr(closureRetVal)); // Added as part of 'prepareForInterpretation' code. // catchUncaughtBreakInLambdas(closure); Variable lambda = s.getNewTemporaryVariable(); s.addInstr(new BuildLambdaInstr(lambda, closure, node.getPosition())); return lambda; }
public Operand buildLambda(LambdaNode node, IRScope s) { IRClosure closure = new IRClosure(manager, s, false, node.getPosition().getStartLine(), node.getScope(), Arity.procArityOf(node.getArgs()), node.getArgumentType(), true); s.addClosure(closure); // Create a new nested builder to ensure this gets its own IR builder state // like the ensure block stack IRBuilder closureBuilder = newIRBuilder(manager); // Receive self closure.addInstr(new ReceiveSelfInstr(getSelf(closure))); // args closureBuilder.receiveBlockArgs(node, closure); closureBuilder.receiveBlockClosureArg(node.getBlockVarNode(), closure); Operand closureRetVal = node.getBody() == null ? manager.getNil() : closureBuilder.build(node.getBody(), closure); // can be U_NIL if the node is an if node with returns in both branches. if (closureRetVal != U_NIL) closure.addInstr(new ReturnInstr(closureRetVal)); // Added as part of 'prepareForInterpretation' code. // catchUncaughtBreakInLambdas(closure); Variable lambda = s.getNewTemporaryVariable(); s.addInstr(new BuildLambdaInstr(lambda, closure, node.getPosition())); return lambda; }
public Operand buildForIter(final ForNode forNode, IRScope s) { // Create a new closure context IRClosure closure = new IRClosure(manager, s, true, forNode.getPosition().getStartLine(), forNode.getScope(), Arity.procArityOf(forNode.getVarNode()), forNode.getArgumentType(), !is1_9() && !is2_0()); s.addClosure(closure); // Create a new nested builder to ensure this gets its own IR builder state // like the ensure block stack IRBuilder forBuilder = newIRBuilder(manager); // Receive self closure.addInstr(new ReceiveSelfInstr(getSelf(closure))); // Build args Node varNode = forNode.getVarNode(); if (varNode != null && varNode.getNodeType() != null) forBuilder.receiveBlockArgs(forNode, closure); // Set %current_scope = <current-scope> // Set %current_module = <current-module> closure.addInstr(new CopyInstr(closure.getCurrentScopeVariable(), new CurrentScope(closure))); closure.addInstr(new CopyInstr(closure.getCurrentModuleVariable(), new ScopeModule(closure))); // Thread poll on entry of closure closure.addInstr(new ThreadPollInstr()); // Start label -- used by redo! closure.addInstr(new LabelInstr(closure.startLabel)); // Build closure body and return the result of the closure Operand closureRetVal = forNode.getBodyNode() == null ? manager.getNil() : forBuilder.build(forNode.getBodyNode(), closure); if (closureRetVal != U_NIL) { // can be null if the node is an if node with returns in both branches. closure.addInstr(new ReturnInstr(closureRetVal)); } return new WrappedIRClosure(closure); }
public Operand buildForIter(final ForNode forNode, IRScope s) { // Create a new closure context IRClosure closure = new IRClosure(manager, s, true, forNode.getPosition().getStartLine(), forNode.getScope(), Arity.procArityOf(forNode.getVarNode()), forNode.getArgumentType(), !is1_9() && !is2_0()); s.addClosure(closure); // Create a new nested builder to ensure this gets its own IR builder state // like the ensure block stack IRBuilder forBuilder = newIRBuilder(manager); // Receive self closure.addInstr(new ReceiveSelfInstr(getSelf(closure))); // Build args Node varNode = forNode.getVarNode(); if (varNode != null && varNode.getNodeType() != null) forBuilder.receiveBlockArgs(forNode, closure); // Set %current_scope = <current-scope> // Set %current_module = <current-module> closure.addInstr(new CopyInstr(closure.getCurrentScopeVariable(), new CurrentScope(closure))); closure.addInstr(new CopyInstr(closure.getCurrentModuleVariable(), new ScopeModule(closure))); // Thread poll on entry of closure closure.addInstr(new ThreadPollInstr()); // Start label -- used by redo! closure.addInstr(new LabelInstr(closure.startLabel)); // Build closure body and return the result of the closure Operand closureRetVal = forNode.getBodyNode() == null ? manager.getNil() : forBuilder.build(forNode.getBodyNode(), closure); if (closureRetVal != U_NIL) { // can be null if the node is an if node with returns in both branches. closure.addInstr(new ReturnInstr(closureRetVal)); } return new WrappedIRClosure(closure); }