@@ -754,6 +754,18 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
754
754
String [] localNames = names ;
755
755
Node [] localNodes = adoptedNodes ;
756
756
757
+ /*
758
+ * This separate tracking of local exception is necessary to make exception state saving
759
+ * work in generators. On one hand we need to retain the exception that was caught in the
760
+ * generator, on the other hand we don't want to retain the exception state that was passed
761
+ * from the outer frame because that changes with every resume.
762
+ */
763
+ PException localException = null ;
764
+
765
+ // We initialize this lazily when pushing exception state
766
+ boolean fetchedException = false ;
767
+ PException outerException = null ;
768
+
757
769
CompilerAsserts .partialEvaluationConstant (localBC );
758
770
CompilerAsserts .partialEvaluationConstant (bci );
759
771
CompilerAsserts .partialEvaluationConstant (stackTop );
@@ -1261,34 +1273,32 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
1261
1273
if (!(exception instanceof PException )) {
1262
1274
throw CompilerDirectives .shouldNotReachHere ("interop exception state not implemented" );
1263
1275
}
1264
- stackFrame .setObject (stackTop ++, PArguments .getException (virtualFrame ));
1265
- PArguments .setException (virtualFrame , (PException ) exception );
1276
+ if (!fetchedException ) {
1277
+ outerException = PArguments .getException (virtualFrame );
1278
+ fetchedException = true ;
1279
+ }
1280
+ stackFrame .setObject (stackTop ++, localException );
1281
+ localException = (PException ) exception ;
1282
+ PArguments .setException (virtualFrame , localException );
1266
1283
stackFrame .setObject (stackTop , exception );
1267
1284
break ;
1268
1285
}
1269
1286
case OpCodesConstants .POP_EXCEPT : {
1270
- Object savedException = stackFrame .getObject (stackTop );
1271
- if (savedException == null ) {
1272
- stackTop --;
1273
- PArguments .setException (virtualFrame , null );
1274
- } else {
1275
- if (!(savedException instanceof PException )) {
1276
- throw CompilerDirectives .shouldNotReachHere ("interop exception state not implemented" );
1277
- }
1278
- stackFrame .setObject (stackTop --, null );
1279
- PArguments .setException (virtualFrame , (PException ) savedException );
1280
- }
1287
+ localException = popExceptionState (virtualFrame , stackFrame .getObject (stackTop ), outerException );
1288
+ stackFrame .setObject (stackTop --, null );
1281
1289
break ;
1282
1290
}
1283
1291
case OpCodesConstants .END_EXC_HANDLER : {
1284
- throw bytecodeEndExcHandler (virtualFrame , stackFrame , stackTop );
1292
+ localException = popExceptionState (virtualFrame , stackFrame .getObject (stackTop - 1 ), outerException );
1293
+ throw bytecodeEndExcHandler (stackFrame , stackTop );
1285
1294
}
1286
1295
case OpCodesConstants .YIELD_VALUE : {
1287
1296
if (CompilerDirectives .inInterpreter () && loopCount > 0 ) {
1288
1297
LoopNode .reportLoopCount (this , loopCount );
1289
1298
}
1290
1299
Object value = stackFrame .getObject (stackTop );
1291
1300
stackFrame .setObject (stackTop --, null );
1301
+ PArguments .setException (PArguments .getGeneratorFrame (virtualFrame ), localException );
1292
1302
// See PBytecodeGeneratorRootNode#execute
1293
1303
if (localFrame != stackFrame ) {
1294
1304
copyStackSlotsToGeneratorFrame (stackFrame , localFrame , stackTop );
@@ -1305,6 +1315,10 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
1305
1315
ThrowData throwData = (ThrowData ) sendValue ;
1306
1316
throw PException .fromObject (throwData .pythonException , this , throwData .withJavaStacktrace );
1307
1317
}
1318
+ localException = PArguments .getException (PArguments .getGeneratorFrame (virtualFrame ));
1319
+ if (localException != null ) {
1320
+ PArguments .setException (virtualFrame , localException );
1321
+ }
1308
1322
stackFrame .setObject (++stackTop , sendValue );
1309
1323
break ;
1310
1324
}
@@ -1375,13 +1389,17 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
1375
1389
}
1376
1390
long newTarget = findHandler (bci );
1377
1391
CompilerAsserts .partialEvaluationConstant (newTarget );
1378
- if (getCaughtExceptionNode == null ) {
1379
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1380
- getCaughtExceptionNode = ExceptionStateNodes .GetCaughtExceptionNode .create ();
1381
- }
1382
- PException exceptionState = getCaughtExceptionNode .execute (virtualFrame );
1383
- if (exceptionState != null ) {
1384
- ExceptionHandlingStatementNode .chainExceptions (pe .getUnreifiedException (), exceptionState , exceptionChainProfile1 , exceptionChainProfile2 );
1392
+ if (localException != null ) {
1393
+ ExceptionHandlingStatementNode .chainExceptions (pe .getUnreifiedException (), localException , exceptionChainProfile1 , exceptionChainProfile2 );
1394
+ } else {
1395
+ if (getCaughtExceptionNode == null ) {
1396
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1397
+ getCaughtExceptionNode = ExceptionStateNodes .GetCaughtExceptionNode .create ();
1398
+ }
1399
+ PException exceptionState = getCaughtExceptionNode .execute (virtualFrame );
1400
+ if (exceptionState != null ) {
1401
+ ExceptionHandlingStatementNode .chainExceptions (pe .getUnreifiedException (), exceptionState , exceptionChainProfile1 , exceptionChainProfile2 );
1402
+ }
1385
1403
}
1386
1404
if (newTarget == -1 ) {
1387
1405
// For tracebacks
@@ -1527,18 +1545,20 @@ private int bytecodeClosureFromStack(Frame stackFrame, int stackTop, int oparg)
1527
1545
return stackTop ;
1528
1546
}
1529
1547
1530
- private PException bytecodeEndExcHandler (VirtualFrame virtualFrame , Frame stackFrame , int stackTop ) {
1531
- Object exception = stackFrame .getObject (stackTop );
1532
- Object savedException = stackFrame .getObject (stackTop - 1 );
1548
+ private PException popExceptionState (VirtualFrame virtualFrame , Object savedException , PException outerException ) {
1549
+ PException localException = null ;
1550
+ if (savedException instanceof PException ) {
1551
+ localException = (PException ) savedException ;
1552
+ }
1533
1553
if (savedException == null ) {
1534
- PArguments .setException (virtualFrame , null );
1535
- } else {
1536
- if (!(savedException instanceof PException )) {
1537
- throw CompilerDirectives .shouldNotReachHere ("interop exception state not implemented" );
1538
- }
1539
- stackFrame .setObject (stackTop , null );
1540
- PArguments .setException (virtualFrame , (PException ) savedException );
1554
+ savedException = outerException ;
1541
1555
}
1556
+ PArguments .setException (virtualFrame , (PException ) savedException );
1557
+ return localException ;
1558
+ }
1559
+
1560
+ private PException bytecodeEndExcHandler (Frame stackFrame , int stackTop ) {
1561
+ Object exception = stackFrame .getObject (stackTop );
1542
1562
if (exception instanceof PException ) {
1543
1563
throw ((PException ) exception ).getExceptionForReraise ();
1544
1564
} else if (exception instanceof AbstractTruffleException ) {
0 commit comments