@@ -2547,18 +2547,28 @@ impl Compiler {
25472547 ) ?;
25482548 }
25492549 self . compile_statements ( finalbody) ?;
2550- // RERAISE 0 is emitted BEFORE pop_fblock
2551- // This ensures RERAISE goes to cleanup block (FinallyEnd handler)
2552- // which then properly restores prev_exc before going to outer handler
2550+
2551+ // Pop FinallyEnd fblock BEFORE emitting RERAISE
2552+ // This ensures RERAISE routes to outer exception handler, not cleanup block
2553+ // Cleanup block is only for new exceptions raised during finally body execution
2554+ if finally_cleanup_block. is_some ( ) {
2555+ self . pop_fblock ( FBlockType :: FinallyEnd ) ;
2556+ }
2557+
2558+ // Restore prev_exc as current exception before RERAISE
2559+ // Stack: [prev_exc, exc] -> COPY 2 -> [prev_exc, exc, prev_exc]
2560+ // POP_EXCEPT pops prev_exc and sets exc_info->exc_value = prev_exc
2561+ // Stack after POP_EXCEPT: [prev_exc, exc]
2562+ emit ! ( self , Instruction :: Copy { index: 2_u32 } ) ;
2563+ emit ! ( self , Instruction :: PopExcept ) ;
2564+
2565+ // RERAISE 0: re-raise the original exception to outer handler
25532566 emit ! (
25542567 self ,
25552568 Instruction :: RaiseVarargs {
25562569 kind: bytecode:: RaiseKind :: ReraiseFromStack
25572570 }
25582571 ) ;
2559- if finally_cleanup_block. is_some ( ) {
2560- self . pop_fblock ( FBlockType :: FinallyEnd ) ;
2561- }
25622572 }
25632573
25642574 if let Some ( cleanup) = finally_cleanup_block {
@@ -2837,21 +2847,28 @@ impl Compiler {
28372847 // Run finally body
28382848 self . compile_statements ( finalbody) ?;
28392849
2840- // RERAISE 0 is emitted BEFORE pop_fblock
2841- // This ensures RERAISE goes to cleanup block (FinallyEnd handler)
2842- // which then properly restores prev_exc before going to outer handler
2843- // RERAISE 0: reraise the exception on TOS
2850+ // Pop FinallyEnd fblock BEFORE emitting RERAISE
2851+ // This ensures RERAISE routes to outer exception handler, not cleanup block
2852+ // Cleanup block is only for new exceptions raised during finally body execution
2853+ if finally_cleanup_block. is_some ( ) {
2854+ self . pop_fblock ( FBlockType :: FinallyEnd ) ;
2855+ }
2856+
2857+ // Restore prev_exc as current exception before RERAISE
2858+ // Stack: [lasti, prev_exc, exc] -> COPY 2 -> [lasti, prev_exc, exc, prev_exc]
2859+ // POP_EXCEPT pops prev_exc and sets exc_info->exc_value = prev_exc
2860+ // Stack after POP_EXCEPT: [lasti, prev_exc, exc]
2861+ emit ! ( self , Instruction :: Copy { index: 2_u32 } ) ;
2862+ emit ! ( self , Instruction :: PopExcept ) ;
2863+
2864+ // RERAISE 0: re-raise the original exception to outer handler
28442865 // Stack: [lasti, prev_exc, exc] - exception is on top
28452866 emit ! (
28462867 self ,
28472868 Instruction :: RaiseVarargs {
28482869 kind: bytecode:: RaiseKind :: ReraiseFromStack ,
28492870 }
28502871 ) ;
2851-
2852- if finally_cleanup_block. is_some ( ) {
2853- self . pop_fblock ( FBlockType :: FinallyEnd ) ;
2854- }
28552872 }
28562873
28572874 // finally cleanup block
0 commit comments