/** 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; }
private void decrementScopeDepth(LocalVariable v, IRScope s, Map<Operand, Operand> varRenameMap) { if (varRenameMap.get(v) == null) varRenameMap.put(v, v.cloneForDepth(v.getScopeDepth() - 1)); }
/** 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; }
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; }
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; }
/** * Find or create a local variable. By default, scopes are assumed to * only check current depth. Blocks/Closures override this because they * have special nesting rules. */ public LocalVariable getLocalVariable(RubySymbol name, int scopeDepth) { LocalVariable lvar = findExistingLocalVariable(name, scopeDepth); if (lvar == null) { lvar = getNewLocalVariable(name, scopeDepth); } else if (lvar.getScopeDepth() != scopeDepth) { lvar = lvar.cloneForDepth(scopeDepth); } return lvar; }
/** * Find or create a local variable. By default, scopes are assumed to * only check current depth. Blocks/Closures override this because they * have special nesting rules. */ public LocalVariable getLocalVariable(RubySymbol name, int scopeDepth) { LocalVariable lvar = findExistingLocalVariable(name, scopeDepth); if (lvar == null) { lvar = getNewLocalVariable(name, scopeDepth); } else if (lvar.getScopeDepth() != scopeDepth) { lvar = lvar.cloneForDepth(scopeDepth); } return lvar; }
public void decrementLVarScopeDepth() { setOperand(0, getLocalVar().cloneForDepth(getLocalVar().getScopeDepth()-1)); }
public void decrementLVarScopeDepth() { setOperand2(getLocalVar().cloneForDepth(getLocalVar().getScopeDepth()-1)); }
public void decrementLVarScopeDepth() { setOperand2(getLocalVar().cloneForDepth(getLocalVar().getScopeDepth()-1)); }
public void decrementLVarScopeDepth() { setOperand(0, getLocalVar().cloneForDepth(getLocalVar().getScopeDepth()-1)); }
@Override public LocalVariable getLocalVariable(String name, int scopeDepth) { if (isForLoopBody) return getLexicalParent().getLocalVariable(name, scopeDepth); LocalVariable lvar = findExistingLocalVariable(name, scopeDepth); if (lvar == null) lvar = getNewLocalVariable(name, scopeDepth); // Create a copy of the variable usable at the right depth if (lvar.getScopeDepth() != scopeDepth) lvar = lvar.cloneForDepth(scopeDepth); return lvar; }
@Override public LocalVariable getLocalVariable(String name, int scopeDepth) { if (isForLoopBody) return getLexicalParent().getLocalVariable(name, scopeDepth); LocalVariable lvar = findExistingLocalVariable(name, scopeDepth); if (lvar == null) lvar = getNewLocalVariable(name, scopeDepth); // Create a copy of the variable usable at the right depth if (lvar.getScopeDepth() != scopeDepth) lvar = lvar.cloneForDepth(scopeDepth); return lvar; }
public LocalVariable getNewLocalVariable(RubySymbol name, int depth) { if (depth == 0 && !(this instanceof IRFor)) { LocalVariable lvar = new ClosureLocalVariable(name, 0, getStaticScope().addVariableThisScope(name.idString())); localVars.put(name, lvar); return lvar; } else { // IRFor does not have it's own state if (!(this instanceof IRFor)) flags.add(IRFlags.ACCESS_PARENTS_LOCAL_VARIABLES); IRScope s = this; int d = depth; do { // account for for-loops while (s instanceof IRFor) { depth++; s = s.getLexicalParent(); } // walk up d--; if (d >= 0) s = s.getLexicalParent(); } while (d >= 0); return s.getNewLocalVariable(name, 0).cloneForDepth(depth); } }
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); } }
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 LocalVariable getNewLocalVariable(RubySymbol name, int depth) { if (depth == 0 && !(this instanceof IRFor)) { LocalVariable lvar = new ClosureLocalVariable(name, 0, getStaticScope().addVariableThisScope(name.idString())); localVars.put(name, lvar); return lvar; } else { // IRFor does not have it's own state if (!(this instanceof IRFor)) flags.add(IRFlags.ACCESS_PARENTS_LOCAL_VARIABLES); IRScope s = this; int d = depth; do { // account for for-loops while (s instanceof IRFor) { depth++; s = s.getLexicalParent(); } // walk up d--; if (d >= 0) s = s.getLexicalParent(); } while (d >= 0); return s.getNewLocalVariable(name, 0).cloneForDepth(depth); } }
public LocalVariable getImplicitBlockArg() { // SSS: FIXME: Ugly! We cannot use 'getLocalVariable(Variable.BLOCK, getNestingDepth())' because // of scenario 3. below. Can we clean up this code? // // 1. If the variable has previously been defined, return a copy usable at the closure's nesting depth. // 2. If not, and if the closure is ultimately nested within a method, build a local variable that will // be defined in that method. // 3. If not, and if the closure is not nested within a method, the closure can never receive a block. // So, we could return 'null', but it creates problems for IR generation. So, for this scenario, // we simply create a dummy var at depth 0 (meaning, it is local to the closure itself) and return it. LocalVariable blockVar = findExistingLocalVariable(Variable.BLOCK, getNestingDepth()); if (blockVar != null) { // Create a copy of the variable usable at the right depth if (blockVar.getScopeDepth() != getNestingDepth()) blockVar = blockVar.cloneForDepth(getNestingDepth()); } else { IRScope s = this; while (s instanceof IRClosure) s = s.getLexicalParent(); if (s instanceof IRMethod) { blockVar = s.getNewLocalVariable(Variable.BLOCK, 0); // Create a copy of the variable usable at the right depth if (getNestingDepth() != 0) blockVar = blockVar.cloneForDepth(getNestingDepth()); } else { // Dummy var blockVar = getNewLocalVariable(Variable.BLOCK, 0); } } return blockVar; }
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; }