/** * Yield to this block, usually passed to the current call. * * @param context represents the current thread-specific data * @param value The value to yield, either a single value or an array of values * @param self The current self * @param klass * @param aValue Should value be arrayified or not? * @return */ public IRubyObject yield( ThreadContext context, IRubyObject value, IRubyObject self, RubyModule klass, boolean aValue, Binding binding, Block.Type type) { if (klass == null) { self = binding.getSelf(); binding.getFrame().setSelf(self); } Frame lastFrame = pre(context, klass, binding); try { // This while loop is for restarting the block call in case a 'redo' fires. while (true) { try { return callback(value, method, self, Block.NULL_BLOCK); } catch (JumpException.RedoJump rj) { context.pollThreadEvents(); // do nothing, allow loop to redo } catch (JumpException.BreakJump bj) { // if (bj.getTarget() == 0) { // bj.setTarget(this); // } throw bj; } } } catch (JumpException.NextJump nj) { // A 'next' is like a local return from the block, ending this call or yield. return (IRubyObject) nj.getValue(); } finally { post(context, binding, null, lastFrame); } }
private IRubyObject handleNextJump( ThreadContext context, JumpException.NextJump nj, Block.Type type) { return nj.getValue() == null ? context.getRuntime().getNil() : (IRubyObject) nj.getValue(); }