Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: eaa1b9f0732e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: de1981ae70e3
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Jan 24, 2016

  1. Copy the full SHA
    a72faee View commit details
  2. Copy the full SHA
    de1981a View commit details
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.utilities.ConditionProfile;
@@ -40,6 +41,12 @@ public FixnumOrBignumNode(RubyContext context, SourceSection sourceSection) {
private final ConditionProfile integerFromDoubleProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile longFromDoubleProfile = ConditionProfile.createBinaryProfile();

public Object fixnumOrBignum(BigDecimal value) {
CompilerDirectives.transferToInterpreter();

return fixnumOrBignum(value.toBigInteger());
}

public Object fixnumOrBignum(BigInteger value) {
if (lowerProfile.profile(value.compareTo(LONG_MIN_BIGINT) >= 0 && value.compareTo(LONG_MAX_BIGINT) <= 0)) {
final long longValue = value.longValue();
Original file line number Diff line number Diff line change
@@ -17,10 +17,12 @@
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyBignum;
import org.jruby.RubyFixnum;
import org.jruby.RubyRational;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
@@ -1830,6 +1832,8 @@ public Object absSpecial(VirtualFrame frame, DynamicObject value) {
@CoreMethod(names = "round", optional = 2)
public abstract static class RoundNode extends BigDecimalCoreMethodArrayArgumentsNode {

@Child private FixnumOrBignumNode fixnumOrBignumNode;

public RoundNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -1851,7 +1855,12 @@ private BigDecimal round(DynamicObject value, int digit, RoundingMode roundingMo

@Specialization(guards = "isNormal(value)")
public Object round(VirtualFrame frame, DynamicObject value, NotProvided digit, NotProvided roundingMode) {
return createBigDecimal(frame, round(value, 0, getRoundMode(frame)));
if (fixnumOrBignumNode == null) {
CompilerDirectives.transferToInterpreter();
fixnumOrBignumNode = insert(FixnumOrBignumNode.create(getContext(), getSourceSection()));
}

return fixnumOrBignumNode.fixnumOrBignum(round(value, 0, getRoundMode(frame)));
}

@Specialization(guards = "isNormal(value)")
@@ -1866,6 +1875,11 @@ public Object round(VirtualFrame frame, DynamicObject value, int digit, int roun

@Specialization(guards = "!isNormal(value)")
public Object roundSpecial(VirtualFrame frame, DynamicObject value, NotProvided precision, Object unusedRoundingMode) {
if (fixnumOrBignumNode == null) {
CompilerDirectives.transferToInterpreter();
fixnumOrBignumNode = insert(FixnumOrBignumNode.create(getContext(), getSourceSection()));
}

switch (Layouts.BIG_DECIMAL.getType(value)) {
case NEGATIVE_INFINITY:
CompilerDirectives.transferToInterpreter();
@@ -1876,7 +1890,7 @@ public Object roundSpecial(VirtualFrame frame, DynamicObject value, NotProvided
throw new RaiseException(getContext().getCoreLibrary().
floatDomainError("Computation results to 'Infinity'", this));
case NEGATIVE_ZERO:
return value;
return fixnumOrBignumNode.fixnumOrBignum(Layouts.BIG_DECIMAL.getValue(value));
case NAN:
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().
@@ -2111,34 +2125,45 @@ public Object doOther(VirtualFrame frame, DynamicObject value, Object roundingMo
"value.numerator",
"value", value);

final long numeratorValue;
final IRubyObject numeratorValue;

if (numerator instanceof Integer) {
numeratorValue = (int) numerator;
numeratorValue = RubyFixnum.newFixnum(getContext().getRuntime(), (int) numerator);
} else if (numerator instanceof Long) {
numeratorValue = (long) numerator;
numeratorValue = RubyFixnum.newFixnum(getContext().getRuntime(), (long) numerator);
} else if (RubyGuards.isRubyBignum(numerator)) {
numeratorValue = RubyBignum.newBignum(getContext().getRuntime(), Layouts.BIGNUM.getValue((DynamicObject) numerator));
} else {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(numerator.toString());
}

final Object denominator = ruby(
frame,
"value.denominator",
"value", value);

final long denominatorValue;
final IRubyObject denominatorValue;

if (denominator instanceof Integer) {
denominatorValue = (int) denominator;
denominatorValue = RubyFixnum.newFixnum(getContext().getRuntime(), (int) denominator);
} else if (denominator instanceof Long) {
denominatorValue = (long) denominator;
denominatorValue = RubyFixnum.newFixnum(getContext().getRuntime(), (long) denominator);
} else if (RubyGuards.isRubyBignum(denominator)) {
denominatorValue = RubyBignum.newBignum(getContext().getRuntime(), Layouts.BIGNUM.getValue((DynamicObject) denominator));
} else {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException(denominator.toString());
}

final RubyRational rubyRationalValue = RubyRational.newRationalRaw(getContext().getRuntime(), RubyFixnum.newFixnum(getContext().getRuntime(), numeratorValue), RubyFixnum.newFixnum(getContext().getRuntime(), denominatorValue));
final RubyRational rubyRationalValue = RubyRational.newRationalRaw(getContext().getRuntime(), numeratorValue, denominatorValue);

final RubyBigDecimal rubyBigDecimalValue = RubyBigDecimal.getVpRubyObjectWithPrec19Inner(getContext().getRuntime().getCurrentContext(), rubyRationalValue, (RoundingMode) roundingMode);
final RubyBigDecimal rubyBigDecimalValue;

try {
rubyBigDecimalValue = RubyBigDecimal.getVpRubyObjectWithPrec19Inner(getContext().getRuntime().getCurrentContext(), rubyRationalValue, (RoundingMode) roundingMode);
} catch (Exception e) {
e.printStackTrace();
throw e;
}

return rubyBigDecimalValue.getBigDecimalValue();
} else {