Skip to content

Commit d30fd94

Browse files
committed
WhileNode is converted to DSL node
1 parent 9225568 commit d30fd94

File tree

3 files changed

+50
-30
lines changed

3 files changed

+50
-30
lines changed

src/main/java/org/truffleruby/language/control/WhileNode.java

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
package org.truffleruby.language.control;
1111

1212
import com.oracle.truffle.api.TruffleSafepoint;
13+
import com.oracle.truffle.api.dsl.Cached;
14+
import com.oracle.truffle.api.dsl.Specialization;
15+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
1316
import org.truffleruby.RubyLanguage;
1417
import org.truffleruby.core.cast.BooleanCastNode;
15-
import org.truffleruby.core.cast.BooleanCastNodeGen;
1618
import org.truffleruby.language.RubyBaseNode;
1719
import org.truffleruby.language.RubyContextSourceNode;
1820
import org.truffleruby.language.RubyNode;
@@ -21,7 +23,6 @@
2123
import com.oracle.truffle.api.frame.VirtualFrame;
2224
import com.oracle.truffle.api.nodes.LoopNode;
2325
import com.oracle.truffle.api.nodes.RepeatingNode;
24-
import com.oracle.truffle.api.profiles.BranchProfile;
2526

2627
public final class WhileNode extends RubyContextSourceNode {
2728

@@ -45,17 +46,30 @@ public RubyNode cloneUninitialized() {
4546

4647
private abstract static class WhileRepeatingBaseNode extends RubyBaseNode implements RepeatingNode {
4748

48-
@Child protected BooleanCastNode condition;
49+
@Child protected RubyNode condition;
4950
@Child protected RubyNode body;
5051

51-
protected final BranchProfile redoUsed = BranchProfile.create();
52-
protected final BranchProfile nextUsed = BranchProfile.create();
53-
5452
public WhileRepeatingBaseNode(RubyNode condition, RubyNode body) {
55-
this.condition = BooleanCastNodeGen.create(condition);
53+
this.condition = condition;
5654
this.body = body;
5755
}
5856

57+
protected abstract boolean execute(VirtualFrame frame);
58+
59+
@Override
60+
public final boolean executeRepeating(VirtualFrame frame) {
61+
return execute(frame);
62+
}
63+
64+
@Override
65+
public final Object executeRepeatingWithValue(VirtualFrame frame) {
66+
if (executeRepeating(frame)) {
67+
return CONTINUE_LOOP_STATUS;
68+
} else {
69+
return BREAK_LOOP_STATUS;
70+
}
71+
}
72+
5973
@Override
6074
public String toString() {
6175
return "while loop at " + RubyLanguage.filenameLine(getEncapsulatingSourceSection());
@@ -64,15 +78,19 @@ public String toString() {
6478
public abstract WhileRepeatingBaseNode cloneUninitialized();
6579
}
6680

67-
public static class WhileRepeatingNode extends WhileRepeatingBaseNode implements RepeatingNode {
81+
public abstract static class WhileRepeatingNode extends WhileRepeatingBaseNode {
6882

6983
public WhileRepeatingNode(RubyNode condition, RubyNode body) {
7084
super(condition, body);
7185
}
7286

73-
@Override
74-
public boolean executeRepeating(VirtualFrame frame) {
75-
if (!condition.execute(frame)) {
87+
@Specialization
88+
protected boolean doRepeating(VirtualFrame frame,
89+
@Cached BooleanCastNode booleanCastNode,
90+
@Cached InlinedBranchProfile redoUsed,
91+
@Cached InlinedBranchProfile nextUsed) {
92+
var conditionAsBoolean = booleanCastNode.execute(condition.execute(frame));
93+
if (!conditionAsBoolean) {
7694
return false;
7795
}
7896

@@ -81,54 +99,53 @@ public boolean executeRepeating(VirtualFrame frame) {
8199
body.doExecuteVoid(frame);
82100
return true;
83101
} catch (NextException e) {
84-
nextUsed.enter();
102+
nextUsed.enter(this);
85103
return true;
86104
} catch (RedoException e) {
87105
// Just continue in the while(true) loop.
88-
redoUsed.enter();
106+
redoUsed.enter(this);
89107
TruffleSafepoint.poll(this);
90108
}
91109
}
92110
}
93111

94112
@Override
95113
public WhileRepeatingBaseNode cloneUninitialized() {
96-
return new WhileRepeatingNode(
97-
condition.getValueNode().cloneUninitialized(),
114+
return WhileNodeFactory.WhileRepeatingNodeGen.create(
115+
condition.cloneUninitialized(),
98116
body.cloneUninitialized());
99117
}
100118

101119
}
102120

103-
public static class DoWhileRepeatingNode extends WhileRepeatingBaseNode implements RepeatingNode {
121+
public abstract static class DoWhileRepeatingNode extends WhileRepeatingBaseNode {
104122

105123
public DoWhileRepeatingNode(RubyNode condition, RubyNode body) {
106124
super(condition, body);
107125
}
108126

109-
@Override
110-
public boolean executeRepeating(VirtualFrame frame) {
127+
@Specialization
128+
protected boolean doRepeating(VirtualFrame frame,
129+
@Cached BooleanCastNode booleanCastNode,
130+
@Cached InlinedBranchProfile redoUsed,
131+
@Cached InlinedBranchProfile nextUsed) {
111132
try {
112133
body.doExecuteVoid(frame);
113134
} catch (NextException e) {
114-
nextUsed.enter();
135+
nextUsed.enter(this);
115136
} catch (RedoException e) {
116137
// Just continue to next iteration without executing the condition.
117-
redoUsed.enter();
138+
redoUsed.enter(this);
118139
return true;
119140
}
120141

121-
return condition.execute(frame);
122-
}
123-
124-
private RubyNode getConditionBeforeCasting() {
125-
return condition.getValueNode();
142+
return booleanCastNode.execute(condition.execute(frame));
126143
}
127144

128145
@Override
129146
public WhileRepeatingBaseNode cloneUninitialized() {
130-
return new DoWhileRepeatingNode(
131-
getConditionBeforeCasting().cloneUninitialized(),
147+
return WhileNodeFactory.DoWhileRepeatingNodeGen.create(
148+
condition.cloneUninitialized(),
132149
body.cloneUninitialized());
133150
}
134151

src/main/java/org/truffleruby/parser/BodyTranslator.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import org.truffleruby.language.control.ReturnID;
9292
import org.truffleruby.language.control.UnlessNodeGen;
9393
import org.truffleruby.language.control.WhileNode;
94+
import org.truffleruby.language.control.WhileNodeFactory;
9495
import org.truffleruby.language.defined.DefinedNode;
9596
import org.truffleruby.language.defined.DefinedWrapperNode;
9697
import org.truffleruby.language.dispatch.RubyCallNodeParameters;
@@ -2912,9 +2913,9 @@ private RubyNode translateWhileNode(WhileParseNode node, boolean conditionInvers
29122913
final RubyNode loop;
29132914

29142915
if (node.evaluateAtStart()) {
2915-
loop = new WhileNode(new WhileNode.WhileRepeatingNode(condition, body));
2916+
loop = new WhileNode(WhileNodeFactory.WhileRepeatingNodeGen.create(condition, body));
29162917
} else {
2917-
loop = new WhileNode(new WhileNode.DoWhileRepeatingNode(condition, body));
2918+
loop = new WhileNode(WhileNodeFactory.DoWhileRepeatingNodeGen.create(condition, body));
29182919
}
29192920

29202921
final RubyNode ret = new CatchBreakNode(whileBreakID, loop, true);

src/main/java/org/truffleruby/parser/TranslatorDriver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import org.truffleruby.language.arguments.RubyArguments;
7171
import org.truffleruby.language.control.RaiseException;
7272
import org.truffleruby.language.control.WhileNode;
73+
import org.truffleruby.language.control.WhileNodeFactory;
7374
import org.truffleruby.language.locals.FrameDescriptorNamesIterator;
7475
import org.truffleruby.language.locals.WriteLocalVariableNode;
7576
import org.truffleruby.language.methods.Arity;
@@ -296,7 +297,8 @@ public RootCallTarget parse(RubySource rubySource, ParserContext parserContext,
296297
sourceIndexLength,
297298
Arrays.asList(new ChompLoopNode(), truffleNode));
298299
}
299-
truffleNode = new WhileNode(new WhileNode.WhileRepeatingNode(new KernelGetsNode(), truffleNode));
300+
truffleNode = new WhileNode(
301+
WhileNodeFactory.WhileRepeatingNodeGen.create(new KernelGetsNode(), truffleNode));
300302
}
301303

302304
if (beginNode != null) {

0 commit comments

Comments
 (0)