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

Method with_frame_impl

crates/vm/src/vm/mod.rs:1578–1625  ·  view source on GitHub ↗
(
        &self,
        frame: FrameRef,
        exc: Option<PyBaseExceptionRef>,
        traced: bool,
        f: F,
    )

Source from the content-addressed store, hash-verified

1576 }
1577
1578 fn with_frame_impl<R, F: FnOnce(FrameRef) -> PyResult<R>>(
1579 &self,
1580 frame: FrameRef,
1581 exc: Option<PyBaseExceptionRef>,
1582 traced: bool,
1583 f: F,
1584 ) -> PyResult<R> {
1585 self.with_recursion("", || {
1586 // SAFETY: `frame` (FrameRef) stays alive for the entire closure scope,
1587 // keeping the FramePtr valid. We pass a clone to `f` so that `f`
1588 // consuming its FrameRef doesn't invalidate our pointer.
1589 let fp = FramePtr(NonNull::from(&*frame));
1590 self.frames.borrow_mut().push(fp);
1591 // Update the shared frame stack for sys._current_frames() and faulthandler
1592 #[cfg(feature = "threading")]
1593 crate::vm::thread::push_thread_frame(fp);
1594 // Link frame into the signal-safe frame chain (previous pointer)
1595 let old_frame = crate::vm::thread::set_current_frame((&**frame) as *const Frame);
1596 frame.previous.store(
1597 old_frame as *mut Frame,
1598 core::sync::atomic::Ordering::Relaxed,
1599 );
1600 // Push exception context for frame isolation.
1601 // For normal calls: None (clean slate).
1602 // For generators: the saved exception from last yield.
1603 self.push_exception(exc);
1604 let old_owner = frame.owner.swap(
1605 crate::frame::FrameOwner::Thread as i8,
1606 core::sync::atomic::Ordering::AcqRel,
1607 );
1608
1609 // Ensure cleanup on panic: restore owner, pop exception, frame chain, and frames Vec.
1610 scopeguard::defer! {
1611 frame.owner.store(old_owner, core::sync::atomic::Ordering::Release);
1612 self.pop_exception();
1613 crate::vm::thread::set_current_frame(old_frame);
1614 self.frames.borrow_mut().pop();
1615 #[cfg(feature = "threading")]
1616 crate::vm::thread::pop_thread_frame();
1617 }
1618
1619 if traced {
1620 self.dispatch_traced_frame(&frame, |frame| f(frame.to_owned()))
1621 } else {
1622 f(frame.to_owned())
1623 }
1624 })
1625 }
1626
1627 /// Lightweight frame execution for generator/coroutine resume.
1628 /// Pushes to the thread frame stack and fires trace/profile events,

Callers 3

with_frameMethod · 0.80
with_frame_excMethod · 0.80
with_frame_untracedMethod · 0.80

Calls 12

FramePtrClass · 0.85
push_thread_frameFunction · 0.85
set_current_frameFunction · 0.85
with_recursionMethod · 0.80
borrow_mutMethod · 0.80
push_exceptionMethod · 0.80
dispatch_traced_frameMethod · 0.80
fFunction · 0.50
pushMethod · 0.45
storeMethod · 0.45
swapMethod · 0.45
to_ownedMethod · 0.45

Tested by

no test coverage detected