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: 7886e2db9fef
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8f81e15180be
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Feb 16, 2015

  1. [Truffle] Fix Fixnum#div(Bignum).

    * Essentially, as Bignum#coerce(Fixnum).first returns Fixnum,
      all Fixnum operations should act on Bignum instead of doing it
      via coercion.
    eregon committed Feb 16, 2015
    Copy the full SHA
    a93592d View commit details
  2. Copy the full SHA
    8f81e15 View commit details
Showing with 17 additions and 3 deletions.
  1. +12 −2 truffle/src/main/java/org/jruby/truffle/runtime/ObjectIDOperations.java
  2. +5 −1 truffle/src/main/ruby/core/rubinius/common/fixnum.rb
Original file line number Diff line number Diff line change
@@ -65,12 +65,14 @@ public static long smallFixnumToID(long fixnum) {

public static RubyBignum largeFixnumToID(RubyContext context, long fixnum) {
assert !isSmallFixnum(fixnum);
return new RubyBignum(context.getCoreLibrary().getBignumClass(), BigInteger.valueOf(fixnum).or(LARGE_FIXNUM_FLAG));
BigInteger big = unsignedBigInteger(fixnum);
return new RubyBignum(context.getCoreLibrary().getBignumClass(), big.or(LARGE_FIXNUM_FLAG));
}

public static RubyBignum floatToID(RubyContext context, double value) {
long bits = Double.doubleToRawLongBits(value);
return new RubyBignum(context.getCoreLibrary().getBignumClass(), BigInteger.valueOf(bits).or(FLOAT_FLAG));
BigInteger big = unsignedBigInteger(bits);
return new RubyBignum(context.getCoreLibrary().getBignumClass(), big.or(FLOAT_FLAG));
}

// ID => primitive
@@ -99,4 +101,12 @@ public static double toFloat(RubyBignum id) {
return Double.longBitsToDouble(id.bigIntegerValue().longValue());
}

private static BigInteger unsignedBigInteger(long value) {
BigInteger big = BigInteger.valueOf(value);
if (value < 0) {
big = new BigInteger(1, big.toByteArray()); // consider as unsigned
}
return big;
}

}
6 changes: 5 additions & 1 deletion truffle/src/main/ruby/core/rubinius/common/fixnum.rb
Original file line number Diff line number Diff line change
@@ -26,6 +26,10 @@

# Only part of Rubinius' fixnum.rb

# Our Bignum#coerce(Fixnum).first returns a Fixnum and not a Bignum.
# Therefore all Fixnum operations should handle Bignum (or Integer)
# explicitly instead of using coercion.

class Fixnum

alias_method :modulo, :%
@@ -36,7 +40,7 @@ def coerce(other)
end

def fdiv(n)
if n.kind_of?(Fixnum)
if n.kind_of?(Integer) # Truffle: Fixnum => Integer, to handle Bignum as MRI
to_f / n
else
redo_coerced :fdiv, n