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

Commits on Oct 31, 2014

  1. [Truffle] Implement Fixnum#<<(int) correctly.

    * Mostly, there was no case to return an int.
    eregon committed Oct 31, 2014
    Copy the full SHA
    403f65f View commit details
  2. [Truffle] FixnumLowerNode should throw a TypeError if it fails.

    * Add an helper method for typeErrorCantConvertInto.
    eregon committed Oct 31, 2014
    Copy the full SHA
    b605cb5 View commit details
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.control.PassthroughNode;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyFixnum;
import org.jruby.truffle.runtime.core.RubyRange;
@@ -107,7 +108,8 @@ public Object execute(VirtualFrame frame) {
return value;
}

throw new UnsupportedOperationException(value.getClass().getName());
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
value, getContext().getCoreLibrary().getIntegerClass(), this));
}

@Override
50 changes: 43 additions & 7 deletions core/src/main/java/org/jruby/truffle/nodes/core/FixnumNodes.java
Original file line number Diff line number Diff line change
@@ -1187,21 +1187,49 @@ public LeftShiftNode(LeftShiftNode prev) {
fixnumOrBignum = prev.fixnumOrBignum;
}

@Specialization
public Object leftShift(int a, int b) {
return leftShift((long) a, b);
@Specialization(guards = "canShiftIntoInt")
public int leftShift(int a, int b) {
if (b > 0) {
bAboveZeroProfile.enter();

return a << b;
} else {
bNotAboveZeroProfile.enter();
if (-b >= Integer.SIZE) {
return 0;
} else {
return a >> -b;
}
}
}

@Specialization(guards = "canShiftIntoLong")
public long leftShift(long a, int b) {
if (b > 0) {
bAboveZeroProfile.enter();

return a << b;
} else {
bNotAboveZeroProfile.enter();

if (-b >= Long.SIZE) {
return 0;
} else {
return a >> -b;
}
}
}

@Specialization
public Object leftShift(long a, int b) {
public Object leftShiftWithOverflow(long a, int b) {
if (b > 0) {
bAboveZeroProfile.enter();

if (Long.SIZE - Long.numberOfLeadingZeros(a) + b > Long.SIZE - 1) {
if (canShiftIntoLong(a, b)) {
return a << b;
} else {
useBignumProfile.enter();
return fixnumOrBignum.fixnumOrBignum(SlowPathBigInteger.shiftLeft(BigInteger.valueOf(a), b));
} else {
return a << b;
}
} else {
bNotAboveZeroProfile.enter();
@@ -1214,6 +1242,14 @@ public Object leftShift(long a, int b) {
}
}

static boolean canShiftIntoInt(int a, int b) {
return Integer.numberOfLeadingZeros(a) - b > 0;
}

static boolean canShiftIntoLong(long a, int b) {
return Long.numberOfLeadingZeros(a) - b > 0;
}

}

@CoreMethod(names = ">>", required = 1, lowerFixnumParameters = 0)
Original file line number Diff line number Diff line change
@@ -485,6 +485,10 @@ public RubyException typeErrorCantConvertInto(String from, String to, Node curre
return typeError(String.format("can't convert %s into %s", from, to), currentNode);
}

public RubyException typeErrorCantConvertInto(Object from, RubyClass to, Node currentNode) {
return typeErrorCantConvertInto(box(from).getLogicalClass().getName(), to.getName(), currentNode);
}

public RubyException typeErrorIsNotA(String value, String expectedType, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return typeError(String.format("%s is not a %s", value, expectedType), currentNode);
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/bit_and_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Fixnum#& raises a TypeError when passed a Float
fails:Fixnum#& raises a TypeError and does not call #to_int when defined on an object
fails:Fixnum#& returns self bitwise AND a Bignum
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/bit_or_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Fixnum#| raises a TypeError when passed a Float
fails:Fixnum#| raises a TypeError and does not call #to_int when defined on an object
fails:Fixnum#| returns self bitwise OR other
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/fixnum/bit_xor_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Fixnum#^ returns self bitwise EXCLUSIVE OR other
fails:Fixnum#^ returns self bitwise EXCLUSIVE OR a Bignum
fails:Fixnum#^ raises a TypeError when passed a Float
fails:Fixnum#^ raises a TypeError and does not call #to_int when defined on an object
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/divmod_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Fixnum#divmod returns an Array containing quotient and modulus obtained from dividing self by the given argument
fails:Fixnum#divmod raises a TypeError when given a non-Integer
fails:Fixnum#divmod raises a ZeroDivisionError when the given argument is 0 and a Float
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/fixnum/exponent_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
fails:Fixnum#** returns self raised to the given power
fails:Fixnum#** overflows the answer to a bignum transparantly
fails:Fixnum#** raises negative numbers to the given power
fails:Fixnum#** can raise 1 to a Bignum safely
fails:Fixnum#** can raise -1 to a Bignum safely
fails:Fixnum#** switches to a Float when the number is too big
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/fixnum/left_shift_tags.txt
Original file line number Diff line number Diff line change
@@ -3,5 +3,3 @@ fails:Fixnum#<< with n << m returns a Bignum == fixnum_max() * 2 when fixnum_max
fails:Fixnum#<< with n << m returns a Bignum == fixnum_min() * 2 when fixnum_min() << 1 and n < 0
fails:Fixnum#<< with n << m calls #to_int to convert the argument to an Integer
fails:Fixnum#<< with n << m raises a TypeError when #to_int does not return an Integer
fails:Fixnum#<< with n << m raises a TypeError when passed nil
fails:Fixnum#<< with n << m raises a TypeError when passed a String
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/minus_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Fixnum#- raises a TypeError when given a non-Integer
fails:Fixnum#- returns self minus the given Integer
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/multiply_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Fixnum#* raises a TypeError when given a non-Integer
fails:Fixnum#* overflows to Bignum when the result does not fit in Fixnum
fails:Fixnum#* returns self multiplied by the given Integer
1 change: 0 additions & 1 deletion spec/truffle/tags/core/fixnum/plus_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Fixnum#+ returns self plus the given Integer
fails:Fixnum#+ raises a TypeError when given a non-Integer