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

Commits on Jan 9, 2016

  1. Copy the full SHA
    8908183 View commit details
  2. Copy the full SHA
    cfba2a5 View commit details
5 changes: 0 additions & 5 deletions spec/truffle/tags/language/break_tags.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
slow:The break statement in a lambda created at the toplevel returns a value when invoking from a method
slow:The break statement in a lambda created at the toplevel returns a value when invoking from a block
slow:The break statement in a lambda created at the toplevel returns a value when invoking from the toplevel
fails:The break statement in a captured block when the invocation of the scope creating the block is still active raises a LocalJumpError when invoking the block from the scope creating the block
fails:The break statement in a captured block when the invocation of the scope creating the block is still active raises a LocalJumpError when invoking the block from a method
fails:The break statement in a captured block when the invocation of the scope creating the block is still active raises a LocalJumpError when yielding to the block
fails:The break statement in a captured block from a scope that has returned raises a LocalJumpError when calling the block from a method
fails:The break statement in a captured block from a scope that has returned raises a LocalJumpError when yielding to the block
Original file line number Diff line number Diff line change
@@ -9,27 +9,42 @@
*/
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.BreakException;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

public class BreakNode extends RubyNode {

private final BreakID breakID;

@Child private RubyNode child;
private final boolean ignoreMarker;

public BreakNode(RubyContext context, SourceSection sourceSection, BreakID breakID, RubyNode child) {
public BreakNode(RubyContext context, SourceSection sourceSection, BreakID breakID, RubyNode child, boolean ignoreMarker) {
super(context, sourceSection);
this.breakID = breakID;
this.child = child;
this.ignoreMarker = ignoreMarker;
}

@Override
public Object execute(VirtualFrame frame) {
if (!ignoreMarker) {
final FrameOnStackMarker marker = RubyArguments.getFrameOnStackMarker(frame.getArguments());

if (marker != null && !marker.isOnStack()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().localJumpError("break from proc-closure", this));
}
}

throw new BreakException(breakID, child.execute(frame));
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016 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
*/
package org.jruby.truffle.nodes.control;

import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.locals.WriteFrameSlotNode;
import org.jruby.truffle.nodes.locals.WriteFrameSlotNodeGen;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;

public class FrameOnStackNode extends RubyNode {

@Child private RubyNode child;
@Child private WriteFrameSlotNode writeMarker;

public FrameOnStackNode(RubyContext context, SourceSection sourceSection, RubyNode child, FrameSlot markerSlot) {
super(context, sourceSection);
this.child = child;
writeMarker = WriteFrameSlotNodeGen.create(markerSlot);
}

@Override
public Object execute(VirtualFrame frame) {
final FrameOnStackMarker marker = new FrameOnStackMarker();

writeMarker.executeWrite(frame, marker);

try {
return child.execute(frame);
} finally {
marker.setNoLongerOnStack();
}
}

}
Original file line number Diff line number Diff line change
@@ -303,7 +303,7 @@ public static DynamicObject listLocalVariables(RubyContext context, Frame frame)

while (frame != null) {
for (FrameSlot slot : frame.getFrameDescriptor().getSlots()) {
if (slot.getIdentifier() instanceof String) {
if (slot.getIdentifier() instanceof String && !((String) slot.getIdentifier()).startsWith("rubytruffle_temp_frame_on_stack_marker")) {
ArrayOperations.append(array, context.getSymbol((String) slot.getIdentifier()));
}
}
18 changes: 14 additions & 4 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ProcNodes.java
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.StringOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
@@ -52,6 +53,7 @@ public static Object[] packArguments(DynamicObject proc, Object... args) {
Layouts.PROC.getSelf(proc),
Layouts.PROC.getBlock(proc),
DeclarationContext.BLOCK,
Layouts.PROC.getFrameOnStackMarker(proc),
args);
}

@@ -61,12 +63,18 @@ public static Object rootCall(DynamicObject proc, Object... args) {
return Layouts.PROC.getCallTargetForType(proc).call(packArguments(proc, args));
}

public static DynamicObject createRubyProc(DynamicObjectFactory instanceFactory, Type type, SharedMethodInfo sharedMethodInfo, CallTarget callTargetForProcs,
CallTarget callTargetForLambdas, MaterializedFrame declarationFrame, InternalMethod method,
Object self, DynamicObject block) {
return createRubyProc(instanceFactory, type, sharedMethodInfo, callTargetForProcs, callTargetForLambdas, declarationFrame, method, self, block, null);
}

public static DynamicObject createRubyProc(DynamicObjectFactory instanceFactory, Type type, SharedMethodInfo sharedMethodInfo, CallTarget callTargetForProcs,
CallTarget callTargetForLambdas, MaterializedFrame declarationFrame, InternalMethod method,
Object self, DynamicObject block) {
Object self, DynamicObject block, FrameOnStackMarker frameOnStackMarker) {
assert block == null || RubyGuards.isRubyProc(block);
final CallTarget callTargetForType = (type == Type.PROC) ? callTargetForProcs : callTargetForLambdas;
return Layouts.PROC.createProc(instanceFactory, type, sharedMethodInfo, callTargetForType, callTargetForLambdas, declarationFrame, method, self, block);
return Layouts.PROC.createProc(instanceFactory, type, sharedMethodInfo, callTargetForType, callTargetForLambdas, declarationFrame, method, self, block, frameOnStackMarker);
}

public enum Type {
@@ -140,7 +148,8 @@ public DynamicObject procSpecial(VirtualFrame frame, DynamicObject procClass, Ob
Layouts.PROC.getDeclarationFrame(block),
Layouts.PROC.getMethod(block),
Layouts.PROC.getSelf(block),
Layouts.PROC.getBlock(block));
Layouts.PROC.getBlock(block),
Layouts.PROC.getFrameOnStackMarker(block));
initializeNode.call(frame, proc, "initialize", block, args);
return proc;
}
@@ -172,7 +181,8 @@ public DynamicObject dup(DynamicObject proc) {
Layouts.PROC.getDeclarationFrame(proc),
Layouts.PROC.getMethod(proc),
Layouts.PROC.getSelf(proc),
Layouts.PROC.getBlock(proc));
Layouts.PROC.getBlock(proc),
Layouts.PROC.getFrameOnStackMarker(proc));
return copy;
}

Original file line number Diff line number Diff line change
@@ -10,13 +10,17 @@
package org.jruby.truffle.nodes.methods;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.ProcNodes;
import org.jruby.truffle.nodes.core.ProcNodes.Type;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNode;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNodeGen;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

@@ -38,15 +42,23 @@ public class BlockDefinitionNode extends RubyNode {

private final BreakID breakID;

@Child private ReadFrameSlotNode readFrameOnStackMarkerNode;

public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, Type type, SharedMethodInfo sharedMethodInfo,
CallTarget callTargetForProcs, CallTarget callTargetForLambdas, BreakID breakID) {
CallTarget callTargetForProcs, CallTarget callTargetForLambdas, BreakID breakID, FrameSlot frameOnStackMarkerSlot) {
super(context, sourceSection);
this.type = type;
this.sharedMethodInfo = sharedMethodInfo;

this.callTargetForProcs = callTargetForProcs;
this.callTargetForLambdas = callTargetForLambdas;
this.breakID = breakID;

if (frameOnStackMarkerSlot == null) {
readFrameOnStackMarkerNode = null;
} else {
readFrameOnStackMarkerNode = ReadFrameSlotNodeGen.create(frameOnStackMarkerSlot);
}
}

public BreakID getBreakID() {
@@ -55,11 +67,26 @@ public BreakID getBreakID() {

@Override
public Object execute(VirtualFrame frame) {
final FrameOnStackMarker frameOnStackMarker;

if (readFrameOnStackMarkerNode == null) {
frameOnStackMarker = null;
} else {
final Object frameOnStackMarkerValue = readFrameOnStackMarkerNode.executeRead(frame);

if (frameOnStackMarkerValue instanceof FrameOnStackMarker) {
frameOnStackMarker = (FrameOnStackMarker) frameOnStackMarkerValue;
} else {
frameOnStackMarker = null;
}
}

return ProcNodes.createRubyProc(getContext().getCoreLibrary().getProcFactory(), type, sharedMethodInfo,
callTargetForProcs, callTargetForLambdas, frame.materialize(),
RubyArguments.getMethod(frame.getArguments()),
RubyArguments.getSelf(frame.getArguments()),
RubyArguments.getBlock(frame.getArguments()));
RubyArguments.getBlock(frame.getArguments()),
frameOnStackMarker);
}

}
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
@@ -56,7 +57,8 @@ public InternalMethod executeMethod(VirtualFrame frame) {
capturedDefaultDefinee = null;
}

return new InternalMethod(sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, null, capturedDefaultDefinee);
return new InternalMethod(sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, null,
capturedDefaultDefinee);
}

@Override
Original file line number Diff line number Diff line change
@@ -78,6 +78,7 @@ private Object[] packArguments(DynamicObject block, Object self, Object blockArg
self,
(DynamicObject) blockArgument,
declarationContext,
Layouts.PROC.getFrameOnStackMarker(block),
arguments);
}

Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.truffle.nodes.methods.DeclarationContext;
import org.jruby.truffle.nodes.methods.MarkerNode;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;
import org.jruby.truffle.runtime.methods.InternalMethod;

/**
@@ -30,9 +31,14 @@ public final class RubyArguments {
public static final int SELF_INDEX = 3;
public static final int BLOCK_INDEX = 4;
public static final int DECLARATION_CONTEXT_INDEX = 5;
public static final int RUNTIME_ARGUMENT_COUNT = 6;
public static final int FRAME_ON_STACK_MARKER_INDEX = 6;
public static final int RUNTIME_ARGUMENT_COUNT = 7;

public static Object[] pack(InternalMethod method, MaterializedFrame declarationFrame, MaterializedFrame callerFrame, Object self, DynamicObject block, DeclarationContext declarationContext, Object[] arguments) {
return pack(method, declarationFrame, callerFrame, self, block, declarationContext, null, arguments);
}

public static Object[] pack(InternalMethod method, MaterializedFrame declarationFrame, MaterializedFrame callerFrame, Object self, DynamicObject block, DeclarationContext declarationContext, FrameOnStackMarker frameOnStackMarker, Object[] arguments) {
assert method != null;
assert self != null;
assert block == null || RubyGuards.isRubyProc(block);
@@ -47,6 +53,7 @@ public static Object[] pack(InternalMethod method, MaterializedFrame declaration
packed[SELF_INDEX] = self;
packed[BLOCK_INDEX] = block;
packed[DECLARATION_CONTEXT_INDEX] = declarationContext;
packed[FRAME_ON_STACK_MARKER_INDEX] = frameOnStackMarker;
ArrayUtils.arraycopy(arguments, 0, packed, RUNTIME_ARGUMENT_COUNT, arguments.length);

return packed;
@@ -211,4 +218,8 @@ public static MaterializedFrame getDeclarationFrame(MaterializedFrame frame, int

return parentFrame;
}

public static FrameOnStackMarker getFrameOnStackMarker(Object[] arguments) {
return (FrameOnStackMarker) arguments[FRAME_ON_STACK_MARKER_INDEX];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2016 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
*/
package org.jruby.truffle.runtime.control;

public final class FrameOnStackMarker {

private boolean onStack = true;

public FrameOnStackMarker() {
}

public boolean isOnStack() {
return onStack;
}

public void setNoLongerOnStack() {
onStack = false;
}

}
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.truffle.nodes.core.ProcNodes;
import org.jruby.truffle.om.dsl.api.Layout;
import org.jruby.truffle.om.dsl.api.Nullable;
import org.jruby.truffle.runtime.control.FrameOnStackMarker;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;

@@ -42,7 +43,8 @@ DynamicObject createProc(
@Nullable MaterializedFrame declarationFrame,
@Nullable InternalMethod method,
Object self,
@Nullable DynamicObject block);
@Nullable DynamicObject block,
@Nullable FrameOnStackMarker frameOnStackMarker);

boolean isProc(ObjectType objectType);
boolean isProc(DynamicObject object);
@@ -64,4 +66,6 @@ DynamicObject createProc(

DynamicObject getBlock(DynamicObject object);

FrameOnStackMarker getFrameOnStackMarker(DynamicObject object);

}
Loading