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

Function label_exception_targets

crates/codegen/src/ir.rs:2917–3049  ·  view source on GitHub ↗

Label exception targets: walk CFG with except stack, set per-instruction handler info and block preserve_lasti flag. Converts POP_BLOCK to NOP. flowgraph.c label_exception_targets + push_except_block

(blocks: &mut [Block])

Source from the content-addressed store, hash-verified

2915/// handler info and block preserve_lasti flag. Converts POP_BLOCK to NOP.
2916/// flowgraph.c label_exception_targets + push_except_block
2917pub(crate) fn label_exception_targets(blocks: &mut [Block]) {
2918 #[derive(Clone)]
2919 struct ExceptEntry {
2920 handler_block: BlockIdx,
2921 preserve_lasti: bool,
2922 }
2923
2924 let num_blocks = blocks.len();
2925 if num_blocks == 0 {
2926 return;
2927 }
2928
2929 let mut visited = vec![false; num_blocks];
2930 let mut block_stacks: Vec<Option<Vec<ExceptEntry>>> = vec![None; num_blocks];
2931
2932 // Entry block
2933 visited[0] = true;
2934 block_stacks[0] = Some(Vec::new());
2935
2936 let mut todo = vec![BlockIdx(0)];
2937
2938 while let Some(block_idx) = todo.pop() {
2939 let bi = block_idx.idx();
2940 let mut stack = block_stacks[bi].take().unwrap_or_default();
2941 let mut last_yield_except_depth: i32 = -1;
2942
2943 let instr_count = blocks[bi].instructions.len();
2944 for i in 0..instr_count {
2945 // Read all needed fields (each temporary borrow ends immediately)
2946 let target = blocks[bi].instructions[i].target;
2947 let arg = blocks[bi].instructions[i].arg;
2948 let is_push = blocks[bi].instructions[i].instr.is_block_push();
2949 let is_pop = blocks[bi].instructions[i].instr.is_pop_block();
2950
2951 if is_push {
2952 // Determine preserve_lasti from instruction type (push_except_block)
2953 let preserve_lasti = matches!(
2954 blocks[bi].instructions[i].instr.pseudo(),
2955 Some(
2956 PseudoInstruction::SetupWith { .. }
2957 | PseudoInstruction::SetupCleanup { .. }
2958 )
2959 );
2960
2961 // Set preserve_lasti on handler block
2962 if preserve_lasti && target != BlockIdx::NULL {
2963 blocks[target.idx()].preserve_lasti = true;
2964 }
2965
2966 // Propagate except stack to handler block if not visited
2967 if target != BlockIdx::NULL && !visited[target.idx()] {
2968 visited[target.idx()] = true;
2969 block_stacks[target.idx()] = Some(stack.clone());
2970 todo.push(target);
2971 }
2972
2973 // Push handler onto except stack
2974 stack.push(ExceptEntry {

Callers 1

finalize_codeMethod · 0.85

Calls 15

newFunction · 0.85
idxMethod · 0.80
is_block_pushMethod · 0.80
is_pop_blockMethod · 0.80
as_u32Method · 0.80
is_scope_exitMethod · 0.80
is_unconditional_jumpMethod · 0.80
SomeClass · 0.50
lenMethod · 0.45
popMethod · 0.45
takeMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected