Пример #1
0
    @ExplodeLoop
    @Override
    public RubyArray executeArray(VirtualFrame frame) {
      CompilerDirectives.transferToInterpreter();

      final Object[] executedValues = new Object[values.length];

      for (int n = 0; n < values.length; n++) {
        executedValues[n] = values[n].execute(frame);
      }

      final RubyArray array =
          RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues);
      final Object store = array.getStore();

      if (store == null) {
        replace(new EmptyArrayLiteralNode(getContext(), getSourceSection(), values));
      }
      if (store instanceof int[]) {
        replace(new IntegerFixnumArrayLiteralNode(getContext(), getSourceSection(), values));
      } else if (store instanceof long[]) {
        replace(new LongFixnumArrayLiteralNode(getContext(), getSourceSection(), values));
      } else if (store instanceof double[]) {
        replace(new FloatArrayLiteralNode(getContext(), getSourceSection(), values));
      } else {
        replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values));
      }

      return array;
    }
Пример #2
0
 public int readFixnum(RubyBasicObject object, boolean condition)
     throws UnexpectedResultException {
   if (isSet(object)) {
     return CompilerDirectives.unsafeGetInt(object, offset, condition, this);
   } else {
     throw new UnexpectedResultException(NilPlaceholder.INSTANCE);
   }
 }
Пример #3
0
 @Override
 public Object execute(VirtualFrame frame) {
   if (CompilerDirectives.injectBranchProbability(
       getBranchProbability(), condition.executeBoolean(frame))) {
     if (CompilerDirectives.inInterpreter()) {
       thenCount++;
     }
     thenProfile.enter();
     return thenBody.execute(frame);
   } else {
     if (CompilerDirectives.inInterpreter()) {
       elseCount++;
     }
     elseProfile.enter();
     return elseBody.execute(frame);
   }
 }
Пример #4
0
    @Specialization
    public Object methodMissing(RubyBasicObject self, Object[] args, RubyProc block) {
      notDesignedForCompilation();

      CompilerDirectives.transferToInterpreter();

      final RubySymbol name = (RubySymbol) args[0];
      final Object[] sentArgs = Arrays.copyOfRange(args, 1, args.length);
      return methodMissing(self, name, sentArgs, block);
    }
Пример #5
0
    @Specialization
    public Object methodMissing(
        RubyBasicObject self,
        Object[] args,
        @SuppressWarnings("unused") UndefinedPlaceholder block) {
      notDesignedForCompilation();

      CompilerDirectives.transferToInterpreter();

      final RubySymbol name = (RubySymbol) args[0];
      final Object[] sentArgs = Arrays.copyOfRange(args, 1, args.length);
      return methodMissing(self, name, sentArgs, null);
    }
Пример #6
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();
  }
Пример #7
0
  @Override
  public Object execute(VirtualFrame frame) {
    while (true) {
      try {
        final Object result = tryPart.execute(frame);
        elsePart.executeVoid(frame);
        return result;
      } catch (ControlFlowException exception) {
        controlFlowProfile.enter();

        throw exception;
      } catch (RuntimeException exception) {
        CompilerDirectives.transferToInterpreter();

        try {
          return handleException(frame, exception);
        } catch (RetryException e) {
          continue;
        }
      }
    }
  }
Пример #8
0
 public void writeFixnum(RubyBasicObject object, int value) {
   CompilerDirectives.unsafePutInt(object, offset, value, null);
   markAsSet(object);
 }
Пример #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));
  }