Пример #1
0
    @Specialization
    public Object step(
        VirtualFrame frame, RubyRange.IntegerFixnumRange range, int step, RubyProc block) {
      int count = 0;

      try {
        outer:
        for (int n = range.getBegin(); n < range.getExclusiveEnd(); n += step) {
          while (true) {
            if (CompilerDirectives.inInterpreter()) {
              count++;
            }

            try {
              yield(frame, block, n);
              continue outer;
            } catch (BreakException e) {
              breakProfile.enter();
              return e.getResult();
            } catch (NextException e) {
              nextProfile.enter();
              continue outer;
            } catch (RedoException e) {
              redoProfile.enter();
            }
          }
        }
      } finally {
        if (CompilerDirectives.inInterpreter()) {
          getRootNode().reportLoopCount(count);
        }
      }

      return range;
    }
Пример #2
0
  private Object coerceObject(VirtualFrame frame, Object object) {
    if (toIntNode == null) {
      CompilerDirectives.transferToInterpreter();
      toIntNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
    }

    final Object coerced;
    try {
      coerced = toIntNode.call(frame, object, "to_int", null);
    } catch (RaiseException e) {
      if (Layouts.BASIC_OBJECT.getLogicalClass(e.getRubyException())
          == getContext().getCoreLibrary().getNoMethodErrorClass()) {
        CompilerDirectives.transferToInterpreter();
        throw new RaiseException(
            getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "Integer", this));
      } else {
        throw e;
      }
    }

    if (getContext().getCoreLibrary().getLogicalClass(coerced)
        == getContext().getCoreLibrary().getFixnumClass()) {
      return coerced;
    } else {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(
          getContext()
              .getCoreLibrary()
              .typeErrorBadCoercion(object, "Integer", "to_int", coerced, this));
    }
  }
Пример #3
0
  @Specialization(guards = "!isRubyString(object)")
  public RubyBasicObject coerceObject(VirtualFrame frame, Object object) {
    final Object coerced;

    try {
      coerced = toStrNode.call(frame, object, "to_str", null);
    } catch (RaiseException e) {
      if (((RubyBasicObject) e.getRubyException()).getLogicalClass()
          == getContext().getCoreLibrary().getNoMethodErrorClass()) {
        CompilerDirectives.transferToInterpreter();
        throw new RaiseException(
            getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this));
      } else {
        throw e;
      }
    }

    if (RubyGuards.isRubyString(coerced)) {
      return (RubyBasicObject) coerced;
    } else {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(
          getContext()
              .getCoreLibrary()
              .typeErrorBadCoercion(object, "String", "to_str", coerced, this));
    }
  }
Пример #4
0
 @ExplodeLoop
 public void profileArguments(Object[] args) {
   Assumption typesAssumption = profiledArgumentTypesAssumption;
   if (typesAssumption == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     initializeProfiledArgumentTypes(args);
   } else {
     Class<?>[] types = profiledArgumentTypes;
     if (types != null) {
       if (types.length != args.length) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
         typesAssumption.invalidate();
         profiledArgumentTypes = null;
       } else if (typesAssumption.isValid()) {
         for (int i = 0; i < types.length; i++) {
           Class<?> type = types[i];
           Object value = args[i];
           if (type != null && (value == null || value.getClass() != type)) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             updateProfiledArgumentTypes(args, types);
             break;
           }
         }
       }
     }
   }
 }
Пример #5
0
    @Specialization
    public RubyArray collect(
        VirtualFrame frame, RubyRange.IntegerFixnumRange range, RubyProc block) {
      final int begin = range.getBegin();
      final int exclusiveEnd = range.getExclusiveEnd();
      final int length = exclusiveEnd - begin;

      Object store = arrayBuilder.start(length);

      int count = 0;

      try {
        for (int n = 0; n < length; n++) {
          if (CompilerDirectives.inInterpreter()) {
            count++;
          }

          store = arrayBuilder.append(store, n, yield(frame, block, n));
        }
      } finally {
        if (CompilerDirectives.inInterpreter()) {
          getRootNode().reportLoopCount(count);
        }
      }

      return new RubyArray(
          getContext().getCoreLibrary().getArrayClass(),
          arrayBuilder.finish(store, length),
          length);
    }
Пример #6
0
    @Specialization(
        guards = {"!isRubySymbol(index)", "!isRubyString(index)", "!isIntegerFixnumRange(index)"})
    public Object getIndex(
        VirtualFrame frame, DynamicObject matchData, Object index, NotProvided length) {
      CompilerDirectives.transferToInterpreter();

      if (toIntNode == null) {
        CompilerDirectives.transferToInterpreter();
        toIntNode = insert(ToIntNodeGen.create(getContext(), getSourceSection(), null));
      }

      return getIndex(matchData, toIntNode.doInt(frame, index), NotProvided.INSTANCE);
    }
 @Override
 public void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame) {
   CompilerDirectives.transferToInterpreterAndInvalidate();
   if (name.isEmpty()) {
     throw RError.error(RError.NO_CALLER, RError.Message.ZERO_LENGTH_VARIABLE);
   }
   final WriteSuperFrameVariableNode writeNode;
   if (REnvironment.isGlobalEnvFrame(enclosingFrame)) {
     /*
      * we've reached the global scope, do unconditional write. if this is the first node
      * in the chain, needs the rhs and enclosingFrame nodes
      */
     AccessEnclosingFrameNode enclosingFrameNode =
         RArguments.getEnclosingFrame(frame) == enclosingFrame
             ? new AccessEnclosingFrameNode()
             : null;
     writeNode =
         ResolvedWriteSuperFrameVariableNodeGen.create(
             mode,
             rhs,
             enclosingFrameNode,
             FrameSlotNode.create(
                 findOrAddFrameSlot(
                     enclosingFrame.getFrameDescriptor(), name, FrameSlotKind.Illegal)),
             name);
   } else {
     ResolvedWriteSuperFrameVariableNode actualWriteNode =
         ResolvedWriteSuperFrameVariableNodeGen.create(
             mode, null, null, FrameSlotNode.create(name), name);
     writeNode =
         new WriteSuperFrameVariableConditionalNode(
             actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(name, null, mode), rhs);
   }
   replace(writeNode).execute(frame, value, enclosingFrame);
 }
Пример #8
0
 private Object frozen(Object object) {
   CompilerDirectives.transferToInterpreter();
   throw new RaiseException(
       getContext()
           .getCoreLibrary()
           .frozenError(getContext().getCoreLibrary().getLogicalClass(object).getName(), this));
 }
Пример #9
0
 protected PromiseHelperNode initPromiseHelper() {
   if (promiseHelper == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     promiseHelper = insert(new PromiseHelperNode());
   }
   return promiseHelper;
 }
Пример #10
0
  @Override
  public DynamicObject execute(VirtualFrame frame) {
    CompilerDirectives.transferToInterpreter();

    final Object receiverObject = receiver.execute(frame);

    final InternalMethod methodObject = (InternalMethod) methodNode.execute(frame);

    final DynamicObject module = (DynamicObject) receiverObject;
    assert RubyGuards.isRubyModule(module);

    final Visibility visibility = getVisibility(frame, methodObject.getName());
    final InternalMethod method =
        methodObject.withDeclaringModule(module).withVisibility(visibility);

    if (method.getVisibility() == Visibility.MODULE_FUNCTION) {
      Layouts.MODULE.getFields(module).addMethod(this, method.withVisibility(Visibility.PRIVATE));
      Layouts.MODULE
          .getFields(singletonClassNode.executeSingletonClass(module))
          .addMethod(this, method.withVisibility(Visibility.PUBLIC));
    } else {
      Layouts.MODULE.getFields(module).addMethod(this, method);
    }

    return getSymbol(method.getName());
  }
Пример #11
0
 protected String getNameFromSymbolInfo(VirtualFrame frame, RList symbol) {
   if (nameExtract == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
   }
   return RRuntime.asString(nameExtract.applyAccessField(frame, symbol, "name"));
 }
Пример #12
0
  @Specialization
  protected Object doInternal(VirtualFrame frame, RPromise x) {
    if (builtinCallNode == null) {
      RNode call = (RNode) x.getRep();
      RNode operand = (RNode) RASTUtils.unwrap(call);

      if (!(operand instanceof RCallNode)) {
        errorProfile.enter();
        throw RError.error(this, RError.Message.INVALID_INTERNAL);
      }

      RCallNode callNode = (RCallNode) operand;
      RNode func = callNode.getFunctionNode();
      String name = ((ReadVariableNode) func).getIdentifier();
      RFunction function = RContext.lookupBuiltin(name);
      if (function == null
          || function.isBuiltin() && function.getRBuiltin().getKind() != RBuiltinKind.INTERNAL) {
        errorProfile.enter();
        if (function == null && notImplemented(name)) {
          throw RInternalError.unimplemented(".Internal " + name);
        }
        throw RError.error(this, RError.Message.NO_SUCH_INTERNAL, name);
      }

      // .Internal function is validated
      CompilerDirectives.transferToInterpreterAndInvalidate();
      builtinCallNode = insert(RCallNode.createInternalCall(callNode, function));
    }
    return builtinCallNode.execute(frame);
  }
Пример #13
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;
    }
 private Object callToHash(VirtualFrame frame, final Object lastArgument) {
   if (callToHashNode == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     callToHashNode = insert(CallDispatchHeadNode.createMethodCall());
   }
   return callToHashNode.call(frame, lastArgument, "to_hash");
 }
 private boolean respondToToHash(VirtualFrame frame, final Object lastArgument) {
   if (respondToToHashNode == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     respondToToHashNode = insert(new DoesRespondDispatchHeadNode(getContext(), false));
   }
   return respondToToHashNode.doesRespondTo(frame, "to_hash", lastArgument);
 }
Пример #16
0
  @Override
  public Object executeDispatch(
      final VirtualFrame frame,
      final Object receiverObject,
      final Object methodName,
      DynamicObject blockObject,
      final Object[] argumentsObjects) {
    CompilerDirectives.transferToInterpreterAndInvalidate();

    // Make sure to have an up-to-date Shape.
    if (receiverObject instanceof DynamicObject) {
      ((DynamicObject) receiverObject).updateShape();
    }

    final DispatchNode dispatch =
        atomic(
            new Callable<DispatchNode>() {
              @Override
              public DispatchNode call() throws Exception {
                final DispatchNode first = getHeadNode().getFirstDispatchNode();

                // First try to see if we did not a miss a specialization added by another thread.

                DispatchNode lookupDispatch = first;
                while (lookupDispatch != null) {
                  if (lookupDispatch.guard(methodName, receiverObject)) {
                    // This one worked, no need to rewrite anything.
                    return lookupDispatch;
                  }
                  lookupDispatch = lookupDispatch.getNext();
                }

                // We need a new node to handle this case.

                final DispatchNode newDispathNode;

                if (depth == getContext().getOptions().DISPATCH_CACHE) {
                  newDispathNode =
                      new UncachedDispatchNode(
                          getContext(), ignoreVisibility, getDispatchAction(), missingBehavior);
                } else {
                  depth++;
                  if (RubyGuards.isForeignObject(receiverObject)) {
                    newDispathNode = createForeign(argumentsObjects, first, methodName);
                  } else if (RubyGuards.isRubyBasicObject(receiverObject)) {
                    newDispathNode =
                        doDynamicObject(frame, first, receiverObject, methodName, argumentsObjects);
                  } else {
                    newDispathNode = doUnboxedObject(frame, first, receiverObject, methodName);
                  }
                }

                first.replace(newDispathNode);
                return newDispathNode;
              }
            });

    return dispatch.executeDispatch(
        frame, receiverObject, methodName, blockObject, argumentsObjects);
  }
Пример #17
0
 private RStringVector castStringVector(Object o) {
   if (castStringNode == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     castStringNode = insert(CastStringNodeGen.create(true, true, true));
   }
   return (RStringVector) ((RStringVector) castStringNode.executeString(o)).copyDropAttributes();
 }
Пример #18
0
    @Specialization
    public DynamicObject toA(DynamicObject matchData) {
      CompilerDirectives.transferToInterpreter();

      return ArrayNodes.fromObjects(
          getContext().getCoreLibrary().getArrayClass(), getValues(matchData));
    }
Пример #19
0
    @Specialization
    public RubyBasicObject timeDecompose(VirtualFrame frame, RubyTime time) {
      CompilerDirectives.transferToInterpreter();
      final DateTime dateTime = time.getDateTime();
      final int sec = dateTime.getSecondOfMinute();
      final int min = dateTime.getMinuteOfHour();
      final int hour = dateTime.getHourOfDay();
      final int day = dateTime.getDayOfMonth();
      final int month = dateTime.getMonthOfYear();
      final int year = dateTime.getYear();

      int wday = dateTime.getDayOfWeek();

      if (wday == 7) {
        wday = 0;
      }

      final int yday = dateTime.getDayOfYear();
      final boolean isdst = false;

      final String envTimeZoneString = readTimeZoneNode.executeRubyString(frame).toString();
      String zoneString = org.jruby.RubyTime.zoneHelper(envTimeZoneString, dateTime, false);
      Object zone;
      if (zoneString.matches(".*-\\d+")) {
        zone = nil();
      } else {
        zone = createString(zoneString);
      }

      final Object[] decomposed =
          new Object[] {sec, min, hour, day, month, year, wday, yday, isdst, zone};
      return createArray(decomposed, decomposed.length);
    }
Пример #20
0
 private Object transpose(RAbstractVector value) {
   if (transpose == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     transpose = insert(TransposeNodeGen.create());
   }
   return transpose.execute(value);
 }
Пример #21
0
    @Specialization
    public Object end(DynamicObject matchData, int index) {
      CompilerDirectives.transferToInterpreter();

      if (badIndexProfile.profile((index < 0) || (index >= getNumberOfRegions(matchData)))) {
        CompilerDirectives.transferToInterpreter();

        throw new RaiseException(
            getContext()
                .getCoreLibrary()
                .indexError(String.format("index %d out of matches", index), this));

      } else {
        return MatchDataNodes.end(matchData, index);
      }
    }
Пример #22
0
    @Specialization(guards = "!isRubyBignum(b)")
    public boolean equal(VirtualFrame frame, DynamicObject a, DynamicObject b) {
      if (booleanCastNode == null) {
        CompilerDirectives.transferToInterpreter();
        booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
      }

      if (reverseCallNode == null) {
        CompilerDirectives.transferToInterpreter();
        reverseCallNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
      }

      final Object reversedResult = reverseCallNode.call(frame, b, "==", null, a);

      return booleanCastNode.executeBoolean(frame, reversedResult);
    }
Пример #23
0
    @Specialization
    public DynamicObject toS(DynamicObject matchData) {
      CompilerDirectives.transferToInterpreter();

      final ByteList bytes = Layouts.STRING.getByteList(getGlobal(matchData)).dup();
      return createString(bytes);
    }
Пример #24
0
 public Object fixnumOrBignum(BigInteger value) {
   if (fixnumOrBignum == null) {
     CompilerDirectives.transferToInterpreter();
     fixnumOrBignum = insert(new FixnumOrBignumNode(getContext(), getSourceSection()));
   }
   return fixnumOrBignum.fixnumOrBignum(value);
 }
Пример #25
0
 protected long getAddressFromSymbolInfo(VirtualFrame frame, RList symbol) {
   if (addressExtract == null) {
     CompilerDirectives.transferToInterpreterAndInvalidate();
     addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
   }
   return ((RExternalPtr) addressExtract.applyAccessField(frame, symbol, "address")).getAddr();
 }
Пример #26
0
  public int doInt(VirtualFrame frame, Object object) {
    // TODO CS 14-Nov-15 this code is crazy - should have separate nodes for ToRubyInteger and
    // ToJavaInt

    final Object integerObject = executeIntOrLong(frame, object);

    if (wasInteger.profile(integerObject instanceof Integer)) {
      return (int) integerObject;
    }

    if (wasLong.profile(integerObject instanceof Long)) {
      final long longValue = (long) integerObject;

      if (wasLongInRange.profile(CoreLibrary.fitsIntoInteger(longValue))) {
        return (int) longValue;
      }
    }

    CompilerDirectives.transferToInterpreter();
    if (RubyGuards.isRubyBignum(object)) {
      throw new RaiseException(
          getContext().getCoreLibrary().rangeError("bignum too big to convert into `long'", this));
    } else {
      throw new UnsupportedOperationException(object.getClass().toString());
    }
  }
Пример #27
0
  private Object lookupRestKeywordArgumentHash(VirtualFrame frame) {
    final Object hash = readUserKeywordsHashNode.execute(frame);

    if (noHash.profile(hash == null)) {
      return Layouts.HASH.createHash(
          coreLibrary().getHashFactory(), null, 0, null, null, null, null, false);
    }

    CompilerDirectives.bailout("Ruby keyword arguments aren't optimized");

    final DynamicObject hashObject = (DynamicObject) hash;

    final List<Map.Entry<Object, Object>> entries = new ArrayList<>();

    outer:
    for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(hashObject)) {
      if (!RubyGuards.isRubySymbol(keyValue.getKey())) {
        continue;
      }

      for (String excludedKeyword : excludedKeywords) {
        if (excludedKeyword.equals(keyValue.getKey().toString())) {
          continue outer;
        }
      }

      entries.add(keyValue);
    }

    return BucketsStrategy.create(
        getContext(), entries, Layouts.HASH.getCompareByIdentity(hashObject));
  }
Пример #28
0
  public DynamicObject getNormalObjectSingletonClass(DynamicObject object) {
    CompilerAsserts.neverPartOfCompilation();

    if (RubyGuards.isRubyClass(object)) { // For the direct caller
      return ClassNodes.getSingletonClass(object);
    }

    if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(object))) {
      return Layouts.BASIC_OBJECT.getMetaClass(object);
    }

    CompilerDirectives.transferToInterpreter();
    final DynamicObject logicalClass = BasicObjectNodes.getLogicalClass(object);

    DynamicObject attached = null;
    if (RubyGuards.isRubyModule(object)) {
      attached = object;
    }

    final String name =
        String.format(
            "#<Class:#<%s:0x%x>>",
            Layouts.MODULE.getFields(logicalClass).getName(),
            BasicObjectNodes.verySlowGetObjectID(object));
    final DynamicObject singletonClass =
        ClassNodes.createSingletonClassOfObject(getContext(), logicalClass, attached, name);
    propagateFrozen(object, singletonClass);

    Layouts.BASIC_OBJECT.setMetaClass(object, singletonClass);

    return singletonClass;
  }
Пример #29
0
  @Specialization
  public DynamicObject assertNotCompiled() {
    final boolean[] compiled = new boolean[] {CompilerDirectives.inCompiledCode()};

    sideEffect = compiled;

    if (compiled[0]) {
      CompilerDirectives.transferToInterpreterAndInvalidate();
      throw new RaiseException(
          getContext()
              .getCoreLibrary()
              .internalError("Call to Truffle::Primitive.assert_not_compiled was compiled", this));
    }

    return nil();
  }
Пример #30
0
 @SuppressWarnings("unused")
 @Specialization
 protected Object updateLengthError(Object vector, Object lengthVector) {
   controlVisibility();
   CompilerDirectives.transferToInterpreter();
   throw RError.error(this, RError.Message.INVALID_UNNAMED_VALUE);
 }