Perform deferred stack unwinding after set_f_lineno. set_f_lineno cannot pop the value stack directly because the execution loop holds the state mutex. Instead it records the work in `pending_stack_pops` / `pending_unwind_from_stack` and we execute it here, inside the execution loop where we already own the state.
(&mut self, pop_count: usize, from_stack: i64, vm: &VirtualMachine)
| 1399 | /// `pending_stack_pops` / `pending_unwind_from_stack` and we execute it |
| 1400 | /// here, inside the execution loop where we already own the state. |
| 1401 | fn unwind_stack_for_lineno(&mut self, pop_count: usize, from_stack: i64, vm: &VirtualMachine) { |
| 1402 | let mut cur_stack = from_stack; |
| 1403 | for _ in 0..pop_count { |
| 1404 | let val = self.pop_value_opt(); |
| 1405 | if stack_analysis::top_of_stack(cur_stack) == stack_analysis::Kind::Except as i64 |
| 1406 | && let Some(exc_obj) = val |
| 1407 | { |
| 1408 | if vm.is_none(&exc_obj) { |
| 1409 | vm.set_exception(None); |
| 1410 | } else { |
| 1411 | let exc = exc_obj.downcast::<PyBaseException>().ok(); |
| 1412 | vm.set_exception(exc); |
| 1413 | } |
| 1414 | } |
| 1415 | cur_stack = stack_analysis::pop_value(cur_stack); |
| 1416 | } |
| 1417 | } |
| 1418 | |
| 1419 | /// Fire 'exception' trace event (sys.settrace) with (type, value, traceback) tuple. |
| 1420 | /// Matches `_PyEval_MonitorRaise` → `PY_MONITORING_EVENT_RAISE` → |
no test coverage detected