Exemple #1
0
  @Override
  public IRubyObject interpret(
      Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
    // Serialization killed our dynamic scope.  We can just create an empty one
    // since serialization cannot serialize an eval (which is the only thing
    // which is capable of having a non-empty dynamic scope).
    if (scope == null) {
      scope = DynamicScope.newDynamicScope(staticScope);
    }

    StaticScope theStaticScope = scope.getStaticScope();

    // Each root node has a top-level scope that we need to push
    context.preScopedBody(scope);

    if (theStaticScope.getModule() == null) {
      theStaticScope.setModule(runtime.getObject());
    }

    try {
      return bodyNode.interpret(runtime, context, self, aBlock);
    } finally {
      context.postScopedBody();
    }
  }
 private Object cache(
     ThreadContext context,
     DynamicScope currDynScope,
     IRubyObject self,
     Object[] temp,
     Ruby runtime,
     Object constant) {
   StaticScope staticScope =
       (StaticScope) definingScope.retrieve(context, self, currDynScope, temp);
   RubyModule object = runtime.getObject();
   // SSS FIXME: IRManager objects dont have a static-scope yet, so this hack of looking up the
   // module right away
   // This IR needs fixing!
   constant =
       (staticScope == null)
           ? object.getConstant(constName)
           : staticScope.getConstantInner(runtime, constName, object);
   if (constant == null) {
     constant = UndefinedValue.UNDEFINED;
   } else {
     // recache
     generation = runtime.getConstantInvalidator().getData();
     cachedConstant = constant;
   }
   return constant;
 }
  public BodyCompiler startFileMethod(
      CompilerCallback args, StaticScope scope, ASTInspector inspector) {
    MethodBodyCompiler methodCompiler =
        new MethodBodyCompiler(this, "__file__", "__file__", inspector, scope, 0);

    // allocate the 0 StaticScope slot in the cache
    int reservedIndex = cacheCompiler.reserveStaticScope();
    assert reservedIndex == 0 : "__file__ scope index was not zero";

    methodCompiler.beginMethod(args, scope);

    // boxed arg list __file__
    SkinnyMethodAdapter method =
        new SkinnyMethodAdapter(
            getClassVisitor(), ACC_PUBLIC, "__file__", getMethodSignature(4), null, null);
    method.start();

    // invoke static __file__
    method.aload(THIS);
    method.aload(THREADCONTEXT_INDEX);
    method.aload(SELF_INDEX);
    method.aload(ARGS_INDEX);
    method.aload(ARGS_INDEX + 1); // block
    method.invokestatic(getClassname(), "__file__", getStaticMethodSignature(getClassname(), 4));

    method.areturn();
    method.end();

    if (methodCompiler.isSpecificArity()) {
      // exact arg list __file__
      method =
          new SkinnyMethodAdapter(
              getClassVisitor(),
              ACC_PUBLIC,
              "__file__",
              getMethodSignature(scope.getRequiredArgs()),
              null,
              null);
      method.start();

      // invoke static __file__
      method.aload(THIS);
      method.aload(THREADCONTEXT_INDEX);
      method.aload(SELF_INDEX);
      for (int i = 0; i < scope.getRequiredArgs(); i++) {
        method.aload(ARGS_INDEX + i);
      }
      method.aload(ARGS_INDEX + scope.getRequiredArgs()); // block
      method.invokestatic(
          getClassname(),
          "__file__",
          getStaticMethodSignature(getClassname(), scope.getRequiredArgs()));

      method.areturn();
      method.end();
    }

    return methodCompiler;
  }
Exemple #4
0
 public void preCompiledClassDummyScope(RubyModule type, StaticScope staticScope) {
   pushRubyClass(type);
   pushFrameCopy();
   getCurrentFrame().setSelf(type);
   getCurrentFrame().setVisibility(Visibility.PUBLIC);
   staticScope.setModule(type);
   pushScope(staticScope.getDummyScope());
 }
Exemple #5
0
 public void preMethodNoFrameAndDummyScope(RubyModule clazz, StaticScope staticScope) {
   RubyModule implementationClass = staticScope.getModule();
   // FIXME: This is currently only here because of some problems with IOOutputStream writing to a
   // "bare" runtime without a proper scope
   if (implementationClass == null) {
     implementationClass = clazz;
   }
   pushScope(staticScope.getDummyScope());
   pushRubyClass(implementationClass);
 }
Exemple #6
0
  @JRubyMethod(name = "initialize", frame = true, visibility = Visibility.PRIVATE)
  public IRubyObject initialize(ThreadContext context, Block procBlock) {
    if (!procBlock.isGiven()) {
      throw getRuntime().newArgumentError("tried to create Proc object without a block");
    }

    if (isLambda() && procBlock == null) {
      // TODO: warn "tried to create Proc object without a block"
    }

    block = procBlock.cloneBlock();

    if (isThread()) {
      // modify the block with a new backref/lastline-grabbing scope
      StaticScope oldScope = block.getBody().getStaticScope();
      StaticScope newScope =
          new BlockStaticScope(oldScope.getEnclosingScope(), oldScope.getVariables());
      newScope.setBackrefLastlineScope(true);
      newScope.setPreviousCRefScope(oldScope.getPreviousCRefScope());
      newScope.setModule(oldScope.getModule());
      block.getBody().setStaticScope(newScope);
    }

    block.type = type;
    block.setProcObject(this);

    file = context.getFile();
    line = context.getLine();
    return this;
  }
Exemple #7
0
  private static Block getIterNodeBlock(Node blockNode, ThreadContext context, IRubyObject self) {
    IterNode iterNode = (IterNode) blockNode;

    StaticScope scope = iterNode.getScope();
    scope.determineModule();

    // Create block for this iter node
    // FIXME: We shouldn't use the current scope if it's not actually from the same hierarchy of
    // static scopes
    return InterpretedBlock.newInterpretedClosure(context, iterNode.getBlockBody(), self);
  }
Exemple #8
0
  // XXX: Again, screwy evaling under previous frame's scope
  public void preExecuteUnder(RubyModule executeUnderClass, Block block) {
    Frame frame = getCurrentFrame();

    pushRubyClass(executeUnderClass);
    DynamicScope scope = getCurrentScope();
    StaticScope sScope = new BlockStaticScope(scope.getStaticScope());
    sScope.setModule(executeUnderClass);
    pushScope(DynamicScope.newDynamicScope(sScope, scope));
    pushCallFrame(frame.getKlazz(), frame.getName(), frame.getSelf(), block);
    getCurrentFrame().setVisibility(getPreviousFrame().getVisibility());
  }
Exemple #9
0
  public static IRubyObject lexicalSearchConst(
      ThreadContext context,
      StaticScope scope,
      MutableCallSite site,
      String constName,
      boolean noPrivateConsts)
      throws Throwable {
    Ruby runtime = context.runtime;

    IRubyObject constant = scope.getConstantInner(constName);

    if (constant == null) {
      constant = UndefinedValue.UNDEFINED;
    }

    SwitchPoint switchPoint = (SwitchPoint) runtime.getConstantInvalidator(constName).getData();

    // bind constant until invalidated
    MethodHandle target = Binder.from(site.type()).drop(0, 2).constant(constant);
    MethodHandle fallback =
        Binder.from(site.type())
            .append(site, constName)
            .append(noPrivateConsts)
            .invokeStatic(LOOKUP, Bootstrap.class, "lexicalSearchConst");

    site.setTarget(switchPoint.guardWithTest(target, fallback));

    return constant;
  }
Exemple #10
0
  public static IRubyObject searchConst(
      ThreadContext context,
      StaticScope staticScope,
      MutableCallSite site,
      String constName,
      boolean noPrivateConsts)
      throws Throwable {

    // Lexical lookup
    Ruby runtime = context.getRuntime();
    RubyModule object = runtime.getObject();
    IRubyObject constant =
        (staticScope == null)
            ? object.getConstant(constName)
            : staticScope.getConstantInner(constName);

    // Inheritance lookup
    RubyModule module = null;
    if (constant == null) {
      // SSS FIXME: Is this null check case correct?
      module = staticScope == null ? object : staticScope.getModule();
      constant =
          noPrivateConsts
              ? module.getConstantFromNoConstMissing(constName, false)
              : module.getConstantNoConstMissing(constName);
    }

    // Call const_missing or cache
    if (constant == null) {
      return module.callMethod(context, "const_missing", context.runtime.fastNewSymbol(constName));
    }

    SwitchPoint switchPoint = (SwitchPoint) runtime.getConstantInvalidator(constName).getData();

    // bind constant until invalidated
    MethodHandle target = Binder.from(site.type()).drop(0, 2).constant(constant);
    MethodHandle fallback =
        Binder.from(site.type())
            .append(site, constName)
            .append(noPrivateConsts)
            .invokeStatic(LOOKUP, Bootstrap.class, "searchConst");

    site.setTarget(switchPoint.guardWithTest(target, fallback));

    return constant;
  }
Exemple #11
0
  public IRubyObject shadowing_lvar(IRubyObject identifier) {
    String name = lexer.getIdent();

    if (name == "_") return identifier;

    StaticScope current = getCurrentScope();
    if (current.isBlockScope()) {
      if (current.exists(name) >= 0) yyerror("duplicated argument name");

      if (lexer.isVerbose() && current.isDefined(name) >= 0) {
        lexer.warning("shadowing outer local variable - " + name);
      }
    } else if (current.exists(name) >= 0) {
      yyerror("duplicated argument name");
    }

    return identifier;
  }
Exemple #12
0
  public static RubyModule getClassVariableBase(Ruby runtime, StaticScope scope) {
    RubyModule rubyClass = scope.getModule();
    while (rubyClass.isSingleton() || rubyClass == runtime.getDummy()) {
      // We ran out of scopes to check
      if (scope == null) return null;

      scope = scope.getPreviousCRefScope();
      rubyClass = scope.getModule();
      if (scope.getPreviousCRefScope() == null) {
        runtime
            .getWarnings()
            .warn(
                ID.CVAR_FROM_TOPLEVEL_SINGLETON_METHOD,
                "class variable access from toplevel singleton method");
      }
    }
    return rubyClass;
  }
Exemple #13
0
  public IRubyObject arg_var(IRubyObject identifier) {
    String name = lexer.getIdent();
    StaticScope current = getCurrentScope();

    // Multiple _ arguments are allowed.  To not screw with tons of arity
    // issues in our runtime we will allocate unnamed bogus vars so things
    // still work. MRI does not use name as intern'd value so they don't
    // have this issue.
    if (name == "_") {
      int count = 0;
      while (current.exists(name) >= 0) {
        name = "_$" + count++;
      }
    }

    current.addVariableThisScope(name);

    return identifier;
  }
Exemple #14
0
  private void setup(Block procBlock) {
    if (!procBlock.isGiven()) {
      throw getRuntime().newArgumentError("tried to create Proc object without a block");
    }

    if (isLambda()) {
      // TODO: warn "tried to create Proc object without a block"
    }

    if (isThread()) {
      // binding for incoming proc must not share frame
      Binding oldBinding = procBlock.getBinding();
      Binding newBinding =
          new Binding(
              oldBinding.getSelf(),
              oldBinding.getFrame().duplicate(),
              oldBinding.getVisibility(),
              oldBinding.getDynamicScope(),
              oldBinding.getMethod(),
              oldBinding.getFile(),
              oldBinding.getLine());
      block = new Block(procBlock.getBody(), newBinding);

      // modify the block with a new backref/lastline-grabbing scope
      StaticScope oldScope = block.getBody().getStaticScope();
      StaticScope newScope = oldScope.duplicate();
      block.getBody().setStaticScope(newScope);
    } else {
      // just use as is
      block = procBlock;
    }

    // force file/line info into the new block's binding
    block.getBinding().setFile(block.getBody().getFile());
    block.getBinding().setLine(block.getBody().getLine());

    block.type = type;
    block.setProcObject(this);

    // pre-request dummy scope to avoid clone overhead in lightweight blocks
    block.getBinding().getDummyScope(block.getBody().getStaticScope());
  }
Exemple #15
0
 private static IRScope getEvalContainerScope(Ruby runtime, StaticScope evalScope) {
   // SSS FIXME: Weirdness here.  We cannot get the containing IR scope from evalScope because of
   // static-scope wrapping
   // that is going on
   // 1. In all cases, DynamicScope.getEvalScope wraps the executing static scope in a new local
   // scope.
   // 2. For instance-eval (module-eval, class-eval) scenarios, there is an extra scope that is
   // added to
   //    the stack in ThreadContext.java:preExecuteUnder
   // I dont know what rule to apply when.  However, in both these cases, since there is no
   // IR-scope associated,
   // I have used the hack below where I first unwrap once and see if I get a non-null IR scope.
   // If that doesn't
   // work, I unwarp once more and I am guaranteed to get the IR scope I want.
   IRScope containingIRScope = ((IRStaticScope) evalScope.getEnclosingScope()).getIRScope();
   if (containingIRScope == null)
     containingIRScope =
         ((IRStaticScope) evalScope.getEnclosingScope().getEnclosingScope()).getIRScope();
   return containingIRScope;
 }
Exemple #16
0
 public void preMethodFrameAndScope(
     RubyModule clazz, String name, IRubyObject self, Block block, StaticScope staticScope) {
   RubyModule implementationClass = staticScope.getModule();
   // FIXME: This is currently only here because of some problems with IOOutputStream writing to a
   // "bare" runtime without a proper scope
   if (implementationClass == null) {
     implementationClass = clazz;
   }
   pushCallFrame(clazz, name, self, block);
   pushScope(DynamicScope.newDynamicScope(staticScope));
   pushRubyClass(implementationClass);
 }
  private Object cache(
      ThreadContext context,
      StaticScope currScope,
      DynamicScope currDynScope,
      IRubyObject self,
      Object[] temp) {
    StaticScope staticScope =
        (StaticScope) definingScope.retrieve(context, self, currScope, currDynScope, temp);

    IRubyObject constant = staticScope.getConstantInner(constName);

    if (constant == null) {
      constant = UndefinedValue.UNDEFINED;
    } else {
      // recache
      Invalidator invalidator = context.runtime.getConstantInvalidator(constName);
      cache = new ConstantCache(constant, invalidator.getData(), invalidator);
    }

    return constant;
  }