55use std:: borrow:: { Borrow , Cow } ;
66use std:: hash:: Hash ;
77
8- use rustc:: hir:: { self , def_id:: DefId } ;
8+ use rustc:: hir:: def_id:: DefId ;
99use rustc:: mir;
10- use rustc:: ty:: { self , query:: TyCtxtAt , layout :: Size } ;
10+ use rustc:: ty:: { self , query:: TyCtxtAt } ;
1111
1212use super :: {
1313 Allocation , AllocId , EvalResult , Scalar , AllocationExtra ,
14- InterpretCx , PlaceTy , MPlaceTy , OpTy , ImmTy , MemoryKind ,
14+ InterpretCx , PlaceTy , OpTy , ImmTy , MemoryKind ,
1515} ;
1616
1717/// Whether this kind of memory is allowed to leak
@@ -65,7 +65,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
6565 /// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
6666 /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
6767 /// 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 ;
6969
7070 /// Extra data stored in every call frame.
7171 type FrameExtra ;
@@ -90,7 +90,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
9090 /// The memory kind to use for copied statics -- or None if statics should not be mutated
9191 /// and thus any such attempt will cause a `ModifiedStatic` error to be raised.
9292 /// 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
9494 /// that is added to the memory so that the work is not done twice.
9595 const STATIC_KIND : Option < Self :: MemoryKinds > ;
9696
@@ -133,11 +133,12 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
133133 /// This will only be called once per static and machine; the result is cached in
134134 /// the machine memory. (This relies on `AllocMap::get_or` being able to add the
135135 /// 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.
136138 fn find_foreign_static (
137139 def_id : DefId ,
138140 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 > > ;
141142
142143 /// Called for all binary operations on integer(-like) types when one operand is a pointer
143144 /// value, and for the `Offset` operation that is inherently about pointers.
@@ -156,36 +157,38 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
156157 dest : PlaceTy < ' tcx , Self :: PointerTag > ,
157158 ) -> EvalResult < ' tcx > ;
158159
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`.
161168 ///
162169 /// This should avoid copying if no work has to be done! If this returns an owned
163170 /// allocation (because a copy had to be done to add tags or metadata), machine memory will
164171 /// cache the result. (This relies on `AllocMap::get_or` being able to add the
165172 /// 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 > > ,
168180 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 ;
189192
190193 /// Executes a retagging operation
191194 #[ inline]
0 commit comments