Skip to content

Commit

Permalink
[Truffle] Start to use Rubinius for core library implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Josef Haider committed Sep 30, 2014
1 parent e0ca0a4 commit c6627b9
Show file tree
Hide file tree
Showing 56 changed files with 2,562 additions and 107 deletions.
Expand Up @@ -88,4 +88,8 @@ public Object isDefined(VirtualFrame frame) {
}
}

public String getName() {
return name;
}

}
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java
Expand Up @@ -51,6 +51,10 @@ public class RubyCallNode extends RubyNode {
@Child protected BooleanCastNode respondToMissingCast;

public RubyCallNode(RubyContext context, SourceSection section, String methodName, RubyNode receiver, RubyNode block, boolean isSplatted, RubyNode... arguments) {
this(context, section, methodName, receiver, block, isSplatted, false, arguments);
}

public RubyCallNode(RubyContext context, SourceSection section, String methodName, RubyNode receiver, RubyNode block, boolean isSplatted, boolean rubiniusPrimitive, RubyNode... arguments) {
super(context, section);

this.methodName = methodName;
Expand All @@ -66,7 +70,7 @@ public RubyCallNode(RubyContext context, SourceSection section, String methodNam
this.arguments = arguments;
this.isSplatted = isSplatted;

dispatchHead = new DispatchHeadNode(context);
dispatchHead = new DispatchHeadNode(context, false, rubiniusPrimitive, Dispatch.MissingBehavior.CALL_METHOD_MISSING);
respondToMissing = new DispatchHeadNode(context, false, Dispatch.MissingBehavior.RETURN_MISSING);
respondToMissingCast = BooleanCastNodeFactory.create(context, section, null);
}
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Expand Up @@ -28,6 +28,8 @@
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.core.RubyRange;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.truffle.runtime.rubinius.RubiniusChannel;

import java.math.BigInteger;

Expand Down Expand Up @@ -189,6 +191,14 @@ public UndefinedPlaceholder executeUndefinedPlaceholder(VirtualFrame frame) thro
return RubyTypesGen.RUBYTYPES.expectUndefinedPlaceholder(execute(frame));
}

public RubiniusByteArray executeRubiniusByteArray(VirtualFrame frame) throws UnexpectedResultException {
return RubyTypesGen.RUBYTYPES.expectRubiniusByteArray(execute(frame));
}

public RubiniusChannel executeRubiniusChannel(VirtualFrame frame) throws UnexpectedResultException {
return RubyTypesGen.RUBYTYPES.expectRubiniusChannel(execute(frame));
}

public Dispatch.DispatchAction executeDispatchAction(VirtualFrame frame) {
throw new UnsupportedOperationException();
}
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/RubyTypes.java
Expand Up @@ -19,6 +19,8 @@
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.core.RubyRange;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.truffle.runtime.rubinius.RubiniusChannel;

import java.math.BigInteger;

Expand Down Expand Up @@ -63,9 +65,12 @@
RubyTime.class, //
RubyTrueClass.class, //
RubyFalseClass.class, //
RubiniusChannel.class, //
RubiniusByteArray.class, //
RubyObject.class, //
RubyBasicObject.class, //
Object[].class})

public class RubyTypes {

@ImplicitCast
Expand Down
Expand Up @@ -186,7 +186,9 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
if (methodDetails.getMethodAnnotation().isSplatted()) {
argumentsNodes.add(new ReadAllArgumentsNode(context, sourceSection));
} else {
assert arity.getMaximum() != Arity.NO_MAXIMUM;
if (arity.getMaximum() == Arity.NO_MAXIMUM) {
throw new UnsupportedOperationException("if a core method isn't splatted, you need to specify a maximum");
}

for (int n = 0; n < arity.getMaximum(); n++) {
RubyNode readArgumentNode = new ReadPreArgumentNode(context, sourceSection, n, MissingArgumentBehaviour.UNDEFINED);
Expand Down
42 changes: 41 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Expand Up @@ -957,7 +957,7 @@ public TruffelizedNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public TruffelizedNode(ThrowNode prev) {
public TruffelizedNode(TruffelizedNode prev) {
super(prev);
}

Expand All @@ -968,4 +968,44 @@ public boolean truffelized() {

}

// Rubinius API
@CoreMethod(names = "undefined", isModuleMethod = true, needsSelf = false, maxArgs = 0, visibility = Visibility.PRIVATE)
public abstract static class UndefinedNode extends CoreMethodNode {

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

public UndefinedNode(UndefinedNode prev) {
super(prev);
}

@Specialization
public UndefinedPlaceholder undefined() {
return UndefinedPlaceholder.INSTANCE;
}

}

// Rubinius API
@CoreMethod(names = "StringValue", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1)
public abstract static class StringValueNode extends CoreMethodNode {
@Child
protected DispatchHeadNode argToStringNode;

public StringValueNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
argToStringNode = new DispatchHeadNode(context);
}

public StringValueNode(StringValueNode prev) {
super(prev);
argToStringNode = prev.argToStringNode;
}

@Specialization
public RubyString StringValue(VirtualFrame frame, Object arg) {
return (RubyString) argToStringNode.call(frame, arg, "to_s", null);
}
}
}
18 changes: 18 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Expand Up @@ -21,6 +21,7 @@
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyRange;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.ByteList;
import org.jruby.util.Pack;

Expand Down Expand Up @@ -925,4 +926,21 @@ public RubyArray unpack(RubyString string, RubyString format) {
}

}

// Rubinius API
@CoreMethod(names = "data", maxArgs = 0)
public abstract static class DataNode extends CoreMethodNode {
public DataNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public DataNode(DataNode prev) {
super(prev);
}

@Specialization
public RubyObject data(RubyString string) {
return new RubiniusByteArray(getContext().getCoreLibrary().getRubiniusLibrary().getByteArrayCLass(), string.getBytes().getUnsafeBytes());
}
}
}
29 changes: 28 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/core/TimeNodes.java
Expand Up @@ -33,7 +33,7 @@ public SubNode(SubNode prev) {

@Specialization
public double sub(RubyTime a, RubyTime b) {
return RubyTime.nanosecondsToSecond(a.nanoseconds - b.nanoseconds);
return a.getSeconds() - b.getSeconds();
}

}
Expand All @@ -57,6 +57,33 @@ public RubyTime now() {

}

@CoreMethod(names = {"from_array", "time_s_from_array"}, isModuleMethod = true, needsSelf = false, maxArgs = 0)
public abstract static class FromArrayNode extends CoreMethodNode {

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

public FromArrayNode(FromArrayNode prev) {
super(prev);
}

@CompilerDirectives.SlowPath
@Specialization
public RubyTime fromArray(int second,
int minute,
int hour,
int dayOfMonth,
int month,
int year,
int nanoOfSecond,
boolean isdst,
RubyString zone) {
return RubyTime.fromArray(getContext().getCoreLibrary().getTimeClass(),second, minute, hour, dayOfMonth, month, year, nanoOfSecond, isdst, zone);
}

}

@CoreMethod(names = {"to_s", "inspect"}, maxArgs = 0)
public abstract static class ToSNode extends CoreMethodNode {

Expand Down
Expand Up @@ -20,22 +20,28 @@ public class DispatchHeadNode extends Node {

private final RubyContext context;
private final boolean ignoreVisibility;
private final boolean rubiniusPrimitive;
private final Dispatch.MissingBehavior missingBehavior;

@Child protected DispatchNode first;

public DispatchHeadNode(RubyContext context) {
this(context, false, Dispatch.MissingBehavior.CALL_METHOD_MISSING);
this(context, false, false, Dispatch.MissingBehavior.CALL_METHOD_MISSING);
}

public DispatchHeadNode(RubyContext context, Dispatch.MissingBehavior missingBehavior) {
this(context, false, missingBehavior);
this(context, false, false, missingBehavior);
}

public DispatchHeadNode(RubyContext context, boolean ignoreVisibility, Dispatch.MissingBehavior missingBehavior) {
this(context, ignoreVisibility, false, missingBehavior);
}

public DispatchHeadNode(RubyContext context, boolean ignoreVisibility, boolean rubiniusPrimitive, Dispatch.MissingBehavior missingBehavior) {
this.context = context;
this.ignoreVisibility = ignoreVisibility;
this.missingBehavior = missingBehavior;
this.rubiniusPrimitive = rubiniusPrimitive;
first = new UnresolvedDispatchNode(context, ignoreVisibility, missingBehavior);
}

Expand Down Expand Up @@ -150,6 +156,17 @@ public Object dispatch(
Object blockObject,
Object argumentsObjects,
Dispatch.DispatchAction dispatchAction) {
if (rubiniusPrimitive) {
return first.executeDispatch(
frame,
methodReceiverObject,
callingSelf,
callingSelf,
methodName,
blockObject,
RubyArguments.concatUserArguments(argumentsObjects, frame.getArguments()),
dispatchAction);
}
return first.executeDispatch(
frame,
methodReceiverObject,
Expand Down

0 comments on commit c6627b9

Please sign in to comment.