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

Function generate_exception_table

crates/codegen/src/ir.rs:2007–2079  ·  view source on GitHub ↗

Generate Python 3.11+ exception table from instruction handler info

(blocks: &[Block], block_to_index: &[u32])

Source from the content-addressed store, hash-verified

2005
2006/// Generate Python 3.11+ exception table from instruction handler info
2007fn generate_exception_table(blocks: &[Block], block_to_index: &[u32]) -> Box<[u8]> {
2008 let mut entries: Vec<ExceptionTableEntry> = Vec::new();
2009 let mut current_entry: Option<(ExceptHandlerInfo, u32)> = None; // (handler_info, start_index)
2010 let mut instr_index = 0u32;
2011
2012 // Iterate through all instructions in block order
2013 // instr_index is the index into the final instructions array (including EXTENDED_ARG)
2014 // This matches how frame.rs uses lasti
2015 for (_, block) in iter_blocks(blocks) {
2016 for instr in &block.instructions {
2017 // instr_size includes EXTENDED_ARG and CACHE entries
2018 let instr_size = instr.arg.instr_size() as u32 + instr.cache_entries;
2019
2020 match (&current_entry, instr.except_handler) {
2021 // No current entry, no handler - nothing to do
2022 (None, None) => {}
2023
2024 // No current entry, handler starts - begin new entry
2025 (None, Some(handler)) => {
2026 current_entry = Some((handler, instr_index));
2027 }
2028
2029 // Current entry exists, same handler - continue
2030 (Some((curr_handler, _)), Some(handler))
2031 if curr_handler.handler_block == handler.handler_block
2032 && curr_handler.stack_depth == handler.stack_depth
2033 && curr_handler.preserve_lasti == handler.preserve_lasti => {}
2034
2035 // Current entry exists, different handler - finish current, start new
2036 (Some((curr_handler, start)), Some(handler)) => {
2037 let target_index = block_to_index[curr_handler.handler_block.idx()];
2038 entries.push(ExceptionTableEntry::new(
2039 *start,
2040 instr_index,
2041 target_index,
2042 curr_handler.stack_depth as u16,
2043 curr_handler.preserve_lasti,
2044 ));
2045 current_entry = Some((handler, instr_index));
2046 }
2047
2048 // Current entry exists, no handler - finish current entry
2049 (Some((curr_handler, start)), None) => {
2050 let target_index = block_to_index[curr_handler.handler_block.idx()];
2051 entries.push(ExceptionTableEntry::new(
2052 *start,
2053 instr_index,
2054 target_index,
2055 curr_handler.stack_depth as u16,
2056 curr_handler.preserve_lasti,
2057 ));
2058 current_entry = None;
2059 }
2060 }
2061
2062 instr_index += instr_size; // Account for EXTENDED_ARG instructions
2063 }
2064 }

Callers 1

finalize_codeMethod · 0.85

Calls 7

newFunction · 0.85
iter_blocksFunction · 0.85
encode_exception_tableFunction · 0.85
instr_sizeMethod · 0.80
idxMethod · 0.80
SomeClass · 0.50
pushMethod · 0.45

Tested by

no test coverage detected