/** * Yield to this block, usually passed to the current call. * * @param context represents the current thread-specific data * @param args The args for yield * @param self The current self * @return */ @Override public IRubyObject yield( ThreadContext context, IRubyObject[] args, IRubyObject self, Binding binding, Block.Type type, Block block) { // SSS FIXME: This is now being done unconditionally compared to if (klass == null) earlier self = prepareSelf(binding); Frame lastFrame = pre(context, binding); try { // This while loop is for restarting the block call in case a 'redo' fires. while (true) { try { IRubyObject[] preppedArgs = RubyProc.prepareArgs(context, type, arity, args); return callback(context.runtime.newArrayNoCopyLight(preppedArgs), method, self, 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.FlowControlException jump) { return Helpers.handleBlockJump(context, jump, type); } finally { post(context, binding, null, lastFrame); } }
/** * 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); } }