11use crate :: frame:: Frame ;
22use crate :: { AsObject , PyObject , VirtualMachine } ;
33#[ cfg( feature = "threading" ) ]
4- use crate :: { builtins:: PyBaseExceptionRef , frame:: FrameRef } ;
4+ use crate :: builtins:: PyBaseExceptionRef ;
5+ #[ cfg( feature = "threading" ) ]
6+ use super :: FramePtr ;
57#[ cfg( feature = "threading" ) ]
68use alloc:: sync:: Arc ;
79use core:: {
@@ -16,7 +18,9 @@ use std::thread_local;
1618/// The exception field uses atomic operations for lock-free cross-thread reads.
1719#[ cfg( feature = "threading" ) ]
1820pub struct ThreadSlot {
19- pub frames : parking_lot:: Mutex < Vec < FrameRef > > ,
21+ /// Raw frame pointers, valid while the owning thread's call stack is active.
22+ /// Readers must hold the Mutex and convert to FrameRef inside the lock.
23+ pub frames : parking_lot:: Mutex < Vec < FramePtr > > ,
2024 pub exception : crate :: PyAtomicRef < Option < crate :: exceptions:: types:: PyBaseException > > ,
2125}
2226
@@ -83,13 +87,13 @@ fn init_thread_slot_if_needed(vm: &VirtualMachine) {
8387 } ) ;
8488}
8589
86- /// Push a frame onto the current thread's shared frame stack.
87- /// Called when a new frame is entered .
90+ /// Push a frame pointer onto the current thread's shared frame stack.
91+ /// The pointed-to frame must remain alive until the matching pop .
8892#[ cfg( feature = "threading" ) ]
89- pub fn push_thread_frame ( frame : FrameRef ) {
93+ pub fn push_thread_frame ( fp : FramePtr ) {
9094 CURRENT_THREAD_SLOT . with ( |slot| {
9195 if let Some ( s) = slot. borrow ( ) . as_ref ( ) {
92- s. frames . lock ( ) . push ( frame ) ;
96+ s. frames . lock ( ) . push ( fp ) ;
9397 }
9498 } ) ;
9599}
@@ -157,12 +161,7 @@ pub fn cleanup_current_thread_frames(vm: &VirtualMachine) {
157161#[ cfg( feature = "threading" ) ]
158162pub fn reinit_frame_slot_after_fork ( vm : & VirtualMachine ) {
159163 let current_ident = crate :: stdlib:: thread:: get_ident ( ) ;
160- let current_frames: Vec < FrameRef > = vm
161- . frames
162- . borrow ( )
163- . iter ( )
164- . map ( |fp| unsafe { fp. as_ref ( ) } . to_owned ( ) )
165- . collect ( ) ;
164+ let current_frames: Vec < FramePtr > = vm. frames . borrow ( ) . clone ( ) ;
166165 let new_slot = Arc :: new ( ThreadSlot {
167166 frames : parking_lot:: Mutex :: new ( current_frames) ,
168167 exception : crate :: PyAtomicRef :: from ( vm. topmost_exception ( ) ) ,
0 commit comments