Skip to content

Commit 7a21fc4

Browse files
committed
Merge branch 'master' into truffle-head
2 parents 42d8c43 + b083103 commit 7a21fc4

25 files changed

+333
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ target
6666
test/prawn
6767
test/rails
6868
test/testapp/testapp
69+
test/truffle/*.methods
6970
tool/nailgun/Makefile
7071
tool/nailgun/config.log
7172
tool/nailgun/config.status

core/src/main/java/org/jruby/RubyIO.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,6 +3446,10 @@ public static IRubyObject ioOpen(ThreadContext context, IRubyObject filename, IR
34463446
int perm;
34473447
IRubyObject cmd;
34483448

3449+
if ((filename instanceof RubyString) && ((RubyString) filename).isEmpty()) {
3450+
throw context.getRuntime().newErrnoENOENTError();
3451+
}
3452+
34493453
Object pm = EncodingUtils.vmodeVperm(vmode, vperm);
34503454

34513455
IOEncodable convconfig = new IOEncodable.ConvConfig();

core/src/main/java/org/jruby/RubyThread.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,12 @@ public <Data, Return> Return executeTask(ThreadContext context, Data data, Task<
12581258
try {
12591259
this.unblockFunc = task;
12601260
this.unblockArg = data;
1261+
12611262
enterSleep();
1263+
1264+
// check for interrupt before going into blocking call
1265+
context.pollThreadEvents();
1266+
12621267
return task.run(context, data);
12631268
} finally {
12641269
exitSleep();

core/src/main/java/org/jruby/truffle/nodes/cast/BooleanCastNode.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,16 @@ public boolean doLongFixnum(long value) {
5252
return true;
5353
}
5454

55-
@Specialization
56-
public boolean doBignum(RubyBignum value) {
57-
return true;
58-
}
59-
6055
@Specialization
6156
public boolean doFloat(double value) {
6257
return true;
6358
}
6459

65-
@Specialization(guards = "neitherNilNorFalse")
60+
@Specialization(guards = "!isNil")
6661
public boolean doBasicObject(RubyBasicObject object) {
6762
return true;
6863
}
6964

70-
protected boolean neitherNilNorFalse(RubyBasicObject object) {
71-
return object != getContext().getCoreLibrary().getNilObject();
72-
}
73-
7465
@Override
7566
public abstract boolean executeBoolean(VirtualFrame frame);
7667

core/src/main/java/org/jruby/truffle/nodes/core/BasicObjectNodes.java

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
import java.util.*;
1313

1414
import com.oracle.truffle.api.CompilerDirectives;
15+
import com.oracle.truffle.api.ExactMath;
1516
import com.oracle.truffle.api.source.*;
1617
import com.oracle.truffle.api.dsl.*;
1718
import com.oracle.truffle.api.frame.VirtualFrame;
1819
import org.jruby.runtime.Visibility;
20+
import org.jruby.truffle.nodes.RubyNode;
21+
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
1922
import org.jruby.truffle.nodes.dispatch.Dispatch;
2023
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
2124
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
@@ -38,9 +41,15 @@ public NotNode(NotNode prev) {
3841
super(prev);
3942
}
4043

44+
@CreateCast("arguments") public RubyNode[] createCast(RubyNode[] arguments) {
45+
return new RubyNode[] {
46+
BooleanCastNodeFactory.create(getContext(), getSourceSection(), arguments[0])
47+
};
48+
}
49+
4150
@Specialization
42-
public boolean not(Object value) {
43-
return !getContext().getCoreLibrary().isTruthy(value);
51+
public boolean not(boolean value) {
52+
return !value;
4453
}
4554

4655
}
@@ -95,25 +104,48 @@ public int objectIDFalse(boolean value) {
95104

96105
@Specialization
97106
public long objectID(int value) {
98-
return ObjectIDOperations.fixnumToID(value);
107+
return ObjectIDOperations.smallFixnumToID(value);
108+
}
109+
110+
@Specialization(rewriteOn = ArithmeticException.class)
111+
public long objectIDSmallFixnumOverflow(long value) {
112+
return ObjectIDOperations.smallFixnumToIDOverflow(value);
113+
}
114+
115+
/* TODO: Ideally we would have this instead of the code below to speculate better. [GRAAL-903]
116+
@Specialization(guards = "isSmallFixnum")
117+
public long objectIDSmallFixnum(long value) {
118+
return ObjectIDOperations.smallFixnumToID(value);
99119
}
100120
121+
@Specialization(guards = "!isSmallFixnum")
122+
public Object objectIDLargeFixnum(long value) {
123+
return ObjectIDOperations.largeFixnumToID(getContext(), value);
124+
} */
125+
101126
@Specialization
102-
public long objectID(long value) {
103-
return ObjectIDOperations.fixnumToID(value);
127+
public Object objectID(long value) {
128+
if (isSmallFixnum(value)) {
129+
return ObjectIDOperations.smallFixnumToID(value);
130+
} else {
131+
return ObjectIDOperations.largeFixnumToID(getContext(), value);
132+
}
104133
}
105134

106135
@Specialization
107-
public long objectID(double value) {
108-
CompilerDirectives.transferToInterpreter();
109-
throw new UnsupportedOperationException("No ID for Float yet");
136+
public RubyBignum objectID(double value) {
137+
return ObjectIDOperations.floatToID(getContext(), value);
110138
}
111139

112140
@Specialization
113141
public long objectID(RubyBasicObject object) {
114142
return object.getObjectID();
115143
}
116144

145+
protected boolean isSmallFixnum(long fixnum) {
146+
return ObjectIDOperations.isSmallFixnum(fixnum);
147+
}
148+
117149
}
118150

119151
@CoreMethod(names = {"equal?", "=="}, required = 1)
@@ -127,8 +159,7 @@ public ReferenceEqualNode(ReferenceEqualNode prev) {
127159
super(prev);
128160
}
129161

130-
// The @CreateCast is not applied when using this, so the caller needs to unbox itself.
131-
protected abstract boolean executeEqualWithUnboxed(VirtualFrame frame, Object a, Object b);
162+
protected abstract boolean executeReferenceEqual(VirtualFrame frame, Object a, Object b);
132163

133164
@Specialization public boolean equal(boolean a, boolean b) { return a == b; }
134165
@Specialization public boolean equal(int a, int b) { return a == b; }

core/src/main/java/org/jruby/truffle/nodes/core/FloatNodes.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.oracle.truffle.api.dsl.*;
1717
import com.oracle.truffle.api.utilities.BranchProfile;
1818
import org.jruby.truffle.runtime.*;
19+
import org.jruby.truffle.runtime.control.RaiseException;
1920
import org.jruby.truffle.runtime.core.*;
2021
import org.jruby.truffle.runtime.core.RubyArray;
2122

@@ -301,6 +302,15 @@ public boolean less(double a, double b) {
301302
public boolean less(double a, RubyBignum b) {
302303
return a < b.doubleValue();
303304
}
305+
306+
@Specialization(guards = "!isBignum(arguments[1])")
307+
public boolean less(@SuppressWarnings("unused") double a, RubyBasicObject other) {
308+
throw new RaiseException(new RubyException(
309+
getContext().getCoreLibrary().getArgumentErrorClass(),
310+
getContext().makeString(String.format("comparison of Float with %s failed", other.getLogicalClass().getName())),
311+
RubyCallStack.getBacktrace(this)
312+
));
313+
}
304314
}
305315

306316
@CoreMethod(names = "<=", required = 1)
@@ -333,6 +343,15 @@ public boolean lessEqual(double a, double b) {
333343
public boolean lessEqual(double a, RubyBignum b) {
334344
return a <= b.doubleValue();
335345
}
346+
347+
@Specialization(guards = "!isBignum(arguments[1])")
348+
public boolean less(@SuppressWarnings("unused") double a, RubyBasicObject other) {
349+
throw new RaiseException(new RubyException(
350+
getContext().getCoreLibrary().getArgumentErrorClass(),
351+
getContext().makeString(String.format("comparison of Float with %s failed", other.getLogicalClass().getName())),
352+
RubyCallStack.getBacktrace(this)
353+
));
354+
}
336355
}
337356

338357
@CoreMethod(names = "==", required = 1)
@@ -365,6 +384,12 @@ public boolean equal(double a, double b) {
365384
public boolean equal(double a, RubyBignum b) {
366385
return a == b.doubleValue();
367386
}
387+
388+
@Specialization(guards = "!isBignum(arguments[1])")
389+
public boolean less(@SuppressWarnings("unused") double a, RubyBasicObject other) {
390+
// TODO (nirvdrum Dec. 1, 2014): This is a stub. There is one case where this should return 'true', but it's not a trivial fix.
391+
return false;
392+
}
368393
}
369394

370395
@CoreMethod(names = "<=>", required = 1)
@@ -414,6 +439,15 @@ public boolean greaterEqual(double a, double b) {
414439
public boolean greaterEqual(double a, RubyBignum b) {
415440
return a >= b.doubleValue();
416441
}
442+
443+
@Specialization(guards = "!isBignum(arguments[1])")
444+
public boolean less(@SuppressWarnings("unused") double a, RubyBasicObject other) {
445+
throw new RaiseException(new RubyException(
446+
getContext().getCoreLibrary().getArgumentErrorClass(),
447+
getContext().makeString(String.format("comparison of Float with %s failed", other.getLogicalClass().getName())),
448+
RubyCallStack.getBacktrace(this)
449+
));
450+
}
417451
}
418452

419453
@CoreMethod(names = ">", required = 1)
@@ -446,6 +480,15 @@ public boolean equal(double a, double b) {
446480
public boolean equal(double a, RubyBignum b) {
447481
return a > b.doubleValue();
448482
}
483+
484+
@Specialization(guards = "!isBignum(arguments[1])")
485+
public boolean less(@SuppressWarnings("unused") double a, RubyBasicObject other) {
486+
throw new RaiseException(new RubyException(
487+
getContext().getCoreLibrary().getArgumentErrorClass(),
488+
getContext().makeString(String.format("comparison of Float with %s failed", other.getLogicalClass().getName())),
489+
RubyCallStack.getBacktrace(this)
490+
));
491+
}
449492
}
450493

451494
@CoreMethod(names = "abs")

core/src/main/java/org/jruby/truffle/nodes/core/HashNodes.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.oracle.truffle.api.frame.*;
1919
import com.oracle.truffle.api.utilities.BranchProfile;
2020
import org.jruby.runtime.Visibility;
21+
import org.jruby.truffle.nodes.RubyNode;
2122
import org.jruby.truffle.nodes.RubyRootNode;
2223
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
2324
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
@@ -1004,6 +1005,42 @@ public RubyHash mergeObjectArrayObjectArray(VirtualFrame frame, RubyHash hash, R
10041005

10051006
}
10061007

1008+
@CoreMethod(names = "default", optional = 1)
1009+
public abstract static class DefaultNode extends HashCoreMethodNode {
1010+
1011+
public DefaultNode(RubyContext context, SourceSection sourceSection) {
1012+
super(context, sourceSection);
1013+
}
1014+
1015+
public DefaultNode(DefaultNode prev) {
1016+
super(prev);
1017+
}
1018+
1019+
@Specialization
1020+
public Object defaultElement(VirtualFrame frame, RubyHash hash, UndefinedPlaceholder undefined) {
1021+
Object ret = hash.getDefaultValue();
1022+
1023+
// TODO (nirvdrum Dec. 1, 2014): This needs to evaluate the defaultProc if it exists before it tries defaultValue.
1024+
if (ret != null) {
1025+
return ret;
1026+
} else {
1027+
return getContext().getCoreLibrary().getNilObject();
1028+
}
1029+
}
1030+
1031+
@Specialization
1032+
public Object defaultElement(VirtualFrame frame, RubyHash hash, Object key) {
1033+
Object ret = hash.getDefaultValue();
1034+
1035+
// TODO (nirvdrum Dec. 1, 2014): This really needs to do something with the key. Dummy stub for now.
1036+
if (ret != null) {
1037+
return ret;
1038+
} else {
1039+
return getContext().getCoreLibrary().getNilObject();
1040+
}
1041+
}
1042+
}
1043+
10071044
@CoreMethod(names = "size")
10081045
public abstract static class SizeNode extends HashCoreMethodNode {
10091046

core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected boolean areSame(VirtualFrame frame, Object left, Object right) {
6565
CompilerDirectives.transferToInterpreterAndInvalidate();
6666
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null}));
6767
}
68-
return referenceEqualNode.executeEqualWithUnboxed(frame, left, right);
68+
return referenceEqualNode.executeReferenceEqual(frame, left, right);
6969
}
7070

7171
protected boolean areEqual(VirtualFrame frame, Object left, Object right) {
@@ -377,6 +377,11 @@ public RubyClass getClass(@SuppressWarnings("unused") int value) {
377377
return getContext().getCoreLibrary().getFixnumClass();
378378
}
379379

380+
@Specialization
381+
public RubyClass getClass(@SuppressWarnings("unused") long value) {
382+
return getContext().getCoreLibrary().getFixnumClass();
383+
}
384+
380385
@Specialization
381386
public RubyClass getClass(@SuppressWarnings("unused") RubyBignum value) {
382387
return getContext().getCoreLibrary().getBignumClass();

core/src/main/java/org/jruby/truffle/nodes/core/NilClassNodes.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.oracle.truffle.api.source.*;
1313
import com.oracle.truffle.api.dsl.*;
1414
import org.jruby.truffle.runtime.*;
15+
import org.jruby.truffle.runtime.control.RaiseException;
1516
import org.jruby.truffle.runtime.core.*;
1617

1718
@CoreClass(name = "NilClass")
@@ -85,6 +86,23 @@ public int toI() {
8586
}
8687
}
8788

89+
@CoreMethod(names = "to_f", needsSelf = false)
90+
public abstract static class ToFNode extends CoreMethodNode {
91+
92+
public ToFNode(RubyContext context, SourceSection sourceSection) {
93+
super(context, sourceSection);
94+
}
95+
96+
public ToFNode(ToINode prev) {
97+
super(prev);
98+
}
99+
100+
@Specialization
101+
public double toF() {
102+
return 0.0f;
103+
}
104+
}
105+
88106
@CoreMethod(names = "to_s", needsSelf = false)
89107
public abstract static class ToSNode extends CoreMethodNode {
90108

@@ -102,6 +120,40 @@ public RubyString toS() {
102120
}
103121
}
104122

123+
@CoreMethod(names = "to_h", needsSelf = false)
124+
public abstract static class ToHNode extends CoreMethodNode {
125+
126+
public ToHNode(RubyContext context, SourceSection sourceSection) {
127+
super(context, sourceSection);
128+
}
129+
130+
public ToHNode(ToHNode prev) {
131+
super(prev);
132+
}
133+
134+
@Specialization
135+
public RubyHash toH() {
136+
return new RubyHash(getContext().getCoreLibrary().getHashClass(), null, getContext().getCoreLibrary().getNilObject(), null, 0);
137+
}
138+
}
139+
140+
@CoreMethod(names = "dup", needsSelf = false)
141+
public abstract static class DupNode extends CoreMethodNode {
142+
143+
public DupNode(RubyContext context, SourceSection sourceSection) {
144+
super(context, sourceSection);
145+
}
146+
147+
public DupNode(DupNode prev) {
148+
super(prev);
149+
}
150+
151+
@Specialization
152+
public RubyString dup() {
153+
throw new RaiseException(getContext().getCoreLibrary().typeError("can't dup NilClass", this));
154+
}
155+
}
156+
105157
@CoreMethod(names = "&", needsSelf = false, required = 1)
106158
public abstract static class AndNode extends CoreMethodNode {
107159

0 commit comments

Comments
 (0)