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

Commits on Sep 14, 2015

  1. Copy the full SHA
    389f1f1 View commit details
  2. [Truffle] Cleanup of Fixnum#<< and #>>.

    * Fixes some edge cases as well.
    eregon committed Sep 14, 2015
    Copy the full SHA
    8f737b4 View commit details
  3. Copy the full SHA
    33007cb View commit details
  4. Synchronize Fixnum#<< and #>>

    * The removed code is already covered just above.
    eregon committed Sep 14, 2015
    Copy the full SHA
    4fb2e0f View commit details
22 changes: 20 additions & 2 deletions spec/ruby/core/fixnum/left_shift_spec.rb
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@

it "returns n shifted left m bits when n < 0, m > 0" do
(-1 << 1).should == -2
(-7 << 1).should == -14
(-42 << 2).should == -168
end

it "returns n shifted right m bits when n > 0, m < 0" do
@@ -29,8 +31,24 @@
(-1 << 0).should == -1
end

it "returns 0 when m < 0 and m == p where 2**p > n >= 2**(p-1)" do
(4 << -3).should == 0
it "returns 0 when n > 0, m < 0 and n < 2**-m" do
(3 << -2).should == 0
(7 << -3).should == 0
(127 << -7).should == 0

# To make sure the exponent is not truncated
(7 << -32).should == 0
(7 << -64).should == 0
end

it "returns -1 when n < 0, m < 0 and n > -(2**-m)" do
(-3 << -2).should == -1
(-7 << -3).should == -1
(-127 << -7).should == -1

# To make sure the exponent is not truncated
(-7 << -32).should == -1
(-7 << -64).should == -1
end

not_compliant_on :rubinius, :jruby do
10 changes: 0 additions & 10 deletions spec/ruby/core/fixnum/right_shift_spec.rb
Original file line number Diff line number Diff line change
@@ -51,16 +51,6 @@
(-7 >> 64).should == -1
end

fixnum_bits = (Math.log(fixnum_max) / Math.log(2)).to_i

it "returns 0 when m is outside the available bits and n >= 0" do
(2 >> (fixnum_bits + 1)).should == 0
end

it "returns -1 when m is outside the available bits and n < 0" do
(-2 >> (fixnum_bits + 1)).should == -1
end

not_compliant_on :rubinius do
it "returns 0 when m is a Bignum" do
(3 >> bignum_value).should == 0
Original file line number Diff line number Diff line change
@@ -18,10 +18,12 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.core.fixnum.FixnumNodesFactory.RightShiftNodeFactory;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.methods.UnsupportedOperationBehavior;
@@ -825,69 +827,54 @@ public Object bitXOr(VirtualFrame frame, Object a, DynamicObject b) {
@CoreMethod(names = "<<", required = 1, lowerFixnumParameters = 0)
public abstract static class LeftShiftNode extends BignumNodes.BignumCoreMethodNode {

@Child private RightShiftNode rightShiftNode;
@Child private CallDispatchHeadNode fallbackCallNode;

public LeftShiftNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

protected Object lower(BigInteger value) {
return fixnumOrBignum(value);
}

public abstract Object executeLeftShift(VirtualFrame frame, Object a, Object b);

@Specialization(guards = {"isPositive(b)", "canShiftIntoInt(a, b)"})
@Specialization(guards = { "b >= 0", "canShiftIntoInt(a, b)" })
public int leftShift(int a, int b) {
return a << b;
}

@Specialization(guards = {"isPositive(b)", "canShiftIntoInt(a, b)"})
@Specialization(guards = { "b >= 0", "canShiftIntoInt(a, b)" })
public int leftShift(int a, long b) {
return a << b;
}

@Specialization(guards = "isStrictlyNegative(b)")
public int leftShiftNeg(int a, int b) {
if (-b >= Integer.SIZE) {
return 0;
} else if (b == Integer.MIN_VALUE) {
return 0;
} else {
return a >> -b;
}
}

@Specialization(guards = {"isPositive(b)", "canShiftIntoLong(a, b)"})
@Specialization(guards = { "b >= 0", "canShiftIntoLong(a, b)" })
public long leftShiftToLong(long a, int b) {
return a << b;
}

@Specialization(guards = {"isPositive(b)"})
@Specialization(guards = "b >= 0")
public Object leftShiftWithOverflow(long a, int b) {
if (canShiftIntoLong(a, b)) {
return leftShiftToLong(a, b);
} else {
return lower(BigInteger.valueOf(a).shiftLeft(b));
return fixnumOrBignum(BigInteger.valueOf(a).shiftLeft(b));
}
}

@Specialization(guards = "isStrictlyNegative(b)")
public long leftShiftNeg(long a, int b) {
if (-b >= Integer.SIZE) {
return 0;
} else {
return a >> -b;
@Specialization(guards = "b < 0")
public Object leftShiftNeg(VirtualFrame frame, long a, int b) {
if (rightShiftNode == null) {
CompilerDirectives.transferToInterpreter();
rightShiftNode = insert(RightShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
}
return rightShiftNode.executeRightShift(frame, a, -b);
}

@Specialization(guards = {"!isInteger(b)", "!isLong(b)"})
@Specialization(guards = { "!isInteger(b)", "!isLong(b)" })
public Object leftShiftFallback(VirtualFrame frame, Object a, Object b) {
if (fallbackCallNode == null) {
CompilerDirectives.transferToInterpreter();
fallbackCallNode = insert(DispatchHeadNodeFactory.createMethodCallOnSelf(getContext()));
}

return fallbackCallNode.call(frame, a, "left_shift_fallback", null, b);
}

@@ -899,26 +886,10 @@ static boolean canShiftIntoInt(int a, long b) {
return Integer.numberOfLeadingZeros(a) - b > 0;
}

static boolean canShiftIntoLong(int a, int b) {
return canShiftIntoLong((long) a, b);
}

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

static boolean isPositive(int value) {
return value >= 0;
}

static boolean isPositive(long value) {
return value >= 0;
}

static boolean isStrictlyNegative(int value) {
return value < 0;
}

}

@CoreMethod(names = ">>", required = 1, lowerFixnumParameters = 0)
@@ -931,92 +902,72 @@ public RightShiftNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public abstract Object executeRightShift(VirtualFrame frame, Object a, Object b);

@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, int a, int b) {
if (b > 0) {
if (b >= Integer.SIZE - 1) {
if (a < 0) {
return -1;
} else {
return 0;
}
} else {
return a >> b;
}
if (b >= Integer.SIZE - 1) {
return a < 0 ? -1 : 0;
} else {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null}));
}

return leftShiftNode.executeLeftShift(frame, a, -b);
return a >> b;
}
}

@Specialization
@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, int a, long b) {
if (b > 0) {
if (b >= Integer.SIZE - 1) {
if (a < 0) {
return -1;
} else {
return 0;
}
} else {
return a >> b;
}
if (b >= Integer.SIZE - 1) {
return a < 0 ? -1 : 0;
} else {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null}));
}

return leftShiftNode.executeLeftShift(frame, a, -b);
return a >> b;
}
}

@Specialization
@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, long a, int b) {
if (b > 0) {
if (b >= Long.SIZE - 1) {
if (a < 0) {
return -1;
} else {
return 0;
}
} else {
return a >> b;
}
if (b >= Long.SIZE - 1) {
return a < 0 ? -1 : 0;
} else {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null}));
}

return leftShiftNode.executeLeftShift(frame, a, -b);
return a >> b;
}
}

@Specialization(guards = "isRubyBignum(b)")
public int rightShift(int a, DynamicObject b) {
return 0;
@Specialization(guards = "b < 0")
public Object rightShiftNeg(VirtualFrame frame, long a, int b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
}
return leftShiftNode.executeLeftShift(frame, a, -b);
}

@Specialization(guards = "isRubyBignum(b)")
@Specialization(guards = { "isRubyBignum(b)", "isPositive(b)" })
public int rightShift(long a, DynamicObject b) {
return 0;
}

@Specialization(guards = {"!isInteger(b)", "!isLong(b)"})
@Specialization(guards = { "isRubyBignum(b)", "!isPositive(b)" })
public Object rightShiftNeg(VirtualFrame frame, long a, DynamicObject b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
}
CompilerDirectives.transferToInterpreter();
return leftShiftNode.executeLeftShift(frame, a, Layouts.BIGNUM.getValue(b).negate());
}

@Specialization(guards = { "!isInteger(b)", "!isLong(b)" })
public Object rightShiftFallback(VirtualFrame frame, Object a, Object b) {
if (fallbackCallNode == null) {
CompilerDirectives.transferToInterpreter();
fallbackCallNode = insert(DispatchHeadNodeFactory.createMethodCallOnSelf(getContext()));
}

return fallbackCallNode.call(frame, a, "right_shift_fallback", null, b);
}

protected static boolean isPositive(DynamicObject b) {
return Layouts.BIGNUM.getValue(b).signum() >= 0;
}

}

@CoreMethod(names = {"abs", "magnitude"})