@@ -181,6 +181,41 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
181181 }
182182}
183183
184+ impl VisitMachineValues for Thread < ' _ , ' _ > {
185+ fn visit_machine_values ( & self , visit : & mut impl FnMut ( & Operand < Provenance > ) ) {
186+ let Thread { panic_payload, last_error, stack, .. } = self ;
187+
188+ if let Some ( payload) = panic_payload {
189+ visit ( & Operand :: Immediate ( Immediate :: Scalar ( * payload) ) )
190+ }
191+ if let Some ( error) = last_error {
192+ visit ( & Operand :: Indirect ( * * error) )
193+ }
194+ for frame in stack {
195+ frame. visit_machine_values ( visit)
196+ }
197+ }
198+ }
199+
200+ impl VisitMachineValues for Frame < ' _ , ' _ , Provenance , FrameData < ' _ > > {
201+ fn visit_machine_values ( & self , visit : & mut impl FnMut ( & Operand < Provenance > ) ) {
202+ let Frame { return_place, locals, extra, .. } = self ;
203+
204+ // Return place.
205+ if let Place :: Ptr ( mplace) = * * return_place {
206+ visit ( & Operand :: Indirect ( mplace) ) ;
207+ }
208+ // Locals.
209+ for local in locals. iter ( ) {
210+ if let LocalValue :: Live ( value) = & local. value {
211+ visit ( value) ;
212+ }
213+ }
214+
215+ extra. visit_machine_values ( visit) ;
216+ }
217+ }
218+
184219/// A specific moment in time.
185220#[ derive( Debug ) ]
186221pub enum Time {
@@ -253,6 +288,22 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> {
253288 }
254289}
255290
291+ impl VisitMachineValues for ThreadManager < ' _ , ' _ > {
292+ fn visit_machine_values ( & self , visit : & mut impl FnMut ( & Operand < Provenance > ) ) {
293+ let ThreadManager { threads, thread_local_alloc_ids, .. } = self ;
294+
295+ for thread in threads {
296+ thread. visit_machine_values ( visit) ;
297+ }
298+ for ptr in thread_local_alloc_ids. borrow ( ) . values ( ) . copied ( ) {
299+ let ptr: Pointer < Option < Provenance > > = ptr. into ( ) ;
300+ visit ( & Operand :: Indirect ( MemPlace :: from_ptr ( ptr) ) ) ;
301+ }
302+ // FIXME: Do we need to do something for TimeoutCallback? That's a Box<dyn>, not sure what
303+ // to do.
304+ }
305+ }
306+
256307impl < ' mir , ' tcx : ' mir > ThreadManager < ' mir , ' tcx > {
257308 pub ( crate ) fn init ( ecx : & mut MiriInterpCx < ' mir , ' tcx > ) {
258309 if ecx. tcx . sess . target . os . as_ref ( ) != "windows" {
@@ -625,33 +676,6 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
625676 }
626677}
627678
628- impl VisitMachineValues for ThreadManager < ' _ , ' _ > {
629- fn visit_machine_values ( & self , visit : & mut impl FnMut ( & Operand < Provenance > ) ) {
630- // FIXME some other fields also contain machine values
631- let ThreadManager { threads, .. } = self ;
632-
633- for thread in threads {
634- // FIXME: implement VisitMachineValues for `Thread` and `Frame` instead.
635- // In particular we need to visit the `last_error` and `catch_unwind` fields.
636- if let Some ( payload) = thread. panic_payload {
637- visit ( & Operand :: Immediate ( Immediate :: Scalar ( payload) ) )
638- }
639- for frame in & thread. stack {
640- // Return place.
641- if let Place :: Ptr ( mplace) = * frame. return_place {
642- visit ( & Operand :: Indirect ( mplace) ) ;
643- }
644- // Locals.
645- for local in frame. locals . iter ( ) {
646- if let LocalValue :: Live ( value) = & local. value {
647- visit ( value) ;
648- }
649- }
650- }
651- }
652- }
653- }
654-
655679// Public interface to thread management.
656680impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
657681pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
0 commit comments