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

Method unwind_blocks

crates/vm/src/frame.rs:6323–6378  ·  view source on GitHub ↗
(&mut self, vm: &VirtualMachine, reason: UnwindReason)

Source from the content-addressed store, hash-verified

6321 /// Optionally returns an exception.
6322 #[cfg_attr(feature = "flame-it", flame("Frame"))]
6323 fn unwind_blocks(&mut self, vm: &VirtualMachine, reason: UnwindReason) -> FrameResult {
6324 // use exception table for exception handling
6325 match reason {
6326 UnwindReason::Raising { exception } => {
6327 // Look up handler in exception table
6328 // lasti points to NEXT instruction (already incremented in run loop)
6329 // The exception occurred at the previous instruction
6330 // Python uses signed int where INSTR_OFFSET() - 1 = -1 before first instruction.
6331 // We use u32, so check for 0 explicitly.
6332 if self.lasti() == 0 {
6333 // No instruction executed yet, no handler can match
6334 return Err(exception);
6335 }
6336 let offset = self.lasti() - 1;
6337 if let Some(entry) =
6338 bytecode::find_exception_handler(&self.code.exceptiontable, offset)
6339 {
6340 // Fire EXCEPTION_HANDLED before setting up handler.
6341 // If the callback raises, the handler is NOT set up and the
6342 // new exception propagates instead.
6343 if vm.state.monitoring_events.load() & monitoring::EVENT_EXCEPTION_HANDLED != 0
6344 {
6345 let byte_offset = offset * 2;
6346 let exc_obj: PyObjectRef = exception.clone().into();
6347 monitoring::fire_exception_handled(vm, self.code, byte_offset, &exc_obj)?;
6348 }
6349
6350 // 1. Pop stack to entry.depth
6351 while self.localsplus.stack_len() > entry.depth as usize {
6352 let _ = self.localsplus.stack_pop();
6353 }
6354
6355 // 2. If push_lasti=true (SETUP_CLEANUP), push lasti before exception
6356 // pushes lasti as PyLong
6357 if entry.push_lasti {
6358 self.push_value(vm.ctx.new_int(offset as i32).into());
6359 }
6360
6361 // 3. Push exception onto stack
6362 // always push exception, PUSH_EXC_INFO transforms [exc] -> [prev_exc, exc]
6363 // Do NOT call vm.set_exception here! PUSH_EXC_INFO will do it.
6364 // PUSH_EXC_INFO needs to get prev_exc from vm.current_exception() BEFORE setting the new one.
6365 self.push_value(exception.into());
6366
6367 // 4. Jump to handler
6368 self.jump(bytecode::Label::from_u32(entry.target));
6369
6370 Ok(None)
6371 } else {
6372 // No handler found, propagate exception
6373 Err(exception)
6374 }
6375 }
6376 UnwindReason::Returning { value } => Ok(Some(ExecutionResult::Return(value))),
6377 }
6378 }
6379
6380 fn execute_store_subscript(&mut self, vm: &VirtualMachine) -> FrameResult {

Callers 5

handle_exceptionMethod · 0.80
gen_throwMethod · 0.80
execute_instructionMethod · 0.80
execute_instrumentedMethod · 0.80

Calls 12

find_exception_handlerFunction · 0.85
fire_exception_handledFunction · 0.85
lastiMethod · 0.80
stack_lenMethod · 0.80
stack_popMethod · 0.80
push_valueMethod · 0.80
jumpMethod · 0.80
ErrClass · 0.50
SomeClass · 0.50
loadMethod · 0.45
cloneMethod · 0.45
new_intMethod · 0.45

Tested by

no test coverage detected