5
5
use std:: borrow:: { Borrow , Cow } ;
6
6
use std:: hash:: Hash ;
7
7
8
- use rustc:: hir:: { self , def_id:: DefId } ;
8
+ use rustc:: hir:: def_id:: DefId ;
9
9
use rustc:: mir;
10
- use rustc:: ty:: { self , query:: TyCtxtAt , layout :: Size } ;
10
+ use rustc:: ty:: { self , query:: TyCtxtAt } ;
11
11
12
12
use super :: {
13
13
Allocation , AllocId , EvalResult , Scalar , AllocationExtra ,
14
- InterpretCx , PlaceTy , MPlaceTy , OpTy , ImmTy , MemoryKind ,
14
+ InterpretCx , PlaceTy , OpTy , ImmTy , MemoryKind ,
15
15
} ;
16
16
17
17
/// Whether this kind of memory is allowed to leak
@@ -65,7 +65,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
65
65
/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
66
66
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
67
67
/// The `default()` is used for pointers to consts, statics, vtables and functions.
68
- type PointerTag : :: std:: fmt:: Debug + Default + Copy + Eq + Hash + ' static ;
68
+ type PointerTag : :: std:: fmt:: Debug + Copy + Eq + Hash + ' static ;
69
69
70
70
/// Extra data stored in every call frame.
71
71
type FrameExtra ;
@@ -90,7 +90,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
90
90
/// The memory kind to use for copied statics -- or None if statics should not be mutated
91
91
/// and thus any such attempt will cause a `ModifiedStatic` error to be raised.
92
92
/// Statics are copied under two circumstances: When they are mutated, and when
93
- /// `static_with_default_tag ` or `find_foreign_static` (see below) returns an owned allocation
93
+ /// `tag_allocation ` or `find_foreign_static` (see below) returns an owned allocation
94
94
/// that is added to the memory so that the work is not done twice.
95
95
const STATIC_KIND : Option < Self :: MemoryKinds > ;
96
96
@@ -133,11 +133,12 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
133
133
/// This will only be called once per static and machine; the result is cached in
134
134
/// the machine memory. (This relies on `AllocMap::get_or` being able to add the
135
135
/// owned allocation to the map even when the map is shared.)
136
+ ///
137
+ /// This allocation will then be fed to `tag_allocation` to initialize the "extra" state.
136
138
fn find_foreign_static (
137
139
def_id : DefId ,
138
140
tcx : TyCtxtAt < ' a , ' tcx , ' tcx > ,
139
- memory_extra : & Self :: MemoryExtra ,
140
- ) -> EvalResult < ' tcx , Cow < ' tcx , Allocation < Self :: PointerTag , Self :: AllocExtra > > > ;
141
+ ) -> EvalResult < ' tcx , Cow < ' tcx , Allocation > > ;
141
142
142
143
/// Called for all binary operations on integer(-like) types when one operand is a pointer
143
144
/// value, and for the `Offset` operation that is inherently about pointers.
@@ -156,36 +157,38 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
156
157
dest : PlaceTy < ' tcx , Self :: PointerTag > ,
157
158
) -> EvalResult < ' tcx > ;
158
159
159
- /// Called to turn an allocation obtained from the `tcx` into one that has
160
- /// the right type for this machine.
160
+ /// Called to initialize the "extra" state of an allocation and make the pointers
161
+ /// it contains (in relocations) tagged. The way we construct allocations is
162
+ /// to always first construct it without extra and then add the extra.
163
+ /// This keeps uniform code paths for handling both allocations created by CTFE
164
+ /// for statics, and allocations ceated by Miri during evaluation.
165
+ ///
166
+ /// `kind` is the kind of the allocation being tagged; it can be `None` when
167
+ /// it's a static and `STATIC_KIND` is `None`.
161
168
///
162
169
/// This should avoid copying if no work has to be done! If this returns an owned
163
170
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
164
171
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
165
172
/// owned allocation to the map even when the map is shared.)
166
- fn adjust_static_allocation < ' b > (
167
- alloc : & ' b Allocation ,
173
+ ///
174
+ /// For static allocations, the tag returned must be the same as the one returned by
175
+ /// `tag_static_base_pointer`.
176
+ fn tag_allocation < ' b > (
177
+ id : AllocId ,
178
+ alloc : Cow < ' b , Allocation > ,
179
+ kind : Option < MemoryKind < Self :: MemoryKinds > > ,
168
180
memory_extra : & Self :: MemoryExtra ,
169
- ) -> Cow < ' b , Allocation < Self :: PointerTag , Self :: AllocExtra > > ;
170
-
171
- /// Computes the extra state and the tag for a new allocation.
172
- fn new_allocation (
173
- size : Size ,
174
- extra : & Self :: MemoryExtra ,
175
- kind : MemoryKind < Self :: MemoryKinds > ,
176
- ) -> ( Self :: AllocExtra , Self :: PointerTag ) ;
177
-
178
- /// Executed when evaluating the `*` operator: Following a reference.
179
- /// This has the chance to adjust the tag. It should not change anything else!
180
- /// `mutability` can be `None` in case a raw ptr is being dereferenced.
181
- #[ inline]
182
- fn tag_dereference (
183
- _ecx : & InterpretCx < ' a , ' mir , ' tcx , Self > ,
184
- place : MPlaceTy < ' tcx , Self :: PointerTag > ,
185
- _mutability : Option < hir:: Mutability > ,
186
- ) -> EvalResult < ' tcx , Scalar < Self :: PointerTag > > {
187
- Ok ( place. ptr )
188
- }
181
+ ) -> ( Cow < ' b , Allocation < Self :: PointerTag , Self :: AllocExtra > > , Self :: PointerTag ) ;
182
+
183
+ /// Return the "base" tag for the given static allocation: the one that is used for direct
184
+ /// accesses to this static/const/fn allocation.
185
+ ///
186
+ /// Be aware that requesting the `Allocation` for that `id` will lead to cycles
187
+ /// for cyclic statics!
188
+ fn tag_static_base_pointer (
189
+ id : AllocId ,
190
+ memory_extra : & Self :: MemoryExtra ,
191
+ ) -> Self :: PointerTag ;
189
192
190
193
/// Executes a retagging operation
191
194
#[ inline]
0 commit comments