@Override public Instr cloneForInlining(InlinerInfo ii) { return new ThrowExceptionInstr(exceptionArg.cloneForInlining(ii)); }
@Override public Instr cloneForInlining(InlinerInfo ii) { return new ThrowExceptionInstr(exceptionArg.cloneForInlining(ii)); }
public static ThrowExceptionInstr decode(IRReaderDecoder d) { return new ThrowExceptionInstr(d.decodeOperand()); }
public static ThrowExceptionInstr decode(IRReaderDecoder d) { return new ThrowExceptionInstr(d.decodeOperand()); }
@Override public Instr clone(CloneInfo ii) { return new ThrowExceptionInstr(getException().cloneForInlining(ii)); }
@Override public Instr clone(CloneInfo ii) { return new ThrowExceptionInstr(getException().cloneForInlining(ii)); }
public Operand buildRetry(Node node, IRScope s) { // JRuby only supports retry when present in rescue blocks! // 1.9 doesn't support retry anywhere else. // Jump back to the innermost rescue block // We either find it, or we add code to throw a runtime exception if (_rescueBlockStack.empty()) { s.addInstr(new ThrowExceptionInstr(IRException.RETRY_LocalJumpError)); } else { s.addInstr(new ThreadPollInstr(true)); // Restore $! and jump back to the entry of the rescue block RescueBlockInfo rbi = _rescueBlockStack.peek(); s.addInstr(new PutGlobalVarInstr("$!", rbi.savedExceptionVariable)); s.addInstr(new JumpInstr(rbi.entryLabel)); // Retries effectively create a loop s.setHasLoopsFlag(true); } return manager.getNil(); }
public Operand buildRetry(Node node, IRScope s) { // JRuby only supports retry when present in rescue blocks! // 1.9 doesn't support retry anywhere else. // Jump back to the innermost rescue block // We either find it, or we add code to throw a runtime exception if (_rescueBlockStack.empty()) { s.addInstr(new ThrowExceptionInstr(IRException.RETRY_LocalJumpError)); } else { s.addInstr(new ThreadPollInstr(true)); // Restore $! and jump back to the entry of the rescue block RescueBlockInfo rbi = _rescueBlockStack.peek(); s.addInstr(new PutGlobalVarInstr("$!", rbi.savedExceptionVariable)); s.addInstr(new JumpInstr(rbi.entryLabel)); // Retries effectively create a loop s.setHasLoopsFlag(true); } return manager.getNil(); }
public Operand buildRetry() { // JRuby only supports retry when present in rescue blocks! // 1.9 doesn't support retry anywhere else. // SSS FIXME: We should be able to use activeEnsureBlockStack for this // But, see the code in buildRescueInternal that pushes/pops these and // the documentation for retries. There is a small ordering issue // which is preventing me from getting rid of activeRescueBlockStack // altogether! // // Jump back to the innermost rescue block // We either find it, or we add code to throw a runtime exception if (activeRescueBlockStack.empty()) { addInstr(new ThrowExceptionInstr(IRException.RETRY_LocalJumpError)); } else { addInstr(new ThreadPollInstr(true)); // Restore $! and jump back to the entry of the rescue block RescueBlockInfo rbi = activeRescueBlockStack.peek(); addInstr(new PutGlobalVarInstr(symbol("$!"), rbi.savedExceptionVariable)); addInstr(new JumpInstr(rbi.entryLabel)); // Retries effectively create a loop scope.setHasLoopsFlag(); } return manager.getNil(); }
public Operand buildRetry() { // JRuby only supports retry when present in rescue blocks! // 1.9 doesn't support retry anywhere else. // SSS FIXME: We should be able to use activeEnsureBlockStack for this // But, see the code in buildRescueInternal that pushes/pops these and // the documentation for retries. There is a small ordering issue // which is preventing me from getting rid of activeRescueBlockStack // altogether! // // Jump back to the innermost rescue block // We either find it, or we add code to throw a runtime exception if (activeRescueBlockStack.empty()) { addInstr(new ThrowExceptionInstr(IRException.RETRY_LocalJumpError)); } else { addInstr(new ThreadPollInstr(true)); // Restore $! and jump back to the entry of the rescue block RescueBlockInfo rbi = activeRescueBlockStack.peek(); addInstr(new PutGlobalVarInstr(symbol("$!"), rbi.savedExceptionVariable)); addInstr(new JumpInstr(rbi.entryLabel)); // Retries effectively create a loop scope.setHasLoopsFlag(); } return manager.getNil(); }
public Operand buildNext(final NextNode nextNode, IRScope s) { IRLoop currLoop = getCurrentLoop(); Operand rv = (nextNode.getValueNode() == null) ? manager.getNil() : build(nextNode.getValueNode(), s); // If we have ensure blocks, have to run those first! if (!_ensureBlockStack.empty()) EnsureBlockInfo.emitJumpChain(s, _ensureBlockStack, currLoop); else if (!_rescueBlockStack.empty()) _rescueBlockStack.peek().restoreException(s, currLoop); if (currLoop != null) { // If a regular loop, the next is simply a jump to the end of the iteration s.addInstr(new JumpInstr(currLoop.iterEndLabel)); } else { s.addInstr(new ThreadPollInstr(true)); // If a closure, the next is simply a return from the closure! if (s instanceof IRClosure) s.addInstr(new ReturnInstr(rv)); else s.addInstr(new ThrowExceptionInstr(IRException.NEXT_LocalJumpError)); } // Once the "next instruction" (closure-return) executes, control exits this scope return UnexecutableNil.U_NIL; }
public Operand buildNext(final NextNode nextNode, IRScope s) { IRLoop currLoop = getCurrentLoop(); Operand rv = (nextNode.getValueNode() == null) ? manager.getNil() : build(nextNode.getValueNode(), s); // If we have ensure blocks, have to run those first! if (!_ensureBlockStack.empty()) EnsureBlockInfo.emitJumpChain(s, _ensureBlockStack, currLoop); else if (!_rescueBlockStack.empty()) _rescueBlockStack.peek().restoreException(s, currLoop); if (currLoop != null) { // If a regular loop, the next is simply a jump to the end of the iteration s.addInstr(new JumpInstr(currLoop.iterEndLabel)); } else { s.addInstr(new ThreadPollInstr(true)); // If a closure, the next is simply a return from the closure! if (s instanceof IRClosure) s.addInstr(new ReturnInstr(rv)); else s.addInstr(new ThrowExceptionInstr(IRException.NEXT_LocalJumpError)); } // Once the "next instruction" (closure-return) executes, control exits this scope return UnexecutableNil.U_NIL; }
if (is1_9() || is2_0()) { if (s instanceof IREvalScript) s.addInstr(new ThrowExceptionInstr(IRException.BREAK_LocalJumpError)); else s.addInstr(new BreakInstr(rv, returnScope)); } else { s.addInstr(new ThrowExceptionInstr(IRException.BREAK_LocalJumpError));
if (is1_9() || is2_0()) { if (s instanceof IREvalScript) s.addInstr(new ThrowExceptionInstr(IRException.BREAK_LocalJumpError)); else s.addInstr(new BreakInstr(rv, returnScope)); } else { s.addInstr(new ThrowExceptionInstr(IRException.BREAK_LocalJumpError));
public Operand buildRedo(Node node, IRScope s) { // If in a loop, a redo is a jump to the beginning of the loop. // If not, for closures, a redo is a jump to the beginning of the closure. // If not in a loop or a closure, it is a local jump error IRLoop currLoop = getCurrentLoop(); if (currLoop != null) { s.addInstr(new JumpInstr(currLoop.iterStartLabel)); } else { if (s instanceof IRClosure) { s.addInstr(new ThreadPollInstr(true)); s.addInstr(new JumpInstr(((IRClosure)s).startLabel)); } else { s.addInstr(new ThrowExceptionInstr(IRException.REDO_LocalJumpError)); } } return manager.getNil(); }
public Operand buildRedo(Node node, IRScope s) { // If in a loop, a redo is a jump to the beginning of the loop. // If not, for closures, a redo is a jump to the beginning of the closure. // If not in a loop or a closure, it is a local jump error IRLoop currLoop = getCurrentLoop(); if (currLoop != null) { s.addInstr(new JumpInstr(currLoop.iterStartLabel)); } else { if (s instanceof IRClosure) { s.addInstr(new ThreadPollInstr(true)); s.addInstr(new JumpInstr(((IRClosure)s).startLabel)); } else { s.addInstr(new ThrowExceptionInstr(IRException.REDO_LocalJumpError)); } } return manager.getNil(); }
public Operand buildReturn(ReturnNode returnNode, IRScope s) { Operand retVal = (returnNode.getValueNode() == null) ? manager.getNil() : build(returnNode.getValueNode(), s); // Before we return, // - have to go execute all the ensure blocks if there are any. // this code also takes care of resetting "$!" // - if we dont have any ensure blocks, we have to clear "$!" if (!_ensureBlockStack.empty()) EnsureBlockInfo.emitJumpChain(s, _ensureBlockStack, null); else if (!_rescueBlockStack.empty()) s.addInstr(new PutGlobalVarInstr("$!", manager.getNil())); if (s instanceof IRClosure) { // If 'm' is a block scope, a return returns from the closest enclosing method. // If this happens to be a module body, the runtime throws a local jump error if // the closure is a proc. If the closure is a lambda, then this is just a normal // return and the static methodToReturnFrom value is ignored s.addInstr(new NonlocalReturnInstr(retVal, s.getNearestMethod())); } else if (s.isModuleBody()) { IRMethod sm = s.getNearestMethod(); // Cannot return from top-level module bodies! if (sm == null) s.addInstr(new ThrowExceptionInstr(IRException.RETURN_LocalJumpError)); else s.addInstr(new NonlocalReturnInstr(retVal, sm)); } else { s.addInstr(new ReturnInstr(retVal)); } // The value of the return itself in the containing expression can never be used because of control-flow reasons. // The expression that uses this result can never be executed beyond the return and hence the value itself is just // a placeholder operand. return UnexecutableNil.U_NIL; }
public Operand buildReturn(ReturnNode returnNode, IRScope s) { Operand retVal = (returnNode.getValueNode() == null) ? manager.getNil() : build(returnNode.getValueNode(), s); // Before we return, // - have to go execute all the ensure blocks if there are any. // this code also takes care of resetting "$!" // - if we dont have any ensure blocks, we have to clear "$!" if (!_ensureBlockStack.empty()) EnsureBlockInfo.emitJumpChain(s, _ensureBlockStack, null); else if (!_rescueBlockStack.empty()) s.addInstr(new PutGlobalVarInstr("$!", manager.getNil())); if (s instanceof IRClosure) { // If 'm' is a block scope, a return returns from the closest enclosing method. // If this happens to be a module body, the runtime throws a local jump error if // the closure is a proc. If the closure is a lambda, then this is just a normal // return and the static methodToReturnFrom value is ignored s.addInstr(new NonlocalReturnInstr(retVal, s.getNearestMethod())); } else if (s.isModuleBody()) { IRMethod sm = s.getNearestMethod(); // Cannot return from top-level module bodies! if (sm == null) s.addInstr(new ThrowExceptionInstr(IRException.RETURN_LocalJumpError)); else s.addInstr(new NonlocalReturnInstr(retVal, sm)); } else { s.addInstr(new ReturnInstr(retVal)); } // The value of the return itself in the containing expression can never be used because of control-flow reasons. // The expression that uses this result can never be executed beyond the return and hence the value itself is just // a placeholder operand. return UnexecutableNil.U_NIL; }
public Operand buildReturn(ReturnNode returnNode) { Operand retVal = build(returnNode.getValueNode()); if (scope instanceof IRClosure) { // Closures return behavior has several cases (which depend on runtime state): // 1. closure in method (return). !method (error) except if in define_method (return) // 2. lambda (return) [dynamic] // FIXME: I believe ->() can be static and omit LJE check. // 3. migrated closure (LJE) [dynamic] // 4. eval/for (return) [static] boolean definedWithinMethod = scope.getNearestMethod() != null; if (!(scope instanceof IREvalScript) && !(scope instanceof IRFor)) addInstr(new CheckForLJEInstr(definedWithinMethod)); addInstr(new NonlocalReturnInstr(retVal, definedWithinMethod ? scope.getNearestMethod().getName() : manager.runtime.newSymbol("--none--"))); } else if (scope.isModuleBody()) { IRMethod sm = scope.getNearestMethod(); // Cannot return from top-level module bodies! if (sm == null) addInstr(new ThrowExceptionInstr(IRException.RETURN_LocalJumpError)); if (sm != null) addInstr(new NonlocalReturnInstr(retVal, sm.getName())); } else { retVal = processEnsureRescueBlocks(retVal); if (RubyInstanceConfig.FULL_TRACE_ENABLED) { addInstr(new TraceInstr(RubyEvent.RETURN, getName(), getFileName(), returnNode.getLine())); } addInstr(new ReturnInstr(retVal)); } // The value of the return itself in the containing expression can never be used because of control-flow reasons. // The expression that uses this result can never be executed beyond the return and hence the value itself is just // a placeholder operand. return U_NIL; }
public Operand buildReturn(ReturnNode returnNode) { Operand retVal = build(returnNode.getValueNode()); if (scope instanceof IRClosure) { // Closures return behavior has several cases (which depend on runtime state): // 1. closure in method (return). !method (error) except if in define_method (return) // 2. lambda (return) [dynamic] // FIXME: I believe ->() can be static and omit LJE check. // 3. migrated closure (LJE) [dynamic] // 4. eval/for (return) [static] boolean definedWithinMethod = scope.getNearestMethod() != null; if (!(scope instanceof IREvalScript) && !(scope instanceof IRFor)) addInstr(new CheckForLJEInstr(definedWithinMethod)); addInstr(new NonlocalReturnInstr(retVal, definedWithinMethod ? scope.getNearestMethod().getName() : manager.runtime.newSymbol("--none--"))); } else if (scope.isModuleBody()) { IRMethod sm = scope.getNearestMethod(); // Cannot return from top-level module bodies! if (sm == null) addInstr(new ThrowExceptionInstr(IRException.RETURN_LocalJumpError)); if (sm != null) addInstr(new NonlocalReturnInstr(retVal, sm.getName())); } else { retVal = processEnsureRescueBlocks(retVal); if (RubyInstanceConfig.FULL_TRACE_ENABLED) { addInstr(new TraceInstr(RubyEvent.RETURN, getName(), getFileName(), returnNode.getLine())); } addInstr(new ReturnInstr(retVal)); } // The value of the return itself in the containing expression can never be used because of control-flow reasons. // The expression that uses this result can never be executed beyond the return and hence the value itself is just // a placeholder operand. return U_NIL; }