Skip to content

Commit a0ace05

Browse files
authored
Fix asyncio compile (#6739)
1 parent 609dbb1 commit a0ace05

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

crates/codegen/src/compile.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)