Skip to content

Commit 30c0d28

Browse files
committed
Fix non-constant node execution in generator try-except.
1 parent 428f23f commit 30c0d28

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/generator/GeneratorTryExceptNode.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.SaveExceptionStateNode;
4949
import com.oracle.graal.python.runtime.exception.ExceptionHandledException;
5050
import com.oracle.graal.python.runtime.exception.PException;
51+
import com.oracle.truffle.api.CompilerAsserts;
5152
import com.oracle.truffle.api.frame.VirtualFrame;
5253
import com.oracle.truffle.api.nodes.ControlFlowException;
5354
import com.oracle.truffle.api.nodes.ExplodeLoop;
@@ -121,11 +122,8 @@ private void catchExceptionInGenerator(VirtualFrame frame, PException exception,
121122
}
122123
}
123124
} else if (matchingExceptNodeIndex <= exceptNodes.length) {
124-
// we already found the right except handler, jump back into
125-
// it directly
126-
ExceptNode exceptNode = exceptNodes[matchingExceptNodeIndex - 1];
127-
runExceptionHandler(frame, exception, exceptNode, exceptionState);
128-
wasHandled = true;
125+
// we already found the right except handler, jump back into it directly
126+
wasHandled = catchExceptionInGeneratorCached(frame, exceptNodes, exception, exceptionState, matchingExceptNodeIndex);
129127
}
130128
reset(frame);
131129
if (!wasHandled) {
@@ -135,6 +133,23 @@ private void catchExceptionInGenerator(VirtualFrame frame, PException exception,
135133
restoreExceptionState.execute(frame, exceptionState);
136134
}
137135

136+
@ExplodeLoop
137+
private boolean catchExceptionInGeneratorCached(VirtualFrame frame, ExceptNode[] exceptNodes, PException exception, ExceptionState exceptionState, int matchingExceptNodeIndex) {
138+
CompilerAsserts.compilationConstant(exceptNodes);
139+
assert matchingExceptNodeIndex <= exceptNodes.length;
140+
boolean wasHandled = false;
141+
for (int i = 0; i < exceptNodes.length; i++) {
142+
// we want a constant loop iteration count for ExplodeLoop to work,
143+
// so we always run through all except handlers
144+
if (i == matchingExceptNodeIndex - 1) {
145+
runExceptionHandler(frame, exception, exceptNodes[i], exceptionState);
146+
wasHandled = true;
147+
}
148+
}
149+
assert wasHandled : "cached exception handler does not handle exception";
150+
return wasHandled;
151+
}
152+
138153
private void runExceptionHandler(VirtualFrame frame, PException exception, ExceptNode exceptNode, ExceptionState exceptionState) {
139154
try {
140155
exceptNode.executeExcept(frame, exception);

0 commit comments

Comments
 (0)