Skip to content

Commit

Permalink
Showing 4 changed files with 79 additions and 37 deletions.
40 changes: 40 additions & 0 deletions spec/truffle/specs/truffle/fixnum/and_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

require_relative '../../../../ruby/spec_helper'

describe "Fixnum#&" do
before :each do
@long = (1 << 48) + 1
@mask = Truffle::Primitive.fixnum_lower((1 << 30) - 1)
end

it "returns an int for (int, int)" do
result = (1 & 3)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
end

it "returns an int for (long, int)" do
Truffle::Runtime.java_class_of(@long).should == 'Long'
Truffle::Runtime.java_class_of(@mask).should == 'Integer'

result = (@long & @mask)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
end

it "returns an int for (int, long)" do
Truffle::Runtime.java_class_of(@long).should == 'Long'
Truffle::Runtime.java_class_of(@mask).should == 'Integer'

result = (@mask & @long)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
end
end
Original file line number Diff line number Diff line change
@@ -12,12 +12,15 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.ExactMath;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.*;
@@ -28,6 +31,7 @@
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.CoreLibrary;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;
@@ -756,17 +760,27 @@ public BitAndNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int bitAnd(int a, int b) {
public int bitAndIntInt(int a, int b) {
return a & b;
}

@Specialization
public long bitAnd(long a, long b) {
public int bitAndIntLong(int a, long b) {
return a & ((int) b);
}

@Specialization
public int bitAndLongInt(long a, int b) {
return ((int) a) & b;
}

@Specialization
public long bitAndLongLong(long a, long b) {
return a & b;
}

@Specialization(guards = "isRubyBignum(b)")
public Object bitAnd(long a, DynamicObject b) {
public Object bitAndBignum(long a, DynamicObject b) {
return fixnumOrBignum(BigInteger.valueOf(a).and(Layouts.BIGNUM.getValue(b)));
}
}
@@ -840,9 +854,9 @@ public int leftShift(int a, int b) {
return a << b;
}

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

@Specialization(guards = { "b >= 0", "canShiftIntoLong(a, b)" })
@@ -881,8 +895,8 @@ static boolean canShiftIntoInt(int a, int b) {
return Integer.numberOfLeadingZeros(a) - b > 0;
}

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

static boolean canShiftIntoLong(long a, int b) {
@@ -904,29 +918,22 @@ public RightShiftNode(RubyContext context, SourceSection sourceSection) {
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 >= Integer.SIZE - 1) {
return a < 0 ? -1 : 0;
} else {
return a >> b;
}
}

@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, int a, long b) {
if (b >= Integer.SIZE - 1) {
public int rightShift(VirtualFrame frame, int a, int b,
@Cached("createBinaryProfile()") ConditionProfile profile) {
if (profile.profile(b >= Integer.SIZE - 1)) {
return a < 0 ? -1 : 0;
} else {
return a >> b;
}
}

@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, long a, int b) {
if (b >= Long.SIZE - 1) {
return a < 0 ? -1 : 0;
public Object rightShift(VirtualFrame frame, long a, int b,
@Cached("createBinaryProfile()") ConditionProfile profile) {
if (profile.profile(b >= Long.SIZE - 1)) {
return a < 0 ? -1 : 0; // int
} else {
return a >> b;
return a >> b; // long
}
}

@@ -939,6 +946,12 @@ public Object rightShiftNeg(VirtualFrame frame, long a, int b) {
return leftShiftNode.executeLeftShift(frame, a, -b);
}

@Specialization(guards = "b >= 0")
public int rightShift(long a, long b) { // b is not in int range due to lowerFixnumParameters
assert !CoreLibrary.fitsIntoInteger(b);
return 0;
}

@Specialization(guards = { "isRubyBignum(b)", "isPositive(b)" })
public int rightShift(long a, DynamicObject b) {
return 0;
@@ -950,7 +963,6 @@ public Object rightShiftNeg(VirtualFrame frame, long a, DynamicObject b) {
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());
}

Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ private void newOpenFd(int newFd) {
}
}

@RubiniusPrimitive(name = "io_open", needsSelf = false)
@RubiniusPrimitive(name = "io_open", needsSelf = false, lowerFixnumParameters = { 1, 2 })
public static abstract class IOOpenPrimitiveNode extends RubiniusPrimitiveNode {

public IOOpenPrimitiveNode(RubyContext context, SourceSection sourceSection) {
@@ -171,11 +171,6 @@ public IOTruncatePrimitiveNode(RubyContext context, SourceSection sourceSection)
super(context, sourceSection);
}

@Specialization(guards = "isRubyString(path)")
public int truncate(DynamicObject path, int length) {
return truncate(path, (long) length);
}

@Specialization(guards = "isRubyString(path)")
public int truncate(DynamicObject path, long length) {
final int result = posix().truncate(StringOperations.getString(getContext(), path), length);
@@ -195,11 +190,6 @@ public IOFTruncatePrimitiveNode(RubyContext context, SourceSection sourceSection
super(context, sourceSection);
}

@Specialization
public int ftruncate(VirtualFrame frame, DynamicObject io, int length) {
return ftruncate(frame, io, (long) length);
}

@Specialization
public int ftruncate(VirtualFrame frame, DynamicObject io, long length) {
final int fd = Layouts.IO.getDescriptor(io);
@@ -346,7 +336,7 @@ public Object reopen(VirtualFrame frame, DynamicObject file, DynamicObject io) {

}

@RubiniusPrimitive(name = "io_reopen_path")
@RubiniusPrimitive(name = "io_reopen_path", lowerFixnumParameters = 1)
public static abstract class IOReopenPathPrimitiveNode extends RubiniusPrimitiveNode {

@Child private CallDispatchHeadNode resetBufferingNode;
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ public boolean fixedEncoding(DynamicObject regexp) {

}

@RubiniusPrimitive(name = "regexp_initialize")
@RubiniusPrimitive(name = "regexp_initialize", lowerFixnumParameters = 1)
@ImportStatic(RegexpGuards.class)
public static abstract class RegexpInitializePrimitiveNode extends RubiniusPrimitiveNode {

0 comments on commit 8e1dd9f

Please sign in to comment.