1
+ use std:: any:: Any ;
1
2
use std:: collections:: { hash_map:: Entry , VecDeque } ;
2
3
use std:: ops:: Not ;
3
4
use std:: time:: Duration ;
4
5
5
6
use rustc_data_structures:: fx:: FxHashMap ;
6
7
use rustc_index:: { Idx , IndexVec } ;
7
- use rustc_middle :: ty :: layout :: TyAndLayout ;
8
+ use rustc_target :: abi :: Size ;
8
9
9
10
use super :: init_once:: InitOnce ;
10
11
use super :: vector_clock:: VClock ;
@@ -66,27 +67,6 @@ pub(super) use declare_id;
66
67
67
68
declare_id ! ( MutexId ) ;
68
69
69
- /// The mutex kind.
70
- #[ derive( Debug , Clone , Copy ) ]
71
- #[ non_exhaustive]
72
- pub enum MutexKind {
73
- Invalid ,
74
- Normal ,
75
- Default ,
76
- Recursive ,
77
- ErrorCheck ,
78
- }
79
-
80
- #[ derive( Debug ) ]
81
- /// Additional data that may be used by shim implementations.
82
- pub struct AdditionalMutexData {
83
- /// The mutex kind, used by some mutex implementations like pthreads mutexes.
84
- pub kind : MutexKind ,
85
-
86
- /// The address of the mutex.
87
- pub address : u64 ,
88
- }
89
-
90
70
/// The mutex state.
91
71
#[ derive( Default , Debug ) ]
92
72
struct Mutex {
@@ -100,18 +80,11 @@ struct Mutex {
100
80
clock : VClock ,
101
81
102
82
/// Additional data that can be set by shim implementations.
103
- data : Option < AdditionalMutexData > ,
83
+ data : Option < Box < dyn Any > > ,
104
84
}
105
85
106
86
declare_id ! ( RwLockId ) ;
107
87
108
- #[ derive( Debug ) ]
109
- /// Additional data that may be used by shim implementations.
110
- pub struct AdditionalRwLockData {
111
- /// The address of the rwlock.
112
- pub address : u64 ,
113
- }
114
-
115
88
/// The read-write lock state.
116
89
#[ derive( Default , Debug ) ]
117
90
struct RwLock {
@@ -146,7 +119,7 @@ struct RwLock {
146
119
clock_current_readers : VClock ,
147
120
148
121
/// Additional data that can be set by shim implementations.
149
- data : Option < AdditionalRwLockData > ,
122
+ data : Option < Box < dyn Any > > ,
150
123
}
151
124
152
125
declare_id ! ( CondvarId ) ;
@@ -206,21 +179,21 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
206
179
#[ inline]
207
180
fn get_or_create_id < Id : SyncId + Idx , T > (
208
181
& mut self ,
209
- lock_op : & OpTy < ' tcx > ,
210
- lock_layout : TyAndLayout < ' tcx > ,
182
+ lock : & MPlaceTy < ' tcx > ,
211
183
offset : u64 ,
212
184
get_objs : impl for < ' a > Fn ( & ' a mut MiriInterpCx < ' tcx > ) -> & ' a mut IndexVec < Id , T > ,
213
185
create_obj : impl for < ' a > FnOnce ( & ' a mut MiriInterpCx < ' tcx > ) -> InterpResult < ' tcx , T > ,
214
186
) -> InterpResult < ' tcx , Option < Id > > {
215
187
let this = self . eval_context_mut ( ) ;
216
- let value_place =
217
- this. deref_pointer_and_offset ( lock_op, offset, lock_layout, this. machine . layouts . u32 ) ?;
188
+ let offset = Size :: from_bytes ( offset) ;
189
+ assert ! ( lock. layout. size >= offset + this. machine. layouts. u32 . size) ;
190
+ let id_place = lock. offset ( offset, this. machine . layouts . u32 , this) ?;
218
191
let next_index = get_objs ( this) . next_index ( ) ;
219
192
220
193
// Since we are lazy, this update has to be atomic.
221
194
let ( old, success) = this
222
195
. atomic_compare_exchange_scalar (
223
- & value_place ,
196
+ & id_place ,
224
197
& ImmTy :: from_uint ( 0u32 , this. machine . layouts . u32 ) ,
225
198
Scalar :: from_u32 ( next_index. to_u32 ( ) ) ,
226
199
AtomicRwOrd :: Relaxed , // deliberately *no* synchronization
@@ -258,18 +231,18 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
258
231
/// - `obj` must be the new sync object.
259
232
fn create_id < Id : SyncId + Idx , T > (
260
233
& mut self ,
261
- lock_op : & OpTy < ' tcx > ,
262
- lock_layout : TyAndLayout < ' tcx > ,
234
+ lock : & MPlaceTy < ' tcx > ,
263
235
offset : u64 ,
264
236
get_objs : impl for < ' a > Fn ( & ' a mut MiriInterpCx < ' tcx > ) -> & ' a mut IndexVec < Id , T > ,
265
237
obj : T ,
266
238
) -> InterpResult < ' tcx , Id > {
267
239
let this = self . eval_context_mut ( ) ;
268
- let value_place =
269
- this. deref_pointer_and_offset ( lock_op, offset, lock_layout, this. machine . layouts . u32 ) ?;
240
+ let offset = Size :: from_bytes ( offset) ;
241
+ assert ! ( lock. layout. size >= offset + this. machine. layouts. u32 . size) ;
242
+ let id_place = lock. offset ( offset, this. machine . layouts . u32 , this) ?;
270
243
271
244
let new_index = get_objs ( this) . push ( obj) ;
272
- this. write_scalar ( Scalar :: from_u32 ( new_index. to_u32 ( ) ) , & value_place ) ?;
245
+ this. write_scalar ( Scalar :: from_u32 ( new_index. to_u32 ( ) ) , & id_place ) ?;
273
246
Ok ( new_index)
274
247
}
275
248
@@ -302,15 +275,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
302
275
/// Eagerly create and initialize a new mutex.
303
276
fn mutex_create (
304
277
& mut self ,
305
- lock_op : & OpTy < ' tcx > ,
306
- lock_layout : TyAndLayout < ' tcx > ,
278
+ lock : & MPlaceTy < ' tcx > ,
307
279
offset : u64 ,
308
- data : Option < AdditionalMutexData > ,
280
+ data : Option < Box < dyn Any > > ,
309
281
) -> InterpResult < ' tcx , MutexId > {
310
282
let this = self . eval_context_mut ( ) ;
311
283
this. create_id (
312
- lock_op,
313
- lock_layout,
284
+ lock,
314
285
offset,
315
286
|ecx| & mut ecx. machine . sync . mutexes ,
316
287
Mutex { data, ..Default :: default ( ) } ,
@@ -321,17 +292,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
321
292
/// `initialize_data` must return any additional data that a user wants to associate with the mutex.
322
293
fn mutex_get_or_create_id (
323
294
& mut self ,
324
- lock_op : & OpTy < ' tcx > ,
325
- lock_layout : TyAndLayout < ' tcx > ,
295
+ lock : & MPlaceTy < ' tcx > ,
326
296
offset : u64 ,
327
297
initialize_data : impl for < ' a > FnOnce (
328
298
& ' a mut MiriInterpCx < ' tcx > ,
329
- ) -> InterpResult < ' tcx , Option < AdditionalMutexData > > ,
299
+ ) -> InterpResult < ' tcx , Option < Box < dyn Any > > > ,
330
300
) -> InterpResult < ' tcx , MutexId > {
331
301
let this = self . eval_context_mut ( ) ;
332
302
this. get_or_create_id (
333
- lock_op,
334
- lock_layout,
303
+ lock,
335
304
offset,
336
305
|ecx| & mut ecx. machine . sync . mutexes ,
337
306
|ecx| initialize_data ( ecx) . map ( |data| Mutex { data, ..Default :: default ( ) } ) ,
@@ -340,28 +309,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
340
309
}
341
310
342
311
/// Retrieve the additional data stored for a mutex.
343
- fn mutex_get_data < ' a > ( & ' a mut self , id : MutexId ) -> Option < & ' a AdditionalMutexData >
312
+ fn mutex_get_data < ' a , T : ' static > ( & ' a mut self , id : MutexId ) -> Option < & ' a T >
344
313
where
345
314
' tcx : ' a ,
346
315
{
347
316
let this = self . eval_context_ref ( ) ;
348
- this. machine . sync . mutexes [ id] . data . as_ref ( )
317
+ this. machine . sync . mutexes [ id] . data . as_deref ( ) . and_then ( |p| p . downcast_ref :: < T > ( ) )
349
318
}
350
319
351
320
fn rwlock_get_or_create_id (
352
321
& mut self ,
353
- lock_op : & OpTy < ' tcx > ,
354
- lock_layout : TyAndLayout < ' tcx > ,
322
+ lock : & MPlaceTy < ' tcx > ,
355
323
offset : u64 ,
356
324
initialize_data : impl for < ' a > FnOnce (
357
325
& ' a mut MiriInterpCx < ' tcx > ,
358
- )
359
- -> InterpResult < ' tcx , Option < AdditionalRwLockData > > ,
326
+ ) -> InterpResult < ' tcx , Option < Box < dyn Any > > > ,
360
327
) -> InterpResult < ' tcx , RwLockId > {
361
328
let this = self . eval_context_mut ( ) ;
362
329
this. get_or_create_id (
363
- lock_op,
364
- lock_layout,
330
+ lock,
365
331
offset,
366
332
|ecx| & mut ecx. machine . sync . rwlocks ,
367
333
|ecx| initialize_data ( ecx) . map ( |data| RwLock { data, ..Default :: default ( ) } ) ,
@@ -370,24 +336,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
370
336
}
371
337
372
338
/// Retrieve the additional data stored for a rwlock.
373
- fn rwlock_get_data < ' a > ( & ' a mut self , id : RwLockId ) -> Option < & ' a AdditionalRwLockData >
339
+ fn rwlock_get_data < ' a , T : ' static > ( & ' a mut self , id : RwLockId ) -> Option < & ' a T >
374
340
where
375
341
' tcx : ' a ,
376
342
{
377
343
let this = self . eval_context_ref ( ) ;
378
- this. machine . sync . rwlocks [ id] . data . as_ref ( )
344
+ this. machine . sync . rwlocks [ id] . data . as_deref ( ) . and_then ( |p| p . downcast_ref :: < T > ( ) )
379
345
}
380
346
381
347
fn condvar_get_or_create_id (
382
348
& mut self ,
383
- lock_op : & OpTy < ' tcx > ,
384
- lock_layout : TyAndLayout < ' tcx > ,
349
+ lock : & MPlaceTy < ' tcx > ,
385
350
offset : u64 ,
386
351
) -> InterpResult < ' tcx , CondvarId > {
387
352
let this = self . eval_context_mut ( ) ;
388
353
this. get_or_create_id (
389
- lock_op,
390
- lock_layout,
354
+ lock,
391
355
offset,
392
356
|ecx| & mut ecx. machine . sync . condvars ,
393
357
|_| Ok ( Default :: default ( ) ) ,
0 commit comments