@Override
  protected IRubyObject commonYieldPath(
      ThreadContext context,
      Block block,
      Block.Type type,
      IRubyObject[] args,
      IRubyObject self,
      Block blockArg) {
    if (callCount >= 0) promoteToFullBuild(context);

    InterpreterContext ic = ensureInstrsReady();

    // Update interpreter context for next time this block is executed
    // This ensures that if we had determined canCallDirect() is false
    // based on the old IC, we continue to execute with it.
    interpreterContext = fullInterpreterContext;

    Binding binding = block.getBinding();
    Visibility oldVis = binding.getFrame().getVisibility();
    Frame prevFrame = context.preYieldNoScope(binding);

    // SSS FIXME: Maybe, we should allocate a NoVarsScope/DummyScope for for-loop bodies because the
    // static-scope here
    // probably points to the parent scope? To be verified and fixed if necessary. There is no harm
    // as it is now. It
    // is just wasteful allocation since the scope is not used at all.
    DynamicScope actualScope = binding.getDynamicScope();
    if (ic.pushNewDynScope()) {
      context.pushScope(block.allocScope(actualScope));
    } else if (ic.reuseParentDynScope()) {
      // Reuse! We can avoid the push only if surrounding vars aren't referenced!
      context.pushScope(actualScope);
    }

    self = IRRuntimeHelpers.updateBlockState(block, self);

    try {
      return Interpreter.INTERPRET_BLOCK(
          context, block, self, ic, args, binding.getMethod(), blockArg);
    } finally {
      // IMPORTANT: Do not clear eval-type in case this is reused in bindings!
      // Ex: eval("...", foo.instance_eval { binding })
      // The dyn-scope used for binding needs to have its eval-type set to INSTANCE_EVAL
      binding.getFrame().setVisibility(oldVis);
      if (ic.popDynScope()) {
        context.postYield(binding, prevFrame);
      } else {
        context.postYieldNoScope(prevFrame);
      }
    }
  }
Beispiel #2
0
 @Override
 protected void post(
     ThreadContext context, Binding binding, Visibility visibility, Frame lastFrame) {
   context.postYieldNoScope(lastFrame);
 }