Example #1
0
  /**
   * 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();
 }