39
39
import com .oracle .graal .python .runtime .PythonContext ;
40
40
import com .oracle .graal .python .runtime .PythonOptions ;
41
41
import com .oracle .graal .python .runtime .exception .PException ;
42
+ import com .oracle .graal .python .runtime .exception .PythonErrorType ;
42
43
import com .oracle .truffle .api .CompilerDirectives ;
43
44
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
44
45
import com .oracle .truffle .api .Truffle ;
48
49
import com .oracle .truffle .api .dsl .Specialization ;
49
50
import com .oracle .truffle .api .frame .FrameSlot ;
50
51
import com .oracle .truffle .api .frame .FrameSlotKind ;
51
- import com .oracle .truffle .api .frame .FrameUtil ;
52
+ import com .oracle .truffle .api .frame .FrameSlotTypeException ;
52
53
import com .oracle .truffle .api .frame .VirtualFrame ;
53
54
import com .oracle .truffle .api .nodes .NodeInfo ;
54
55
import com .oracle .truffle .api .nodes .RepeatingNode ;
55
56
56
57
final class ForRepeatingNode extends PNodeWithContext implements RepeatingNode {
57
- @ CompilationFinal FrameSlot firstIterationSlot ;
58
+
58
59
@ CompilationFinal FrameSlot iteratorSlot ;
59
- @ CompilationFinal boolean loopNeverSkipped = true ;
60
60
private final ContextReference <PythonContext > contextRef = PythonLanguage .getContextRef ();
61
61
@ Child ForNextElementNode nextElement ;
62
62
@ Child StatementNode body ;
@@ -68,30 +68,16 @@ public ForRepeatingNode(StatementNode target, StatementNode body) {
68
68
}
69
69
70
70
public boolean executeRepeating (VirtualFrame frame ) {
71
- Object iteratorObject = FrameUtil .getObjectSafe (frame , iteratorSlot );
72
- if (loopNeverSkipped ) {
73
- boolean firstIteration = FrameUtil .getBooleanSafe (frame , firstIterationSlot );
74
- if (firstIteration ) {
75
- // first loop iteration, write the iterator
76
- if (!nextElement .execute (frame , iteratorObject )) {
77
- // if we ever skip the loop we invalidate here. this helps the
78
- // compiler understand if a loop is never skipped, that the loop
79
- // variable can never be null after the loop, so it doesn't have
80
- // to merge the last value of the loop variable with null
81
- CompilerDirectives .transferToInterpreterAndInvalidate ();
82
- loopNeverSkipped = false ;
83
- return false ;
84
- }
85
- frame .setBoolean (firstIterationSlot , false );
86
- } else {
87
- if (!nextElement .execute (frame , iteratorObject )) {
88
- return false ;
89
- }
90
- }
91
- } else {
92
- if (!nextElement .execute (frame , iteratorObject )) {
71
+ try {
72
+ if (!nextElement .execute (frame , frame .getObject (iteratorSlot ))) {
93
73
return false ;
94
74
}
75
+ } catch (FrameSlotTypeException e ) {
76
+ if (raise == null ) {
77
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
78
+ raise = insert (PRaiseNode .create ());
79
+ }
80
+ throw raise .raise (PythonErrorType .RuntimeError , "internal error: unexpected frame slot type" );
95
81
}
96
82
body .executeVoid (frame );
97
83
contextRef .get ().triggerAsyncActions (frame , this );
@@ -101,6 +87,7 @@ public boolean executeRepeating(VirtualFrame frame) {
101
87
102
88
@ ImportStatic ({PythonOptions .class , SpecialMethodNames .class })
103
89
abstract class ForNextElementNode extends PNodeWithContext {
90
+
104
91
@ Child StatementNode target ;
105
92
106
93
public ForNextElementNode (StatementNode target ) {
@@ -165,10 +152,11 @@ protected boolean doIterator(VirtualFrame frame, Object object,
165
152
166
153
@ NodeInfo (shortName = "for" )
167
154
public final class ForNode extends LoopNode {
155
+
168
156
@ CompilationFinal private FrameSlot iteratorSlot ;
169
- @ CompilationFinal private FrameSlot firstIterationSlot ;
170
- @ Child private ExpressionNode iterator ;
157
+
171
158
@ Child private com .oracle .truffle .api .nodes .LoopNode loopNode ;
159
+ @ Child private ExpressionNode iterator ;
172
160
173
161
public ForNode (StatementNode body , StatementNode target , ExpressionNode iterator ) {
174
162
this .iterator = iterator ;
@@ -179,25 +167,22 @@ public StatementNode getTarget() {
179
167
return ((ForRepeatingNode ) loopNode .getRepeatingNode ()).nextElement .target ;
180
168
}
181
169
170
+ public ExpressionNode getIterator () {
171
+ return iterator ;
172
+ }
173
+
182
174
@ Override
183
175
public StatementNode getBody () {
184
176
return ((ForRepeatingNode ) loopNode .getRepeatingNode ()).body ;
185
177
}
186
178
187
- public ExpressionNode getIterator () {
188
- return iterator ;
189
- }
190
-
191
179
@ Override
192
180
public void executeVoid (VirtualFrame frame ) {
193
181
if (iteratorSlot == null ) {
194
182
CompilerDirectives .transferToInterpreterAndInvalidate ();
195
183
iteratorSlot = frame .getFrameDescriptor ().addFrameSlot (new Object (), FrameSlotKind .Object );
196
184
((ForRepeatingNode ) loopNode .getRepeatingNode ()).iteratorSlot = iteratorSlot ;
197
- firstIterationSlot = frame .getFrameDescriptor ().addFrameSlot (new Object (), FrameSlotKind .Boolean );
198
- ((ForRepeatingNode ) loopNode .getRepeatingNode ()).firstIterationSlot = firstIterationSlot ;
199
185
}
200
- frame .setBoolean (firstIterationSlot , true );
201
186
frame .setObject (iteratorSlot , iterator .execute (frame ));
202
187
try {
203
188
loopNode .executeLoop (frame );
0 commit comments