@Override public Instr clone(CloneInfo ii) { Variable var = getResult(); return new RuntimeHelperCall(var == null ? null : ii.getRenamedVariable(var), helperMethod, cloneOperands(ii)); }
@Override public Instr cloneForInlining(InlinerInfo ii) { // SSS FIXME: array of args cloning should be part of utility class Operand[] clonedArgs = new Operand[args.length]; for (int i = 0; i < args.length; i++) { clonedArgs[i] = args[i].cloneForInlining(ii); } Variable var = getResult(); return new RuntimeHelperCall(var == null ? null : ii.getRenamedVariable(var), helperMethod, clonedArgs); }
@Override public Instr clone(CloneInfo ii) { Variable var = getResult(); return new RuntimeHelperCall(var == null ? null : ii.getRenamedVariable(var), helperMethod, cloneOperands(ii)); }
@Override public Instr cloneForInlining(InlinerInfo ii) { // SSS FIXME: array of args cloning should be part of utility class Operand[] clonedArgs = new Operand[args.length]; for (int i = 0; i < args.length; i++) { clonedArgs[i] = args[i].cloneForInlining(ii); } Variable var = getResult(); return new RuntimeHelperCall(var == null ? null : ii.getRenamedVariable(var), helperMethod, clonedArgs); }
public static RuntimeHelperCall decode(IRReaderDecoder d) { return new RuntimeHelperCall(d.decodeVariable(), Methods.fromOrdinal(d.decodeInt()), d.decodeOperandArray()); }
public static RuntimeHelperCall decode(IRReaderDecoder d) { return new RuntimeHelperCall(d.decodeVariable(), Methods.fromOrdinal(d.decodeInt()), d.decodeOperandArray()); }
geb.addInstr(new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} )); cfg.addGlobalEnsureBB(geb); } else { instrs.set(instrs.size(), new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} ));
public Operand buildHash(HashNode hashNode) { List<KeyValuePair<Operand, Operand>> args = new ArrayList<>(); boolean hasAssignments = hashNode.containsVariableAssignment(); Variable hash = null; for (KeyValuePair<Node, Node> pair: hashNode.getPairs()) { Node key = pair.getKey(); Operand keyOperand; if (key == null) { // Splat kwarg [e.g. {**splat1, a: 1, **splat2)] if (hash == null) { // No hash yet. Define so order is preserved. hash = copyAndReturnValue(new Hash(args)); args = new ArrayList<>(); // Used args but we may find more after the splat so we reset } else if (!args.isEmpty()) { addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, new Hash(args) })); args = new ArrayList<>(); } Operand splat = buildWithOrder(pair.getValue(), hasAssignments); addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, splat})); continue; } else { keyOperand = buildWithOrder(key, hasAssignments); } args.add(new KeyValuePair<>(keyOperand, buildWithOrder(pair.getValue(), hasAssignments))); } if (hash == null) { // non-**arg ordinary hash hash = copyAndReturnValue(new Hash(args)); } else if (!args.isEmpty()) { // ordinary hash values encountered after a **arg addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, new Hash(args) })); } return hash; }
geb.addInstr(new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} )); cfg.addGlobalEnsureBB(geb); } else { instrs.set(instrs.size(), new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} ));
public Operand buildHash(HashNode hashNode) { List<KeyValuePair<Operand, Operand>> args = new ArrayList<>(); boolean hasAssignments = hashNode.containsVariableAssignment(); Variable hash = null; for (KeyValuePair<Node, Node> pair: hashNode.getPairs()) { Node key = pair.getKey(); Operand keyOperand; if (key == null) { // Splat kwarg [e.g. {**splat1, a: 1, **splat2)] if (hash == null) { // No hash yet. Define so order is preserved. hash = copyAndReturnValue(new Hash(args)); args = new ArrayList<>(); // Used args but we may find more after the splat so we reset } else if (!args.isEmpty()) { addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, new Hash(args) })); args = new ArrayList<>(); } Operand splat = buildWithOrder(pair.getValue(), hasAssignments); addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, splat})); continue; } else { keyOperand = buildWithOrder(key, hasAssignments); } args.add(new KeyValuePair<>(keyOperand, buildWithOrder(pair.getValue(), hasAssignments))); } if (hash == null) { // non-**arg ordinary hash hash = copyAndReturnValue(new Hash(args)); } else if (!args.isEmpty()) { // ordinary hash values encountered after a **arg addInstr(new RuntimeHelperCall(hash, MERGE_KWARGS, new Operand[] { hash, new Hash(args) })); } return hash; }
private void handleBreakAndReturnsInLambdas() { Label rEndLabel = getNewLabel(); Label rescueLabel = Label.getGlobalEnsureBlockLabel(); // Protect the entire body as it exists now with the global ensure block addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rescueLabel)); addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRBreakJumps) addInstr(new LabelInstr(rescueLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handleBreakAndReturnsInLambdas(context, scope, bj, blockType) Variable ret = createTemporaryVariable(); addInstr(new RuntimeHelperCall(ret, RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} )); addInstr(new ReturnOrRethrowSavedExcInstr(ret)); // End addInstr(new LabelInstr(rEndLabel)); }
private void handleBreakAndReturnsInLambdas() { Label rEndLabel = getNewLabel(); Label rescueLabel = Label.getGlobalEnsureBlockLabel(); // Protect the entire body as it exists now with the global ensure block addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rescueLabel)); addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRBreakJumps) addInstr(new LabelInstr(rescueLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handleBreakAndReturnsInLambdas(context, scope, bj, blockType) Variable ret = createTemporaryVariable(); addInstr(new RuntimeHelperCall(ret, RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} )); addInstr(new ReturnOrRethrowSavedExcInstr(ret)); // End addInstr(new LabelInstr(rEndLabel)); }
private Operand receiveBreakException(Operand block, CodeBlock codeBlock) { // Check if we have to handle a break if (block == null || !(block instanceof WrappedIRClosure) || !(((WrappedIRClosure)block).getClosure()).flags.contains(IRFlags.HAS_BREAK_INSTRS)) { // No protection needed -- add the call and return return codeBlock.run(); } Label rBeginLabel = getNewLabel(); Label rEndLabel = getNewLabel(); Label rescueLabel = getNewLabel(); // Protected region addInstr(new LabelInstr(rBeginLabel)); addInstr(new ExceptionRegionStartMarkerInstr(rescueLabel)); Variable callResult = (Variable)codeBlock.run(); addInstr(new JumpInstr(rEndLabel)); addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRBreakJumps) addInstr(new LabelInstr(rescueLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handlePropagatedBreak(context, scope, bj, blockType) addInstr(new RuntimeHelperCall(callResult, HANDLE_PROPAGATED_BREAK, new Operand[]{exc} )); // End addInstr(new LabelInstr(rEndLabel)); return callResult; }
private Operand receiveBreakException(Operand block, CodeBlock codeBlock) { // Check if we have to handle a break if (block == null || !(block instanceof WrappedIRClosure) || !(((WrappedIRClosure)block).getClosure()).flags.contains(IRFlags.HAS_BREAK_INSTRS)) { // No protection needed -- add the call and return return codeBlock.run(); } Label rBeginLabel = getNewLabel(); Label rEndLabel = getNewLabel(); Label rescueLabel = getNewLabel(); // Protected region addInstr(new LabelInstr(rBeginLabel)); addInstr(new ExceptionRegionStartMarkerInstr(rescueLabel)); Variable callResult = (Variable)codeBlock.run(); addInstr(new JumpInstr(rEndLabel)); addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRBreakJumps) addInstr(new LabelInstr(rescueLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handlePropagatedBreak(context, scope, bj, blockType) addInstr(new RuntimeHelperCall(callResult, HANDLE_PROPAGATED_BREAK, new Operand[]{exc} )); // End addInstr(new LabelInstr(rEndLabel)); return callResult; }
private void handleNonlocalReturnInMethod(IRScope s) { Label rBeginLabel = s.getNewLabel(); Label rEndLabel = s.getNewLabel(); Label gebLabel = s.getNewLabel(); // protect the entire body as it exists now with the global ensure block s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rBeginLabel, rEndLabel, gebLabel, gebLabel)); s.addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRReturnJumps) s.addInstr(new LabelInstr(gebLabel)); Variable exc = s.getNewTemporaryVariable(); s.addInstr(new ReceiveExceptionInstr(exc, false)); // no type-checking // Handle break using runtime helper // --> IRRuntimeHelpers.handleNonlocalReturn(scope, bj, blockType) Variable ret = s.getNewTemporaryVariable(); s.addInstr(new RuntimeHelperCall(ret, "handleNonlocalReturn", new Operand[]{exc} )); s.addInstr(new ReturnInstr(ret)); // End s.addInstr(new LabelInstr(rEndLabel)); }
private void handleNonlocalReturnInMethod(IRScope s) { Label rBeginLabel = s.getNewLabel(); Label rEndLabel = s.getNewLabel(); Label gebLabel = s.getNewLabel(); // protect the entire body as it exists now with the global ensure block s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rBeginLabel, rEndLabel, gebLabel, gebLabel)); s.addInstr(new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRReturnJumps) s.addInstr(new LabelInstr(gebLabel)); Variable exc = s.getNewTemporaryVariable(); s.addInstr(new ReceiveExceptionInstr(exc, false)); // no type-checking // Handle break using runtime helper // --> IRRuntimeHelpers.handleNonlocalReturn(scope, bj, blockType) Variable ret = s.getNewTemporaryVariable(); s.addInstr(new RuntimeHelperCall(ret, "handleNonlocalReturn", new Operand[]{exc} )); s.addInstr(new ReturnInstr(ret)); // End s.addInstr(new LabelInstr(rEndLabel)); }
private void handleNonlocalReturnInMethod() { Label rBeginLabel = getNewLabel(); Label rEndLabel = getNewLabel(); Label gebLabel = getNewLabel(); // Protect the entire body as it exists now with the global ensure block // // Add label and marker instruction in reverse order to the beginning // so that the label ends up being the first instr. addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(gebLabel)); addInstrAtBeginning(new LabelInstr(rBeginLabel)); addInstr( new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRReturnJumps) addInstr(new LabelInstr(gebLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handleNonlocalReturn(scope, bj, blockType) Variable ret = createTemporaryVariable(); addInstr(new RuntimeHelperCall(ret, HANDLE_NONLOCAL_RETURN, new Operand[]{exc} )); addInstr(new ReturnInstr(ret)); // End addInstr(new LabelInstr(rEndLabel)); }
private void handleNonlocalReturnInMethod() { Label rBeginLabel = getNewLabel(); Label rEndLabel = getNewLabel(); Label gebLabel = getNewLabel(); // Protect the entire body as it exists now with the global ensure block // // Add label and marker instruction in reverse order to the beginning // so that the label ends up being the first instr. addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(gebLabel)); addInstrAtBeginning(new LabelInstr(rBeginLabel)); addInstr( new ExceptionRegionEndMarkerInstr()); // Receive exceptions (could be anything, but the handler only processes IRReturnJumps) addInstr(new LabelInstr(gebLabel)); Variable exc = createTemporaryVariable(); addInstr(new ReceiveJRubyExceptionInstr(exc)); // Handle break using runtime helper // --> IRRuntimeHelpers.handleNonlocalReturn(scope, bj, blockType) Variable ret = createTemporaryVariable(); addInstr(new RuntimeHelperCall(ret, HANDLE_NONLOCAL_RETURN, new Operand[]{exc} )); addInstr(new ReturnInstr(ret)); // End addInstr(new LabelInstr(rEndLabel)); }
s.addInstr(new RuntimeHelperCall(callInstr.getResult(), "handlePropagatedBreak", new Operand[]{exc} ));
s.addInstr(new RuntimeHelperCall(callInstr.getResult(), "handlePropagatedBreak", new Operand[]{exc} ));