Skip to content

Commit

Permalink
Showing 5 changed files with 35 additions and 22 deletions.
18 changes: 10 additions & 8 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.nodes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.ImportStatic;
@@ -216,19 +217,20 @@ public MemoryManager getMemoryManager() {
// ruby() helper

protected Object ruby(VirtualFrame frame, String expression, Object... arguments) {
return rubyWithSelf(RubyArguments.getSelf(frame.getArguments()), expression, arguments);
}

protected Object rubyWithSelf(Object self, String expression, Object... arguments) {
final MaterializedFrame evalFrame = setupFrame(self, arguments);
final MaterializedFrame evalFrame = setupFrame(frame, arguments);
final DynamicObject binding = Layouts.BINDING.createBinding(getContext().getCoreLibrary().getBindingFactory(), evalFrame);
return getContext().eval(expression, binding, true, "inline-ruby", this);
}

@TruffleBoundary
private MaterializedFrame setupFrame(Object self, Object... arguments) {
private MaterializedFrame setupFrame(VirtualFrame frame, Object... arguments) {
CompilerDirectives.transferToInterpreter();
final MaterializedFrame evalFrame = Truffle.getRuntime().createMaterializedFrame(
RubyArguments.pack(null, null, self, null, new Object[]{}));
RubyArguments.pack(
RubyArguments.getMethod(frame.getArguments()),
null,
RubyArguments.getSelf(frame.getArguments()),
null,
new Object[] {}));

if (arguments.length % 2 == 1) {
throw new UnsupportedOperationException("odd number of name-value pairs for arguments");
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Cached;
@@ -18,15 +19,18 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.arguments.CheckArityNode;
import org.jruby.truffle.nodes.control.SequenceNode;
import org.jruby.truffle.nodes.methods.SymbolProcNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.SymbolCodeRangeableWrapper;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.util.StringSupport;

@@ -118,19 +122,19 @@ public ToProcNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization(guards = "cachedSymbol == symbol", limit = "getCacheLimit()")
public DynamicObject toProcCached(DynamicObject symbol,
public DynamicObject toProcCached(VirtualFrame frame, DynamicObject symbol,
@Cached("symbol") DynamicObject cachedSymbol,
@Cached("createProc(symbol)") DynamicObject cachedProc) {
@Cached("createProc(frame, symbol)") DynamicObject cachedProc) {
return cachedProc;
}

@TruffleBoundary
@Specialization
public DynamicObject toProcUncached(DynamicObject symbol) {
return createProc(symbol);
public DynamicObject toProcUncached(VirtualFrame frame, DynamicObject symbol) {
return createProc(frame, symbol);
}

protected DynamicObject createProc(DynamicObject symbol) {
protected DynamicObject createProc(VirtualFrame frame, DynamicObject symbol) {
CompilerDirectives.transferToInterpreter();
final SourceSection sourceSection = RubyCallStack.getCallerFrame(getContext())
.getCallNode().getEncapsulatingSourceSection();

@@ -147,13 +151,14 @@ protected DynamicObject createProc(DynamicObject symbol) {
new SymbolProcNode(getContext(), sourceSection, Layouts.SYMBOL.getString(symbol))));

final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final InternalMethod method = RubyArguments.getMethod(frame.getArguments());

return ProcNodes.createRubyProc(
getContext().getCoreLibrary().getProcFactory(),
ProcNodes.Type.PROC,
sharedMethodInfo,
callTarget, callTarget, null,
null, getContext().getCoreLibrary().getNilObject(),
method, getContext().getCoreLibrary().getNilObject(),
null);
}

Original file line number Diff line number Diff line change
@@ -2250,12 +2250,14 @@ public Object max(VirtualFrame frame, DynamicObject array) {

final Memo<Object> maximum = new Memo<>();

final VirtualFrame maximumClosureFrame = Truffle.getRuntime().createVirtualFrame(RubyArguments.pack(null, null, array, null, new Object[] {}), maxBlock.getFrameDescriptor());
final InternalMethod method = RubyArguments.getMethod(frame.getArguments());
final VirtualFrame maximumClosureFrame = Truffle.getRuntime().createVirtualFrame(
RubyArguments.pack(method, null, array, null, new Object[] {}), maxBlock.getFrameDescriptor());
maximumClosureFrame.setObject(maxBlock.getFrameSlot(), maximum);

final DynamicObject block = ProcNodes.createRubyProc(getContext().getCoreLibrary().getProcFactory(), ProcNodes.Type.PROC,
maxBlock.getSharedMethodInfo(), maxBlock.getCallTarget(), maxBlock.getCallTarget(),
maximumClosureFrame.materialize(), null, array, null);
maximumClosureFrame.materialize(), method, array, null);

eachNode.call(frame, array, "each", block);

@@ -2352,12 +2354,14 @@ public Object min(VirtualFrame frame, DynamicObject array) {

final Memo<Object> minimum = new Memo<>();

final VirtualFrame minimumClosureFrame = Truffle.getRuntime().createVirtualFrame(RubyArguments.pack(null, null, array, null, new Object[] {}), minBlock.getFrameDescriptor());
final InternalMethod method = RubyArguments.getMethod(frame.getArguments());
final VirtualFrame minimumClosureFrame = Truffle.getRuntime().createVirtualFrame(
RubyArguments.pack(method, null, array, null, new Object[] {}), minBlock.getFrameDescriptor());
minimumClosureFrame.setObject(minBlock.getFrameSlot(), minimum);

final DynamicObject block = ProcNodes.createRubyProc(getContext().getCoreLibrary().getProcFactory(), ProcNodes.Type.PROC,
minBlock.getSharedMethodInfo(), minBlock.getCallTarget(), minBlock.getCallTarget(),
minimumClosureFrame.materialize(), null, array, null);
minimumClosureFrame.materialize(), method, array, null);

eachNode.call(frame, array, "each", block);

Original file line number Diff line number Diff line change
@@ -256,9 +256,8 @@ public IOReadIfAvailableNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public Object readIfAvailable(DynamicObject file, int numberOfBytes) {
public Object readIfAvailable(VirtualFrame frame, DynamicObject file, int numberOfBytes) {
// Taken from Rubinius's IO::read_if_available.

if (numberOfBytes == 0) {
@@ -281,7 +280,7 @@ public Object readIfAvailable(DynamicObject file, int numberOfBytes) {

if (res == 0) {
CompilerDirectives.transferToInterpreter();
rubyWithSelf(file, "raise IO::EAGAINWaitReadable");
ruby(frame, "raise IO::EAGAINWaitReadable");
}

if (res < 0) {
Original file line number Diff line number Diff line change
@@ -30,7 +30,10 @@ public final class RubyArguments {
public static final int RUNTIME_ARGUMENT_COUNT = 4;

public static Object[] pack(InternalMethod method, MaterializedFrame declarationFrame, Object self, DynamicObject block, Object[] arguments) {
assert method != null;
assert self != null;
assert block == null || RubyGuards.isRubyProc(block);
assert arguments != null;

final Object[] packed = new Object[arguments.length + RUNTIME_ARGUMENT_COUNT];

0 comments on commit bb747c7

Please sign in to comment.