@@ -181,6 +181,41 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
181
181
}
182
182
}
183
183
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
+
184
219
/// A specific moment in time.
185
220
#[ derive( Debug ) ]
186
221
pub enum Time {
@@ -253,6 +288,22 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> {
253
288
}
254
289
}
255
290
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
+
256
307
impl < ' mir , ' tcx : ' mir > ThreadManager < ' mir , ' tcx > {
257
308
pub ( crate ) fn init ( ecx : & mut MiriInterpCx < ' mir , ' tcx > ) {
258
309
if ecx. tcx . sess . target . os . as_ref ( ) != "windows" {
@@ -625,33 +676,6 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
625
676
}
626
677
}
627
678
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
-
655
679
// Public interface to thread management.
656
680
impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriInterpCx < ' mir , ' tcx > { }
657
681
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
0 commit comments