MCPcopy Index your code
hub / github.com/RustPython/RustPython / unwind_fblock_stack

Method unwind_fblock_stack

crates/codegen/src/compile.rs:1608–1689  ·  view source on GitHub ↗

Unwind the fblock stack, emitting cleanup code for each block preserve_tos: if true, preserve the top of stack (e.g., return value) stop_at_loop: if true, stop when encountering a loop (for break/continue)

(&mut self, preserve_tos: bool, stop_at_loop: bool)

Source from the content-addressed store, hash-verified

1606 /// preserve_tos: if true, preserve the top of stack (e.g., return value)
1607 /// stop_at_loop: if true, stop when encountering a loop (for break/continue)
1608 fn unwind_fblock_stack(&mut self, preserve_tos: bool, stop_at_loop: bool) -> CompileResult<()> {
1609 // Collect the info we need, with indices for FinallyTry blocks
1610 #[derive(Clone)]
1611 enum UnwindInfo {
1612 Normal(FBlockInfo),
1613 FinallyTry {
1614 body: Vec<ruff_python_ast::Stmt>,
1615 fblock_idx: usize,
1616 },
1617 }
1618 let mut unwind_infos = Vec::new();
1619
1620 {
1621 let code = self.current_code_info();
1622 for i in (0..code.fblock.len()).rev() {
1623 // Check for exception group handler (forbidden)
1624 if matches!(code.fblock[i].fb_type, FBlockType::ExceptionGroupHandler) {
1625 return Err(self.error(CodegenErrorType::BreakContinueReturnInExceptStar));
1626 }
1627
1628 // Stop at loop if requested
1629 if stop_at_loop
1630 && matches!(
1631 code.fblock[i].fb_type,
1632 FBlockType::WhileLoop | FBlockType::ForLoop
1633 )
1634 {
1635 break;
1636 }
1637
1638 if matches!(code.fblock[i].fb_type, FBlockType::FinallyTry) {
1639 if let FBlockDatum::FinallyBody(ref body) = code.fblock[i].fb_datum {
1640 unwind_infos.push(UnwindInfo::FinallyTry {
1641 body: body.clone(),
1642 fblock_idx: i,
1643 });
1644 }
1645 } else {
1646 unwind_infos.push(UnwindInfo::Normal(code.fblock[i].clone()));
1647 }
1648 }
1649 }
1650
1651 // Process each fblock
1652 for info in unwind_infos {
1653 match info {
1654 UnwindInfo::Normal(fblock_info) => {
1655 self.unwind_fblock(&fblock_info, preserve_tos)?;
1656 }
1657 UnwindInfo::FinallyTry { body, fblock_idx } => {
1658 // codegen_unwind_fblock(FINALLY_TRY)
1659 emit!(self, PseudoInstruction::PopBlock);
1660
1661 // Temporarily remove the FinallyTry fblock so nested return/break/continue
1662 // in the finally body won't see it again
1663 let code = self.current_code_info();
1664 let saved_fblock = code.fblock.remove(fblock_idx);
1665

Callers 1

compile_statementMethod · 0.80

Calls 14

newFunction · 0.85
current_code_infoMethod · 0.80
unwind_fblockMethod · 0.80
push_fblockMethod · 0.80
compile_statementsMethod · 0.80
pop_fblockMethod · 0.80
ErrClass · 0.50
revMethod · 0.45
lenMethod · 0.45
errorMethod · 0.45
pushMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected