Skip to content

Commit

Permalink
[Truffle] Fix most of break.
Browse files Browse the repository at this point in the history
* Breaks out of the call site.
* Relax the type of the ForNode child.
* Fix #2826, #2675.
  • Loading branch information
eregon committed Apr 20, 2015
1 parent d8bb622 commit 434c8a2
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 117 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/language/break_tags.txt
Expand Up @@ -3,7 +3,6 @@ fails:The break statement in a captured block when the invocation of the scope c
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
fails:Executing break from within a block returns from the original invoking method even in case of chained calls
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
Expand Down
4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/nodes/ForNode.java
Expand Up @@ -15,9 +15,9 @@

public class ForNode extends RubyNode {

@Child private RubyCallNode callNode;
@Child private RubyNode callNode;

public ForNode(RubyContext context, SourceSection sourceSection, RubyCallNode callNode) {
public ForNode(RubyContext context, SourceSection sourceSection, RubyNode callNode) {
super(context, sourceSection);
this.callNode = callNode;
}
Expand Down
Expand Up @@ -11,22 +11,29 @@

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.core.RubyProc;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;

public class BreakNode extends RubyNode {

private final BlockID blockID;

@Child private RubyNode child;

public BreakNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
public BreakNode(RubyContext context, SourceSection sourceSection, BlockID blockID, RubyNode child) {
super(context, sourceSection);
this.blockID = blockID;
this.child = child;
}

@Override
public Object execute(VirtualFrame frame) {
throw new BreakException(child.execute(frame));
throw new BreakException(blockID, child.execute(frame));
}

}
61 changes: 6 additions & 55 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Expand Up @@ -1337,9 +1337,6 @@ public Object eachIntegerFixnum(VirtualFrame frame, RubyArray array, RubyProc bl
try {
yield(frame, block, store[n]);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1374,9 +1371,6 @@ public Object eachLongFixnum(VirtualFrame frame, RubyArray array, RubyProc block
try {
yield(frame, block, store[n]);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1411,9 +1405,6 @@ public Object eachFloat(VirtualFrame frame, RubyArray array, RubyProc block) {
try {
yield(frame, block, store[n]);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1448,9 +1439,6 @@ public Object eachObject(VirtualFrame frame, RubyArray array, RubyProc block) {
try {
yield(frame, block, store[n]);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1508,9 +1496,6 @@ public Object eachWithIndexInt(VirtualFrame frame, RubyArray array, RubyProc blo
try {
yield(frame, block, store[n], n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1545,9 +1530,6 @@ public Object eachWithIndexLong(VirtualFrame frame, RubyArray array, RubyProc bl
try {
yield(frame, block, store[n], n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1582,9 +1564,6 @@ public Object eachWithIndexDouble(VirtualFrame frame, RubyArray array, RubyProc
try {
yield(frame, block, store[n], n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1619,9 +1598,6 @@ public Object eachWithIndexObject(VirtualFrame frame, RubyArray array, RubyProc
try {
yield(frame, block, store[n], n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -1743,8 +1719,6 @@ public abstract static class InitializeNode extends YieldingCoreMethodNode {
@Child private KernelNodes.RespondToNode respondToToAryNode;
@Child private ArrayBuilderNode arrayBuilder;

private final BranchProfile breakProfile = BranchProfile.create();

public InitializeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
arrayBuilder = new ArrayBuilderNode.UninitializedArrayBuilderNode(context);
Expand Down Expand Up @@ -1918,29 +1892,24 @@ public Object initialize(VirtualFrame frame, RubyArray array, int size, Undefine
Object store = arrayBuilder.start();

int count = 0;
int n = 0;
try {
for (int n = 0; n < size; n++) {
for (; n < size; n++) {
if (CompilerDirectives.inInterpreter()) {
count++;
}

try {
arrayBuilder.ensure(store, n + 1);
store = arrayBuilder.append(store, n, yield(frame, block, n));
} catch (BreakException e) {
breakProfile.enter();
array.setStore(arrayBuilder.finish(store, n), n);
return e.getResult();
}

arrayBuilder.ensure(store, n + 1);
store = arrayBuilder.append(store, n, yield(frame, block, n));
}
} finally {
if (CompilerDirectives.inInterpreter()) {
getRootNode().reportLoopCount(count);
}

array.setStore(arrayBuilder.finish(store, n), n);
}

array.setStore(arrayBuilder.finish(store, size), size);
return array;
}

Expand Down Expand Up @@ -2309,9 +2278,6 @@ public Object mapIntegerFixnum(VirtualFrame frame, RubyArray array, RubyProc blo
try {
mappedStore = arrayBuilder.append(mappedStore, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -2347,9 +2313,6 @@ public Object mapLongFixnum(VirtualFrame frame, RubyArray array, RubyProc block)
try {
mappedStore = arrayBuilder.append(mappedStore, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -2385,9 +2348,6 @@ public Object mapFloat(VirtualFrame frame, RubyArray array, RubyProc block) {
try {
mappedStore = arrayBuilder.append(mappedStore, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -2423,9 +2383,6 @@ public Object mapObject(VirtualFrame frame, RubyArray array, RubyProc block) {
try {
mappedStore = arrayBuilder.append(mappedStore, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -2490,9 +2447,6 @@ public Object mapInPlaceFixnumInteger(VirtualFrame frame, RubyArray array, RubyP
try {
writeNode.executeWrite(frame, array, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -2533,9 +2487,6 @@ public Object mapInPlaceObject(VirtualFrame frame, RubyArray array, RubyProc blo
try {
writeNode.executeWrite(frame, array, n, yield(frame, block, store[n]));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down
Expand Up @@ -60,9 +60,6 @@ public Object downto(VirtualFrame frame, int from, int to, RubyProc block) {
try {
yield(frame, block, i);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -133,9 +130,6 @@ public Object times(VirtualFrame frame, int n, RubyProc block) {
try {
yield(frame, block, i);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -167,9 +161,6 @@ public Object times(VirtualFrame frame, long n, RubyProc block) {
try {
yield(frame, block, i);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -201,9 +192,6 @@ public Object times(VirtualFrame frame, RubyBignum n, RubyProc block) {
try {
yield(frame, block, fixnumOrBignum.fixnumOrBignum(i));
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -276,9 +264,6 @@ public Object upto(VirtualFrame frame, int from, int to, RubyProc block) {
try {
yield(frame, block, i);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -319,9 +304,6 @@ public Object upto(VirtualFrame frame, long from, long to, RubyProc block) {
try {
yield(frame, block, i);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down
12 changes: 0 additions & 12 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/RangeNodes.java
Expand Up @@ -109,9 +109,6 @@ public Object each(VirtualFrame frame, RubyRange.IntegerFixnumRange range, RubyP
try {
yield(frame, block, n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -146,9 +143,6 @@ public Object each(VirtualFrame frame, RubyRange.LongFixnumRange range, RubyProc
try {
yield(frame, block, n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -311,9 +305,6 @@ public Object step(VirtualFrame frame, RubyRange.IntegerFixnumRange range, int s
try {
yield(frame, block, n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down Expand Up @@ -346,9 +337,6 @@ public Object step(VirtualFrame frame, RubyRange.LongFixnumRange range, int step
try {
yield(frame, block, n);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
Expand Down
Expand Up @@ -13,12 +13,14 @@
import com.oracle.truffle.api.frame.MaterializedFrame;
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.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;

/**
* Create a RubyProc to pass as a block to the called method.
Expand All @@ -37,10 +39,11 @@ public class BlockDefinitionNode extends RubyNode {
private final CallTarget callTargetForMethods;

private final boolean requiresDeclarationFrame;
private final BlockID blockID;

public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, SharedMethodInfo sharedMethodInfo,
boolean requiresDeclarationFrame, CallTarget callTargetForBlocks,
CallTarget callTargetForProcs, CallTarget callTargetForMethods) {
CallTarget callTargetForProcs, CallTarget callTargetForMethods, BlockID blockID) {
super(context, sourceSection);
this.sharedMethodInfo = sharedMethodInfo;

Expand All @@ -49,7 +52,11 @@ public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, Sha
this.callTargetForMethods = callTargetForMethods;

this.requiresDeclarationFrame = requiresDeclarationFrame;
this.blockID = blockID;
}

public BlockID getBlockID() {
return blockID;
}

@Override
Expand Down

0 comments on commit 434c8a2

Please sign in to comment.