Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.ir;
  
  import java.util.List;
  
  // Closures are contexts/scopes for the purpose of IR building.  They are self-contained and accumulate instructions
  // that don't merge into the flow of the containing scope.  They are manipulated as an unit.
  // Their parents are always execution scopes.
 
 public class IRClosure extends IRScope {
     public final Label startLabel// Label for the start of the closure (used to implement redo)
     public final Label endLabel;   // Label for the end of the closure (used to implement retry)
     public final int closureId;    // Unique id for this closure within the nearest ancestor method.
 
     private int nestingDepth;      // How many nesting levels within a method is this closure nested in?
 
     private BlockBody body;
 
     // for-loop body closures are special in that they dont really define a new variable scope.
     // They just silently reuse the parent scope.  This changes how variables are allocated (see IRMethod.java).
     private boolean isForLoopBody;
 
     // Block parameters
     private List<OperandblockArgs;

    
The parameter names, for Proc#parameters
 
     private String[] parameterList;
 
     public boolean addedGEBForUncaughtBreaks;

    
Used by cloning code
 
     private IRClosure(IRClosure cIRScope lexicalParent) {
         super(clexicalParent);
         this. = lexicalParent.getNextClosureId();
         setName("_CLOSURE_CLONE_" + );
         this. = getNewLabel(getName() + "_START");
         this. = getNewLabel(getName() + "_END");
         this. = (c.body instanceof InterpretedIRBlockBody19) ? new InterpretedIRBlockBody19(thisc.body.arity(), c.body.getArgumentType())
                                                                  : new InterpretedIRBlockBody(thisc.body.arity(), c.body.getArgumentType());
         this. = false;
     }
 
     public IRClosure(IRManager managerIRScope lexicalParentboolean isForLoopBody,
             int lineNumberStaticScope staticScopeArity arityint argumentTypeboolean is1_8) {
         this(managerlexicalParentlexicalParent.getFileName(), lineNumberstaticScopeisForLoopBody ? "_FOR_LOOP_" : "_CLOSURE_");
         this. = isForLoopBody;
         this. = new ArrayList<Operand>();
 
         if (getManager().isDryRun()) {
             this. = null;
         } else {
             this. = is1_8 ? new InterpretedIRBlockBody(thisarityargumentType)
                               : new InterpretedIRBlockBody19(thisarityargumentType);
             if ((staticScope != null) && !isForLoopBody) ((IRStaticScope)staticScope).setIRScope(this);
         }
 
         // set nesting depth -- after isForLoopBody value is set
         int n = 0;
         IRScope s = this;
         while (s instanceof IRClosure) {
             if (!s.isForLoopBody()) n++;
             s = s.getLexicalParent();
         }
         this. = n;
     }
 
     // Used by IREvalScript
     protected IRClosure(IRManager managerIRScope lexicalParentString fileNameint lineNumberStaticScope staticScopeString prefix) {
         super(managerlexicalParentnullfileNamelineNumberstaticScope);
 
         this. = false;
         this. = getNewLabel(prefix + "START");
         this. = getNewLabel(prefix + "END");
         this. = lexicalParent.getNextClosureId();
         setName(prefix + );
         this. = null;
         this. = new String[] {};
        // set nesting depth
        int n = 0;
        IRScope s = this;
        while (s instanceof IRClosure) {
            if (!s.isForLoopBody()) n++;
            s = s.getLexicalParent();
        }
        this. = n;
    }
    public void setParameterList(String[] parameterList) {
        this. = parameterList;
    }
    public String[] getParameterList() {
        return this.;
    }
    @Override
    public int getNextClosureId() {
        return getLexicalParent().getNextClosureId();
    }
    @Override
        throw new RuntimeException("Cannot get flip variables from closures.");
    }
    @Override
        ++;
    }
        ++;
        return new TemporaryClosureVariable(name);
    }
    @Override
    public Label getNewLabel() {
        return getNewLabel("CL" +  + "_LBL");
    }
    public String getScopeName() {
        return "Closure";
    }
    @Override
    public boolean isForLoopBody() {
        return ;
    }
    @Override
    public boolean isTopLocalVariableScope() {
        return false;
    }
    @Override
    public boolean isFlipScope() {
        return false;
    }
    @Override
    public void addInstr(Instr i) {
        // Accumulate block arguments
        if (i instanceof ReceiveRestArgInstr.add(new Splat(((ReceiveRestArgInstr)i).getResult()));
        else if (i instanceof ReceiveArgBase.add(((ReceiveArgBasei).getResult());
        super.addInstr(i);
    }
    public Operand[] getBlockArgs() {
        return .toArray(new Operand[.size()]);
    }
    public String toStringBody() {
        StringBuilder buf = new StringBuilder();
        buf.append(getName()).append(" = { \n");
        CFG c = getCFG();
        if (c != null) {
            buf.append("\nCFG:\n").append(c.toStringGraph()).append("\nInstructions:\n").append(c.toStringInstrs());
        } else {
            buf.append(toStringInstrs());
        }
        buf.append("\n}\n\n");
        return buf.toString();
    }
    public BlockBody getBlockBody() {
        return ;
    }
    @Override
    public LocalVariable findExistingLocalVariable(String nameint scopeDepth) {
        LocalVariable lvar = .getVariable(name);
        if (lvar != nullreturn lvar;
        int newDepth =  ? scopeDepth : scopeDepth - 1;
        return newDepth >= 0 ? getLexicalParent().findExistingLocalVariable(namenewDepth) : null;
    }
    public LocalVariable getNewLocalVariable(String nameint depth) {
        if (return getLexicalParent().getNewLocalVariable(namedepth);
        if (depth == 0) {
            LocalVariable lvar = new ClosureLocalVariable(thisname, 0, .);
            .putVariable(namelvar);
            return lvar;
        } else {
            return getLexicalParent().getNewLocalVariable(namedepth-1);
        }
    }
    @Override
    public LocalVariable getLocalVariable(String nameint scopeDepth) {
        if (return getLexicalParent().getLocalVariable(namescopeDepth);
        LocalVariable lvar = findExistingLocalVariable(namescopeDepth);
        if (lvar == nulllvar = getNewLocalVariable(namescopeDepth);
        // Create a copy of the variable usable at the right depth
        if (lvar.getScopeDepth() != scopeDepthlvar = lvar.cloneForDepth(scopeDepth);
        return lvar;
    }
    public int getNestingDepth() {
        return ;
    }
        // 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.
        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 IRClosures = s.getLexicalParent();
            if (s instanceof IRMethod) {
                blockVar = s.getNewLocalVariable(., 0);
                // Create a copy of the variable usable at the right depth
                if (getNestingDepth() != 0) blockVar = blockVar.cloneForDepth(getNestingDepth());
            } else {
                // Dummy var
                blockVar = getNewLocalVariable(., 0);
            }
        }
        return blockVar;
    }
        IRClosure clonedClosure = new IRClosure(thisii.getNewLexicalParentForClosure());
        clonedClosure.isForLoopBody = this.;
        clonedClosure.nestingDepth  = this.;
        clonedClosure.parameterList = this.;
        // Create a new inliner info object
        ii = ii.cloneForCloningClosure(clonedClosure);
        // clone the cfg, and all instructions
        clonedClosure.setCFG(getCFG().cloneForCloningClosure(clonedClosureii));
        return clonedClosure;
    }
    // Add a global-ensure-block to catch uncaught breaks
    // This is usually required only if this closure is being
    // used as a lambda, but it is safe to add this for any closure
    protected boolean addGEBForUncaughtBreaks() {
        // Nothing to do if already done
        if () {
            return false;
        }
        CFG        cfg = cfg();
        BasicBlock geb = cfg.getGlobalEnsureBB();
        if (geb == null) {
            geb = new BasicBlock(cfgnew Label("_GLOBAL_ENSURE_BLOCK"));
            Variable exc = getNewTemporaryVariable();
            geb.addInstr(new ReceiveExceptionInstr(excfalse)); // No need to check type since it is not used before rethrowing
            // Handle uncaught break using runtime helper
            // --> IRRuntimeHelpers.catchUncaughtBreakInLambdas(context, scope, bj, blockType)
            geb.addInstr(new RuntimeHelperCall(null"catchUncaughtBreakInLambdas"new Operand[]{exc} ));
            cfg.addGlobalEnsureBB(geb);
        } else {
            // SSS FIXME: Assumptions:
            //
            // First instr is a 'ReceiveExceptionInstr'
            // Last instr is a 'ThrowExceptionInstr'
            List<Instrinstrs = geb.getInstrs();
            Variable exc = ((ReceiveExceptionInstr)instrs.get(0)).getResult();
            instrs.set(instrs.size(), new RuntimeHelperCall(null"catchUncaughtBreakInLambdas"new Operand[]{exc} ));
        }
        // Update scope
         = true;
        return true;
    }
New to GrepCode? Check out our FAQ X