4848import com .oracle .graal .python .nodes .util .ExceptionStateNodes .SaveExceptionStateNode ;
4949import com .oracle .graal .python .runtime .exception .ExceptionHandledException ;
5050import com .oracle .graal .python .runtime .exception .PException ;
51+ import com .oracle .truffle .api .CompilerAsserts ;
5152import com .oracle .truffle .api .frame .VirtualFrame ;
5253import com .oracle .truffle .api .nodes .ControlFlowException ;
5354import 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