public Variable getNewInlineVariable(String inlinePrefix, Variable v) { if (v instanceof LocalVariable) { LocalVariable lv = (LocalVariable)v; return getLocalVariable(inlinePrefix + lv.getName(), lv.getScopeDepth()); } else { return getNewTemporaryVariable(); } }
@Override public Variable cloneForCloningClosure(InlinerInfo ii) { return new LocalVariable(name, scopeDepth, offset); }
private void decrementScopeDepth(LocalVariable v, IRScope s, Map<Operand, Operand> varRenameMap) { if (varRenameMap.get(v) == null) varRenameMap.put(v, v.cloneForDepth(v.getScopeDepth() - 1)); }
public Variable getRenamedVariable(Variable variable) { Variable renamed = super.getRenamedVariable(variable); // WrappedIRClosure operands in ensure blocks processing will cloneForInlining and inherit the top-scopes // SimpleCloneInfo instance which will already contain a depth 0 version of this "local" variable. We are // in a closure in early stages of cloning it around anywhere it should be for ensure (we copy same ensure // bodies to all possible exit paths) We know closures containing lvars will have the wrong depth. if (variable instanceof LocalVariable && !((LocalVariable) variable).isSameDepth((LocalVariable) renamed)) { return ((LocalVariable) renamed).cloneForDepth(((LocalVariable) variable).getScopeDepth()); } return renamed; }
private static void setResult(Object[] temp, DynamicScope currDynScope, Variable resultVar, Object result) { if (resultVar instanceof TemporaryVariable) { temp[((TemporaryVariable)resultVar).offset] = result; } else { LocalVariable lv = (LocalVariable)resultVar; currDynScope.setValue((IRubyObject)result, lv.getLocation(), lv.getScopeDepth()); } }
public Variable getRenamedVariable(Variable v) { Variable newVar = this.varRenameMap.get(v); if (newVar == null) { if (inClosureCloneMode) { // when cloning a closure, local vars and temps are not renamed newVar = v.cloneForCloningClosure(this); } else if (inClosureInlineMode) { // when inlining a closure, // - local var depths are reduced by 1 (to move them to the host scope) // - tmp vars are reallocated in the host scope if (v instanceof LocalVariable) { LocalVariable lv = (LocalVariable)v; int depth = lv.getScopeDepth(); newVar = getInlineHostScope().getLocalVariable(lv.getName(), depth > 1 ? depth - 1 : 0); } else { newVar = getInlineHostScope().getNewTemporaryVariable(); } } else { // when inlining a method, local vars and temps have to be renamed newVar = getInlineHostScope().getNewInlineVariable(inlineVarPrefix, v); } this.varRenameMap.put(v, newVar); } else if (inClosureCloneMode && (v instanceof LocalVariable)) { LocalVariable l_v = (LocalVariable)v; LocalVariable l_newVar = (LocalVariable)newVar; if (l_v.getScopeDepth() != l_newVar.getScopeDepth()) newVar = l_newVar.cloneForDepth(l_v.getScopeDepth()); } return newVar; }
@Override public String toString() { return isSelf() ? name : name + "(" + scopeDepth + ":" + offset + ")"; }
private TemporaryVariable getLocalVarReplacement(LocalVariable v, IRScope scope, Map<Operand, Operand> varRenameMap) { TemporaryVariable value = (TemporaryVariable)varRenameMap.get(v); if (value == null) { value = scope.getNewTemporaryVariable("%t_" + v.getName()); varRenameMap.put(v, value); } return value; }
private void identifyUndefinedVarsInClosure(Set<Variable> undefinedVars, IRClosure cl, int nestingLevel) { int clBaseDepth = nestingLevel + (cl.getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE) ? 0 : 1); cl.setUpUseDefLocalVarMaps(); for (LocalVariable lv: cl.getUsedLocalVariables()) { // This can happen where an outer scope variable // is not used in this scope but is used in a nested // scope. Ex: ~jruby/bin/ast:21 if (problem.getDFVar(lv) == null) { continue; } // Find variables which belong to the problem.getScope() if (lv.getScopeDepth() == clBaseDepth && !tmp.get(problem.getDFVar(lv))) { // We want lv suitable for initializing in this scope undefinedVars.add(!lv.isOuterScopeVar() ? lv : lv.cloneForDepth(0)); tmp.set(problem.getDFVar(lv)); } } // Recurse for (IRClosure nestedCl: cl.getClosures()) { identifyUndefinedVarsInClosure(undefinedVars, nestedCl, nestingLevel + 1); } }
public void addDFVar(Variable v) { DataFlowVar dfv = new DataFlowVar(this); dfVarMap.put(v, dfv); varDfVarMap.put(dfv.id, v); if ((v instanceof LocalVariable) && !((LocalVariable) v).isSelf()) { //System.out.println("Adding df var for " + v + ":" + dfv.id); int n = ((LocalVariable)v).getScopeDepth(); IRScope s = getScope(); while ((s != null) && (n >= 0)) { if (s instanceof IREvalScript) { // If a variable is at the topmost scope of the eval OR crosses an eval boundary, // it is going to be marked always live since it could be used by other evals (n = 0) // or by enclosing scopes (n > 0) alwaysLiveVars.add((LocalVariable)v); break; } s = s.getLexicalParent(); n--; } localVars.add((LocalVariable) v); } }
@Interp @Override public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block block) { return lvar.retrieve(context, self, currDynScope, temp); }
@Override public Instr cloneForInlining(InlinerInfo ii) { // SSS FIXME: Do we need to rename lvar really? It is just a name-proxy! return new StoreLocalVarInstr(value.cloneForInlining(ii), scope, (LocalVariable)lvar.cloneForInlining(ii)); }
/** When fixing up splats in nested closure we need to tweak the operand if it is a LocalVariable */ public Operand cloneForDepth(int n) { return array instanceof LocalVariable ? new Splat(((LocalVariable) array).cloneForDepth(n)) : this; }
for(LocalVariable l : lv) System.out.println(l.getName()+" : "+l.getSignature());
public boolean isSameDepth(LocalVariable other) { return getScopeDepth() == other.getScopeDepth(); }
@Override public void encode(IRWriterEncoder e) { super.encode(e); }
case IR_EXCEPTION: return IRException.decode(this); case LABEL: return Label.decode(this); case LOCAL_VARIABLE: return LocalVariable.decode(this); case NIL: return manager.getNil(); case NTH_REF: return NthRef.decode(this);
private static void setResult(Object[] temp, DynamicScope currDynScope, Variable resultVar, Object result) { if (resultVar instanceof TemporaryVariable) { temp[((TemporaryVariable)resultVar).offset] = result; } else { LocalVariable lv = (LocalVariable)resultVar; currDynScope.setValue((IRubyObject)result, lv.getLocation(), lv.getScopeDepth()); } }
public Variable getRenamedVariable(Variable v) { Variable newVar = this.varRenameMap.get(v); if (newVar == null) { if (inClosureCloneMode) { // when cloning a closure, local vars and temps are not renamed newVar = v.cloneForCloningClosure(this); } else if (inClosureInlineMode) { // when inlining a closure, // - local var depths are reduced by 1 (to move them to the host scope) // - tmp vars are reallocated in the host scope if (v instanceof LocalVariable) { LocalVariable lv = (LocalVariable)v; int depth = lv.getScopeDepth(); newVar = getInlineHostScope().getLocalVariable(lv.getName(), depth > 1 ? depth - 1 : 0); } else { newVar = getInlineHostScope().getNewTemporaryVariable(); } } else { // when inlining a method, local vars and temps have to be renamed newVar = getInlineHostScope().getNewInlineVariable(inlineVarPrefix, v); } this.varRenameMap.put(v, newVar); } else if (inClosureCloneMode && (v instanceof LocalVariable)) { LocalVariable l_v = (LocalVariable)v; LocalVariable l_newVar = (LocalVariable)newVar; if (l_v.getScopeDepth() != l_newVar.getScopeDepth()) newVar = l_newVar.cloneForDepth(l_v.getScopeDepth()); } return newVar; }
@Override public String toString() { return isSelf() ? name : name + "(" + scopeDepth + ":" + offset + ")"; }