diff options
| author | Ralf Jung <post@ralfj.de> | 2018-10-16 09:15:13 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2018-10-18 12:08:22 +0200 |
| commit | 21934c81f430d1a638279bb5d1d00cbe052a2eee (patch) | |
| tree | 3f20b41c1995b22bdddcfc4a07a356de5d30d6c5 /src/librustc_mir/interpret | |
| parent | 290db47ad67ee2ef0a43fb4b9b6561d00c4a078e (diff) | |
| download | rust-21934c81f430d1a638279bb5d1d00cbe052a2eee.tar.gz rust-21934c81f430d1a638279bb5d1d00cbe052a2eee.zip | |
add support for storing extra data in an allocation
Diffstat (limited to 'src/librustc_mir/interpret')
| -rw-r--r-- | src/librustc_mir/interpret/eval_context.rs | 3 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/machine.rs | 26 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 24 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/place.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/snapshot.rs | 2 |
5 files changed, 26 insertions, 31 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index cf5358a9896..9fb838c28a5 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -205,13 +205,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc tcx: TyCtxtAt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, machine: M, - memory_data: M::MemoryData, ) -> Self { EvalContext { machine, tcx, param_env, - memory: Memory::new(tcx, memory_data), + memory: Memory::new(tcx), stack: Vec::new(), vtables: FxHashMap::default(), } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 560698f3f57..790a1f6b745 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -62,23 +62,25 @@ pub trait AllocMap<K: Hash + Eq, V> { /// Methods of this trait signifies a point where CTFE evaluation would fail /// and some use case dependent behaviour can instead be applied. pub trait Machine<'a, 'mir, 'tcx>: Sized { - /// Additional data that can be accessed via the Memory - type MemoryData; - /// Additional memory kinds a machine wishes to distinguish from the builtin ones - type MemoryKinds: ::std::fmt::Debug + Copy + Eq; + type MemoryKinds: ::std::fmt::Debug + Copy + Eq + 'static; + + /// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows" + /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>. + type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static; + + /// Extra data stored in every allocation. + type AllocExtra: ::std::fmt::Debug + Default + Clone; /// Memory's allocation map type MemoryMap: - AllocMap<AllocId, (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag>)> + + AllocMap< + AllocId, + (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>) + > + Default + Clone; - /// Tag tracked alongside every pointer. This is inert for now, in preparation for - /// a future implementation of "Stacked Borrows" - /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>. - type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static; - /// The memory kind to use for copied statics -- or None if those are not supported. /// Statics are copied under two circumstances: When they are mutated, and when /// `static_with_default_tag` or `find_foreign_static` (see below) returns an owned allocation @@ -127,7 +129,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized { fn find_foreign_static( tcx: TyCtxtAt<'a, 'tcx, 'tcx>, def_id: DefId, - ) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>>; + ) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>; /// Called to turn an allocation obtained from the `tcx` into one that has /// the appropriate tags on each pointer. @@ -138,7 +140,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized { /// owned allocation to the map even when the map is shared.) fn static_with_default_tag( alloc: &'_ Allocation - ) -> Cow<'_, Allocation<Self::PointerTag>>; + ) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>; /// Called for all binary operations on integer(-like) types when one operand is a pointer /// value, and for the `Offset` operation that is inherently about pointers. diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 4b0c0c3ee61..d61f3e38569 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -47,9 +47,6 @@ pub enum MemoryKind<T> { // `Memory` has to depend on the `Machine` because some of its operations // (e.g. `get`) call a `Machine` hook. pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> { - /// Additional data required by the Machine - pub data: M::MemoryData, - /// Allocations local to this instance of the miri engine. The kind /// helps ensure that the same mechanism is used for allocation and /// deallocation. When an allocation is not found here, it is a @@ -91,11 +88,9 @@ impl<'a, 'b, 'c, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout // carefully copy only the reachable parts. impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> Clone for Memory<'a, 'mir, 'tcx, M> - where M::MemoryData: Clone { fn clone(&self) -> Self { Memory { - data: self.data.clone(), alloc_map: self.alloc_map.clone(), dead_alloc_map: self.dead_alloc_map.clone(), tcx: self.tcx, @@ -104,9 +99,8 @@ impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> } impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { - pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self { + pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>) -> Self { Memory { - data, alloc_map: Default::default(), dead_alloc_map: FxHashMap::default(), tcx, @@ -123,7 +117,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn allocate_with( &mut self, - alloc: Allocation<M::PointerTag>, + alloc: Allocation<M::PointerTag, M::AllocExtra>, kind: MemoryKind<M::MemoryKinds>, ) -> EvalResult<'tcx, AllocId> { let id = self.tcx.alloc_map.lock().reserve(); @@ -334,7 +328,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { fn get_static_alloc( tcx: TyCtxtAt<'a, 'tcx, 'tcx>, id: AllocId, - ) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag>>> { + ) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> { let alloc = tcx.alloc_map.lock().get(id); let def_id = match alloc { Some(AllocType::Memory(mem)) => { @@ -376,7 +370,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { }) } - pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation<M::PointerTag>> { + pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation<M::PointerTag, M::AllocExtra>> { // The error type of the inner closure here is somewhat funny. We have two // ways of "erroring": An actual error, or because we got a reference from // `get_static_alloc` that we can actually use directly without inserting anything anywhere. @@ -409,7 +403,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn get_mut( &mut self, id: AllocId, - ) -> EvalResult<'tcx, &mut Allocation<M::PointerTag>> { + ) -> EvalResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> { let tcx = self.tcx; let a = self.alloc_map.get_mut_or(id, || { // Need to make a copy, even if `get_static_alloc` is able @@ -482,12 +476,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { self.dump_allocs(vec![id]); } - fn dump_alloc_helper<Tag>( + fn dump_alloc_helper<Tag, Extra>( &self, allocs_seen: &mut FxHashSet<AllocId>, allocs_to_print: &mut VecDeque<AllocId>, mut msg: String, - alloc: &Allocation<Tag>, + alloc: &Allocation<Tag, Extra>, extra: String, ) { use std::fmt::Write; @@ -687,8 +681,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { /// Interning (for CTFE) impl<'a, 'mir, 'tcx, M> Memory<'a, 'mir, 'tcx, M> where - M: Machine<'a, 'mir, 'tcx, PointerTag=()>, - M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<()>)>, + M: Machine<'a, 'mir, 'tcx, PointerTag=(), AllocExtra=()>, + M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation)>, { /// mark an allocation as static and initialized, either mutable or not pub fn intern_static( diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index e4055947b64..c4f01d8ce31 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -267,7 +267,7 @@ impl<'a, 'mir, 'tcx, Tag, M> EvalContext<'a, 'mir, 'tcx, M> where Tag: ::std::fmt::Debug+Default+Copy+Eq+Hash+'static, M: Machine<'a, 'mir, 'tcx, PointerTag=Tag>, - M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<Tag>)>, + M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<Tag, M::AllocExtra>)>, { /// Take a value, which represents a (thin or fat) reference, and make it a place. /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref`. diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 11d5785bc56..047a0125f78 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -305,7 +305,7 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation type Item = AllocationSnapshot<'a>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { - let Allocation { bytes, relocations, undef_mask, align, mutability } = self; + let Allocation { bytes, relocations, undef_mask, align, mutability, extra: () } = self; AllocationSnapshot { bytes, |
