public static IRubyObject initiateBreak(ThreadContext context, IRScope scope, int scopeIdToReturnTo, IRubyObject breakValue, Block.Type blockType) throws RuntimeException { if (inLambda(blockType)) { // Ensures would already have been run since the IR builder makes // sure that ensure code has run before we hit the break. Treat // the break as a regular return from the closure. return breakValue; } else { if (!(scope instanceof IRClosure)) { // Error -- breaks can only be initiated in closures throw IRException.BREAK_LocalJumpError.getException(context.runtime); } IRBreakJump bj = IRBreakJump.create(scopeIdToReturnTo, breakValue); if (scope instanceof IREvalScript) { // If we are in an eval, record it so we can account for it bj.breakInEval = true; } // Start the process of breaking through the intermediate scopes throw bj; } }
public static IRubyObject initiateBreak(ThreadContext context, IRScope scope, int scopeIdToReturnTo, IRubyObject breakValue, Block.Type blockType) throws RuntimeException { if (inLambda(blockType)) { // Ensures would already have been run since the IR builder makes // sure that ensure code has run before we hit the break. Treat // the break as a regular return from the closure. return breakValue; } else { if (!(scope instanceof IRClosure)) { // Error -- breaks can only be initiated in closures throw IRException.BREAK_LocalJumpError.getException(context.runtime); } IRBreakJump bj = IRBreakJump.create(scopeIdToReturnTo, breakValue); if (scope instanceof IREvalScript) { // If we are in an eval, record it so we can account for it bj.breakInEval = true; } // Start the process of breaking through the intermediate scopes throw bj; } }
public static void catchUncaughtBreakInLambdas(ThreadContext context, IRScope scope, Object exc, Block.Type blockType) throws RuntimeException { if ((exc instanceof IRBreakJump) && inNonMethodBodyLambda(scope, blockType)) { // We just unwound all the way up because of a non-local break throw IRException.BREAK_LocalJumpError.getException(context.getRuntime()); } else { // Propagate Helpers.throwException((Throwable)exc); } }
private static IRScopeType ensureScopeIsClosure(ThreadContext context, DynamicScope dynamicScope) { IRScopeType scopeType = dynamicScope.getStaticScope().getScopeType(); // Error -- breaks can only be initiated in closures if (!scopeType.isClosureType()) throw IRException.BREAK_LocalJumpError.getException(context.runtime); return scopeType; }
private static IRScopeType ensureScopeIsClosure(ThreadContext context, DynamicScope dynamicScope) { IRScopeType scopeType = dynamicScope.getStaticScope().getScopeType(); // Error -- breaks can only be initiated in closures if (!scopeType.isClosureType()) throw IRException.BREAK_LocalJumpError.getException(context.runtime); return scopeType; }
public static void catchUncaughtBreakInLambdas(ThreadContext context, IRScope scope, Object exc, Block.Type blockType) throws RuntimeException { if ((exc instanceof IRBreakJump) && inNonMethodBodyLambda(scope, blockType)) { // We just unwound all the way up because of a non-local break throw IRException.BREAK_LocalJumpError.getException(context.getRuntime()); } else { // Propagate Helpers.throwException((Throwable)exc); } }
public static IRubyObject handlePropagatedBreak(ThreadContext context, IRScope scope, Object bjExc, Block.Type blockType) throws RuntimeException { if (!(bjExc instanceof IRBreakJump)) { throw (RuntimeException)bjExc; } IRBreakJump bj = (IRBreakJump)bjExc; if (bj.breakInEval) { // If the break was in an eval, we pretend as if it was in the containing scope if (!(scope instanceof IRClosure)) { // Error -- breaks can only be initiated in closures throw IRException.BREAK_LocalJumpError.getException(context.getRuntime()); } else { bj.breakInEval = false; throw bj; } } else if (bj.scopeIdToReturnTo == scope.getScopeId()) { // Done!! Hurray! return bj.breakValue; /* --------------------------------------------------------------- * FIXME: Puzzled .. Why is this not needed? } else if (!context.scopeExistsOnCallStack(bj.scopeToReturnTo.getStaticScope())) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); * --------------------------------------------------------------- */ } else { // Propagate throw bj; } } };
@Override public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block block) { if (exceptionArg instanceof IRException) { throw ((IRException) exceptionArg).getException(context.runtime); } Object excObj = exceptionArg.retrieve(context, self, currDynScope, temp); if (excObj instanceof IRubyObject) { RubyKernel.raise(context, context.runtime.getKernel(), new IRubyObject[] {(IRubyObject)excObj}, Block.NULL_BLOCK); } else if (excObj instanceof Throwable) { // java exception -- avoid having to add 'throws' clause everywhere! // SSS FIXME: Can avoid this workaround by adding a case for this instruction in the interpreter loop Helpers.throwException((Throwable)excObj); } // should never get here throw new RuntimeException("Control shouldn't have reached here in ThrowExceptionInstr. excObj is: " + excObj); }
public static IRubyObject handlePropagatedBreak(ThreadContext context, IRScope scope, Object bjExc, Block.Type blockType) throws RuntimeException { if (!(bjExc instanceof IRBreakJump)) { throw (RuntimeException)bjExc; } IRBreakJump bj = (IRBreakJump)bjExc; if (bj.breakInEval) { // If the break was in an eval, we pretend as if it was in the containing scope if (!(scope instanceof IRClosure)) { // Error -- breaks can only be initiated in closures throw IRException.BREAK_LocalJumpError.getException(context.getRuntime()); } else { bj.breakInEval = false; throw bj; } } else if (bj.scopeIdToReturnTo == scope.getScopeId()) { // Done!! Hurray! return bj.breakValue; /* --------------------------------------------------------------- * FIXME: Puzzled .. Why is this not needed? } else if (!context.scopeExistsOnCallStack(bj.scopeToReturnTo.getStaticScope())) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); * --------------------------------------------------------------- */ } else { // Propagate throw bj; } } };
@Override public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block block) { if (exceptionArg instanceof IRException) { throw ((IRException) exceptionArg).getException(context.runtime); } Object excObj = exceptionArg.retrieve(context, self, currDynScope, temp); if (excObj instanceof IRubyObject) { RubyKernel.raise(context, context.runtime.getKernel(), new IRubyObject[] {(IRubyObject)excObj}, Block.NULL_BLOCK); } else if (excObj instanceof Throwable) { // java exception -- avoid having to add 'throws' clause everywhere! // SSS FIXME: Can avoid this workaround by adding a case for this instruction in the interpreter loop Helpers.throwException((Throwable)excObj); } // should never get here throw new RuntimeException("Control shouldn't have reached here in ThrowExceptionInstr. excObj is: " + excObj); }
@Override public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { if (getException() instanceof IRException) { throw ((IRException) getException()).getException(context.runtime); } Object excObj = getException().retrieve(context, self, currScope, currDynScope, temp); if (excObj instanceof IRubyObject) { RubyKernel.raise(context, context.runtime.getKernel(), new IRubyObject[] {(IRubyObject)excObj}, Block.NULL_BLOCK); } else if (excObj instanceof Throwable) { // java exception -- avoid having to add 'throws' clause everywhere! Helpers.throwException((Throwable)excObj); } // should never get here throw new RuntimeException("Control shouldn't have reached here in ThrowExceptionInstr. excObj is: " + excObj); }
@Override public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { if (getException() instanceof IRException) { throw ((IRException) getException()).getException(context.runtime); } Object excObj = getException().retrieve(context, self, currScope, currDynScope, temp); if (excObj instanceof IRubyObject) { RubyKernel.raise(context, context.runtime.getKernel(), new IRubyObject[] {(IRubyObject)excObj}, Block.NULL_BLOCK); } else if (excObj instanceof Throwable) { // java exception -- avoid having to add 'throws' clause everywhere! Helpers.throwException((Throwable)excObj); } // should never get here throw new RuntimeException("Control shouldn't have reached here in ThrowExceptionInstr. excObj is: " + excObj); }
@Override public IRubyObject load(ThreadContext context, IRubyObject self, boolean wrap) { // Compiler does not support BEGIN/END yet and should fail to compile above // Copied from Interpreter RubyModule currModule = staticScope.getModule(); staticScope.setModule(currModule); context.setCurrentVisibility(Visibility.PRIVATE); try { return (IRubyObject) compiledHandle.invokeWithArguments(context, staticScope, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, currModule, null); } catch (IRBreakJump bj) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); } catch (Throwable t) { Helpers.throwException(t); return null; // not reached } finally { } } };
@Override public IRubyObject load(ThreadContext context, IRubyObject self, boolean wrap) { // Compiler does not support BEGIN/END yet and should fail to compile above // Copied from Interpreter RubyModule currModule = staticScope.getModule(); staticScope.setModule(currModule); context.setCurrentVisibility(Visibility.PRIVATE); try { return (IRubyObject) compiledHandle.invokeWithArguments(context, staticScope, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, currModule, null); } catch (IRBreakJump bj) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); } catch (Throwable t) { Helpers.throwException(t); return null; // not reached } finally { } } };
public static void initiateNonLocalReturn(ThreadContext context, IRScope scope, IRMethod methodToReturnFrom, IRubyObject returnValue) { if (scope instanceof IRClosure) { if (methodToReturnFrom == null) { // SSS FIXME: As Tom correctly pointed out, this is not correct. The example that breaks this code is: // // jruby -X-CIR -e "Thread.new { Proc.new { return }.call }.join" // // This should report a LocalJumpError, not a ThreadError. // // The right fix would involve checking the closure to see who it is associated with. // If it is a thread-body, it would be a ThreadError. If not, it would be a local-jump-error // This requires having access to the block -- same requirement as in handleBreakJump. if (context.getThread() == context.runtime.getThreadService().getMainThread()) { throw IRException.RETURN_LocalJumpError.getException(context.runtime); } else { throw context.runtime.newThreadError("return can't jump across threads"); } } // Cannot return from the call that we have long since exited. if (!context.scopeExistsOnCallStack(methodToReturnFrom.getStaticScope())) { if (isDebug()) LOG.info("in scope: " + scope + ", raising unexpected return local jump error"); throw IRException.RETURN_LocalJumpError.getException(context.runtime); } } // methodtoReturnFrom will not be null for explicit returns from class/module/sclass bodies throw IRReturnJump.create(methodToReturnFrom, returnValue); }
public static void initiateNonLocalReturn(ThreadContext context, IRScope scope, IRMethod methodToReturnFrom, IRubyObject returnValue) { if (scope instanceof IRClosure) { if (methodToReturnFrom == null) { // SSS FIXME: As Tom correctly pointed out, this is not correct. The example that breaks this code is: // // jruby -X-CIR -e "Thread.new { Proc.new { return }.call }.join" // // This should report a LocalJumpError, not a ThreadError. // // The right fix would involve checking the closure to see who it is associated with. // If it is a thread-body, it would be a ThreadError. If not, it would be a local-jump-error // This requires having access to the block -- same requirement as in handleBreakJump. if (context.getThread() == context.runtime.getThreadService().getMainThread()) { throw IRException.RETURN_LocalJumpError.getException(context.runtime); } else { throw context.runtime.newThreadError("return can't jump across threads"); } } // Cannot return from the call that we have long since exited. if (!context.scopeExistsOnCallStack(methodToReturnFrom.getStaticScope())) { if (isDebug()) LOG.info("in scope: " + scope + ", raising unexpected return local jump error"); throw IRException.RETURN_LocalJumpError.getException(context.runtime); } } // methodtoReturnFrom will not be null for explicit returns from class/module/sclass bodies throw IRReturnJump.create(methodToReturnFrom, returnValue); }
public static void checkForLJE(ThreadContext context, DynamicScope dynScope, boolean definedWithinMethod, Block block) { if (inLambda(block.type)) return; // break/return in lambda unconditionally a return. dynScope = getContainingMethodsDynamicScope(dynScope); StaticScope staticScope = dynScope.getStaticScope(); boolean inDefineMethod = dynScope != null && staticScope.isArgumentScope() && staticScope.getScopeType().isBlock(); boolean topLevel = staticScope.getScopeType() == IRScopeType.SCRIPT_BODY; if ((definedWithinMethod || inDefineMethod || topLevel) && context.scopeExistsOnCallStack(dynScope)) { return; } throw IRException.RETURN_LocalJumpError.getException(context.runtime); }
public static void checkForLJE(ThreadContext context, DynamicScope dynScope, boolean definedWithinMethod, Block block) { if (inLambda(block.type)) return; // break/return in lambda unconditionally a return. dynScope = getContainingMethodsDynamicScope(dynScope); StaticScope staticScope = dynScope.getStaticScope(); boolean inDefineMethod = dynScope != null && staticScope.isArgumentScope() && staticScope.getScopeType().isBlock(); boolean topLevel = staticScope.getScopeType() == IRScopeType.SCRIPT_BODY; if ((definedWithinMethod || inDefineMethod || topLevel) && context.scopeExistsOnCallStack(dynScope)) { return; } throw IRException.RETURN_LocalJumpError.getException(context.runtime); }
return INTERPRET_ROOT(context, self, ic, currModule, name); } catch (IRBreakJump bj) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); } finally { dumpStats();
return INTERPRET_ROOT(context, self, ic, currModule, name); } catch (IRBreakJump bj) { throw IRException.BREAK_LocalJumpError.getException(context.runtime); } finally { dumpStats();