Example #1
0
  @Override
  public boolean doesRespondTo(VirtualFrame frame, RubyBasicObject receiverObject) {
    // TODO(CS): copy-and-paste of the above - needs to be factored out

    MethodCacheEntry entry = lookupInCache(receiverObject.getLookupNode());

    if (entry == null) {
      CompilerDirectives.transferToInterpreterAndInvalidate();

      final RubyBasicObject boxedCallingSelf =
          getContext().getCoreLibrary().box(RubyArguments.getSelf(frame.getArguments()));

      try {
        entry = new MethodCacheEntry(lookup(boxedCallingSelf, receiverObject, name), false);
      } catch (UseMethodMissingException e) {
        try {
          entry =
              new MethodCacheEntry(
                  lookup(boxedCallingSelf, receiverObject, "method_missing"), true);
        } catch (UseMethodMissingException e2) {
          throw new RaiseException(
              getContext()
                  .getCoreLibrary()
                  .runtimeError(receiverObject.toString() + " didn't have a #method_missing"));
        }
      }

      if (entry.isMethodMissing()) {
        hasAnyMethodsMissing = true;
      }

      cache.put(receiverObject.getLookupNode(), entry);

      if (cache.size() > RubyContext.GENERAL_DISPATCH_SIZE_WARNING_THRESHOLD) {
        getContext()
            .getRuntime()
            .getWarnings()
            .warn(
                IRubyWarnings.ID.TRUFFLE,
                getEncapsulatingSourceSection().getSource().getName(),
                getEncapsulatingSourceSection().getStartLine(),
                "general call node cache has " + cache.size() + " entries");
      }
    }

    return !entry.isMethodMissing();
  }
 @Override
 public double executeFloat(RubyBasicObject receiver) throws UnexpectedResultException {
   if (hasFloat && receiver.getRubyClass() == expectedClass && unmodifiedAssumption.isValid()) {
     return integerFixnumValue;
   } else {
     return next.executeFloat(receiver);
   }
 }
 @Override
 public boolean executeBoolean(RubyBasicObject receiver) throws UnexpectedResultException {
   if (hasBoolean && receiver.getRubyClass() == expectedClass && unmodifiedAssumption.isValid()) {
     return booleanValue;
   } else {
     return next.executeBoolean(receiver);
   }
 }
    @Specialization
    public Object send(RubyBasicObject self, Object[] args, RubyProc block) {
      notDesignedForCompilation();

      final String name = args[0].toString();
      final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length);
      return self.send(name, block, sendArgs);
    }
 @Override
 public long executeLongFixnum(RubyBasicObject receiver) throws UnexpectedResultException {
   if (hasLongFixnum
       && receiver.getRubyClass() == expectedClass
       && unmodifiedAssumption.isValid()) {
     return longFixnumValue;
   } else {
     return next.executeLongFixnum(receiver);
   }
 }
  @Override
  public Object execute(RubyBasicObject receiver) {
    // TODO(CS): not sure trying next on invalid assumption is right...

    if (receiver.getRubyClass() == expectedClass && unmodifiedAssumption.isValid()) {
      return value;
    } else {
      return next.execute(receiver);
    }
  }
    @Specialization
    public Object send(
        RubyBasicObject self,
        Object[] args,
        @SuppressWarnings("unused") UndefinedPlaceholder block) {
      notDesignedForCompilation();

      final String name = args[0].toString();
      final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length);
      return self.send(name, null, sendArgs);
    }
Example #8
0
  /** num_step_scan_args */
  private IRubyObject[] scanStepArgs(ThreadContext context, IRubyObject[] args) {
    IRubyObject to = context.runtime.getNil();
    IRubyObject step = context.runtime.newFixnum(1);

    if (args.length >= 1) to = args[0];
    if (args.length >= 2) step = args[1];

    // TODO: Fold kwargs into the @JRubyMethod decorator
    IRubyObject[] kwargs = ArgsUtil.extractKeywordArgs(context, args, validStepArgs);

    if (kwargs != null) {
      to = kwargs[0];
      step = kwargs[1];

      if (!to.isNil() && args.length > 1) {
        throw context.runtime.newArgumentError("to is given twice");
      }
      if (!step.isNil() && args.length > 2) {
        throw context.runtime.newArgumentError("step is given twice");
      }
    } else {
      if (RubyBasicObject.equalInternal(context, step, RubyFixnum.zero(context.runtime))) {
        throw context.runtime.newArgumentError("step can't be 0");
      }
      if (step.isNil()) {
        throw context.runtime.newTypeError("step must be numeric");
      }
    }

    if (step.isNil()) {
      step = RubyFixnum.one(context.runtime);
    }

    if (to.isNil()) {
      if (f_negative_p(context, step)) {
        to = RubyFloat.newFloat(context.runtime, Double.NEGATIVE_INFINITY);
      } else {
        to = RubyFloat.newFloat(context.runtime, Double.POSITIVE_INFINITY);
      }
    }

    return new IRubyObject[] {to, step};
  }
Example #9
0
  @Override
  public Object dispatch(
      VirtualFrame frame,
      RubyBasicObject receiverObject,
      RubyProc blockObject,
      Object[] argumentsObjects) {
    MethodCacheEntry entry = lookupInCache(receiverObject.getLookupNode());

    if (entry == null) {
      CompilerDirectives.transferToInterpreterAndInvalidate();

      final RubyBasicObject boxedCallingSelf =
          getContext().getCoreLibrary().box(RubyArguments.getSelf(frame.getArguments()));

      try {
        entry = new MethodCacheEntry(lookup(boxedCallingSelf, receiverObject, name), false);
      } catch (UseMethodMissingException e) {
        try {
          entry =
              new MethodCacheEntry(
                  lookup(boxedCallingSelf, receiverObject, "method_missing"), true);
        } catch (UseMethodMissingException e2) {
          throw new RaiseException(
              getContext()
                  .getCoreLibrary()
                  .runtimeError(receiverObject.toString() + " didn't have a #method_missing"));
        }
      }

      if (entry.isMethodMissing()) {
        hasAnyMethodsMissing = true;
      }

      cache.put(receiverObject.getLookupNode(), entry);

      if (cache.size() > RubyContext.GENERAL_DISPATCH_SIZE_WARNING_THRESHOLD) {
        getContext()
            .getRuntime()
            .getWarnings()
            .warn(
                IRubyWarnings.ID.TRUFFLE,
                getEncapsulatingSourceSection().getSource().getName(),
                getEncapsulatingSourceSection().getStartLine(),
                "general call node cache has " + cache.size() + " entries");
      }
    }

    final Object[] argumentsToUse;

    if (hasAnyMethodsMissing && entry.isMethodMissing()) {
      final Object[] modifiedArgumentsObjects = new Object[1 + argumentsObjects.length];
      modifiedArgumentsObjects[0] = getContext().newSymbol(name);
      System.arraycopy(argumentsObjects, 0, modifiedArgumentsObjects, 1, argumentsObjects.length);
      argumentsToUse = modifiedArgumentsObjects;
    } else {
      argumentsToUse = argumentsObjects;
    }

    return callNode.call(
        frame,
        entry.getMethod().getCallTarget(),
        RubyArguments.pack(
            entry.getMethod().getDeclarationFrame(), receiverObject, blockObject, argumentsToUse));
  }
 private Object methodMissing(
     RubyBasicObject self, RubySymbol name, Object[] args, RubyProc block) {
   throw new RaiseException(
       getContext().getCoreLibrary().nameErrorNoMethod(name.toString(), self.toString()));
 }