Esempio n. 1
0
  @Override
  public Object execute(VirtualFrame frame) {
    while (true) {
      getContext().getSafepointManager().poll();

      Object result;

      try {
        result = tryPart.execute(frame);
      } catch (ControlFlowException exception) {
        controlFlowProfile.enter();
        throw exception;
      } catch (RaiseException exception) {
        raiseExceptionProfile.enter();

        try {
          return handleException(frame, exception);
        } catch (RetryException e) {
          continue;
        }
      } finally {
        clearExceptionVariableNode.execute(frame);
      }

      elseProfile.enter();
      elsePart.executeVoid(frame);
      return result;
    }
  }
Esempio n. 2
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;
    }
Esempio n. 3
0
    @CompilerDirectives.SlowPath
    private RubyString formatSlow(RubyString format, Object[] args) {
      final RubyContext context = getContext();

      if (args.length == 1 && args[0] instanceof RubyArray) {
        singleArrayProfile.enter();
        return context.makeString(
            StringFormatter.format(format.toString(), ((RubyArray) args[0]).asList()));
      } else {
        multipleArgumentsProfile.enter();
        return context.makeString(StringFormatter.format(format.toString(), Arrays.asList(args)));
      }
    }
Esempio n. 4
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);
   }
 }
Esempio n. 5
0
 @Specialization
 public Object leftShift(DynamicObject a, int b) {
   if (b >= 0) {
     return fixnumOrBignum(Layouts.BIGNUM.getValue(a).shiftRight(b));
   } else {
     bLessThanZero.enter();
     return fixnumOrBignum(Layouts.BIGNUM.getValue(a).shiftLeft(-b));
   }
 }
 @Override
 public Object execute(VirtualFrame frame) {
   if (RubyArguments.getUserArgumentsCount(frame.getArguments()) < minimum) {
     defaultValueProfile.enter();
     return defaultValue.execute(frame);
   } else {
     return RubyArguments.getUserArgument(frame.getArguments(), index);
   }
 }
Esempio n. 7
0
  @Override
  public Object execute(VirtualFrame frame) {
    try {
      assert assertArgumentsShouldBeVisible(frame);

      final Object result = child.execute(frame);

      assert shouldObjectBeVisible(result)
          : "result@" + getEncapsulatingSourceSection().getShortDescription();

      return result;
    } catch (StackOverflowError error) {
      // TODO: we might want to do sth smarter here to avoid consuming frames when we are almost out
      // of it.
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(translate(error));
    } catch (TruffleFatalException | ThreadExitException exception) {
      throw exception;
    } catch (ControlFlowException exception) {
      controlProfile.enter();
      throw exception;
    } catch (RaiseException exception) {
      rethrowProfile.enter();
      throw exception;
    } catch (MainExitException exception) {
      CompilerDirectives.transferToInterpreter();
      throw exception;
    } catch (ArithmeticException exception) {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(translate(exception));
    } catch (UnsupportedSpecializationException exception) {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(translate(exception));
    } catch (org.jruby.exceptions.RaiseException e) {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(getContext().toTruffle(e.getException(), this));
    } catch (Throwable exception) {
      CompilerDirectives.transferToInterpreter();
      throw new RaiseException(translate(exception));
    }
  }
Esempio n. 8
0
  @Override
  public Object execute(VirtualFrame frame) {
    try {
      return body.execute(frame);
    } catch (BreakException e) {
      breakProfile.enter();

      if (matchingBreakProfile.profile(e.getBreakID() == breakID)) {
        return e.getResult();
      } else {
        throw e;
      }
    }
  }
Esempio n. 9
0
  @Override
  public Object execute(VirtualFrame frame) {
    final RubyClass arrayClass = getContext().getCoreLibrary().getArrayClass();

    int count = RubyArguments.getUserArgumentsCount(frame.getArguments());

    int endIndex = count + negativeEndIndex;

    if (keywordArguments) {
      final Object lastArgument =
          RubyArguments.getUserArgument(
              frame.getArguments(), RubyArguments.getUserArgumentsCount(frame.getArguments()) - 1);

      if (lastArgument instanceof RubyHash) {
        endIndex -= 1;
      }
    }

    final int length = endIndex - startIndex;

    if (startIndex == 0) {
      final Object[] arguments = RubyArguments.extractUserArguments(frame.getArguments());
      return new RubyArray(arrayClass, arguments, length);
    } else {
      if (startIndex >= endIndex) {
        noArgumentsLeftProfile.enter();
        return new RubyArray(arrayClass);
      } else {
        subsetOfArgumentsProfile.enter();
        final Object[] arguments = RubyArguments.extractUserArguments(frame.getArguments());
        // TODO(CS): risk here of widening types too much - always going to be Object[] - does seem
        // to be something that does happen
        return new RubyArray(
            arrayClass, ArrayUtils.extractRange(arguments, startIndex, endIndex), length);
      }
    }
  }
Esempio n. 10
0
  @Override
  public RubyBasicObject executeRubyBasicObject(VirtualFrame frame) {
    final Object object = child.execute(frame);

    RubyBasicObject boxedObject;

    if (object instanceof RubyBasicObject) {
      boxedObject = (RubyBasicObject) object;
    } else {
      boxBranch.enter();
      boxedObject = getContext().getCoreLibrary().box(object);
    }

    return boxedObject;
  }
Esempio n. 11
0
  @ExplodeLoop
  @Specialization(guards = {"isPackedHash(hash)", "!isRubyString(key)"})
  public Object setPackedArray(
      VirtualFrame frame, DynamicObject hash, Object key, Object value, boolean byIdentity) {
    assert HashNodes.verifyStore(hash);

    final int hashed = hashNode.hash(frame, key);

    final Object[] store = (Object[]) Layouts.HASH.getStore(hash);
    final int size = Layouts.HASH.getSize(hash);

    for (int n = 0; n < PackedArrayStrategy.MAX_ENTRIES; n++) {
      if (n < size) {
        if (hashed == PackedArrayStrategy.getHashed(store, n)) {
          final boolean equal;

          if (byIdentityProfile.profile(byIdentity)) {
            equal =
                equalNode.executeReferenceEqual(frame, key, PackedArrayStrategy.getKey(store, n));
          } else {
            equal =
                eqlNode.callBoolean(frame, key, "eql?", null, PackedArrayStrategy.getKey(store, n));
          }

          if (equal) {
            PackedArrayStrategy.setValue(store, n, value);
            assert HashNodes.verifyStore(hash);
            return value;
          }
        }
      }
    }

    extendProfile.enter();

    if (strategyProfile.profile(size + 1 <= PackedArrayStrategy.MAX_ENTRIES)) {
      PackedArrayStrategy.setHashedKeyValue(store, size, hashed, key, value);
      Layouts.HASH.setSize(hash, size + 1);
      return value;
    } else {
      PackedArrayStrategy.promoteToBuckets(hash, store, size);
      BucketsStrategy.addNewEntry(hash, hashed, key, value);
    }

    assert HashNodes.verifyStore(hash);

    return value;
  }
Esempio n. 12
0
  @Override
  public Object execute(VirtualFrame frame) {
    if (index >= RubyArguments.getUserArgumentsCount(frame.getArguments())) {
      outOfRangeProfile.enter();

      switch (missingArgumentBehaviour) {
        case RUNTIME_ERROR:
          break;

        case UNDEFINED:
          return UndefinedPlaceholder.INSTANCE;

        case NIL:
          return nil();
      }
    }

    return argumentValueProfile.profile(RubyArguments.getUserArgument(frame.getArguments(), index));
  }
Esempio n. 13
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;
        }
      }
    }
  }
Esempio n. 14
0
  @Override
  public boolean executeBoolean(VirtualFrame frame) {
    // TODO(CS): express this using normal nodes?

    // If we don't accept any arguments, there's never any need to destructure
    // TODO(CS): is this guaranteed by the translator anyway?

    if (!arity.allowsMore() && arity.getRequired() == 0 && arity.getOptional() == 0) {
      return false;
    }

    // If we only accept one argument, there's never any need to destructure

    if (!arity.allowsMore() && arity.getRequired() == 1 && arity.getOptional() == 0) {
      return false;
    }

    // If the caller supplied no arguments, or more than one argument, there's no need to
    // destructure this time

    if (RubyArguments.getUserArgumentsCount(frame.getArguments()) != 1) {
      return false;
    }

    // If the single argument is a RubyArray, destructure
    // TODO(CS): can we not just reply on the respondToCheck? Should experiment.

    if (RubyGuards.isRubyArray(RubyArguments.getUserArgument(frame.getArguments(), 0))) {
      return true;
    }

    // If the single argument responds to #to_ary, then destructure

    checkRespondProfile.enter();

    return respondToCheck.executeBoolean(frame);
  }