about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBruno Dutra <brunocodutra@gmail.com>2018-08-18 12:14:18 +0200
committerBruno Dutra <brunocodutra@gmail.com>2018-09-03 20:02:35 +0200
commitadb1965c12587bcc24edd62e9ecf1c240f8196cd (patch)
tree7decf0d63feec18af0e629a4910e8c6088707621
parent2f5c3fde7c5443b8afceaa65aec2b1f62f33e12e (diff)
downloadrust-adb1965c12587bcc24edd62e9ecf1c240f8196cd.tar.gz
rust-adb1965c12587bcc24edd62e9ecf1c240f8196cd.zip
Introduce Snapshot and SnapshotContext traits
-rw-r--r--src/librustc_mir/interpret/snapshot.rs266
1 files changed, 265 insertions, 1 deletions
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 45574da7410..2bb184cd9bc 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -1,9 +1,273 @@
 use std::hash::{Hash, Hasher};
 
 use rustc::ich::{StableHashingContext, StableHashingContextProvider};
+use rustc::mir;
+use rustc::mir::interpret::{AllocId, Pointer, Scalar, ScalarMaybeUndef, Relocations, Allocation, UndefMask};
+use rustc::ty;
+use rustc::ty::layout::Align;
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
+use syntax::ast::Mutability;
+use syntax::source_map::Span;
 
-use super::{Frame, Memory, Machine};
+use super::eval_context::{LocalValue, StackPopCleanup};
+use super::{Frame, Memory, Machine, Operand, MemPlace, Place, PlaceExtra, Value};
+
+trait SnapshotContext<'a> {
+    type To;
+    type From;
+    fn resolve(&'a self, id: &Self::From) -> Option<&'a Self::To>;
+}
+
+trait Snapshot<'a, Ctx: SnapshotContext<'a>> {
+    type Item;
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item;
+}
+
+#[derive(Eq, PartialEq)]
+struct AllocIdSnapshot<'a>(Option<AllocationSnapshot<'a>>);
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = AllocIdSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        AllocIdSnapshot(ctx.resolve(self).map(|alloc| alloc.snapshot(ctx)))
+    }
+}
+
+type PointerSnapshot<'a> = Pointer<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Pointer
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = PointerSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        let Pointer{ alloc_id, offset } = self;
+
+        Pointer {
+            alloc_id: alloc_id.snapshot(ctx),
+            offset: *offset,
+        }
+    }
+}
+
+type ScalarSnapshot<'a> = Scalar<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Scalar
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = ScalarSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)),
+            Scalar::Bits{ size, bits } => Scalar::Bits{
+                size: *size,
+                bits: *bits,
+            },
+        }
+    }
+}
+
+type ScalarMaybeUndefSnapshot<'a> = ScalarMaybeUndef<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for ScalarMaybeUndef
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = ScalarMaybeUndefSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.snapshot(ctx)),
+            ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef,
+        }
+    }
+}
+
+type MemPlaceSnapshot<'a> = MemPlace<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for MemPlace
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = MemPlaceSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        let MemPlace{ ptr, extra, align } = self;
+
+        MemPlaceSnapshot{
+            ptr: ptr.snapshot(ctx),
+            extra: extra.snapshot(ctx),
+            align: *align,
+        }
+    }
+}
+
+type PlaceSnapshot<'a> = Place<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Place
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = PlaceSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            Place::Ptr(p) => Place::Ptr(p.snapshot(ctx)),
+
+            Place::Local{ frame, local } => Place::Local{
+                frame: *frame,
+                local: *local,
+            },
+        }
+    }
+}
+
+type PlaceExtraSnapshot<'a> = PlaceExtra<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for PlaceExtra
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = PlaceExtraSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            PlaceExtra::Vtable(p) => PlaceExtra::Vtable(p.snapshot(ctx)),
+            PlaceExtra::Length(l) => PlaceExtra::Length(*l),
+            PlaceExtra::None => PlaceExtra::None,
+        }
+    }
+}
+
+type ValueSnapshot<'a> = Value<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Value
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = ValueSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            Value::Scalar(s) => Value::Scalar(s.snapshot(ctx)),
+            Value::ScalarPair(a, b) => Value::ScalarPair(a.snapshot(ctx), b.snapshot(ctx)),
+        }
+    }
+}
+
+type OperandSnapshot<'a> = Operand<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Operand
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = OperandSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            Operand::Immediate(v) => Operand::Immediate(v.snapshot(ctx)),
+            Operand::Indirect(m) => Operand::Indirect(m.snapshot(ctx)),
+        }
+    }
+}
+
+type LocalValueSnapshot<'a> = LocalValue<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for LocalValue
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = LocalValueSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        match self {
+            LocalValue::Live(v) => LocalValue::Live(v.snapshot(ctx)),
+            LocalValue::Dead => LocalValue::Dead,
+        }
+    }
+}
+
+type RelocationsSnapshot<'a> = Relocations<AllocIdSnapshot<'a>>;
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = RelocationsSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        Relocations::from_presorted(self.iter().map(|(size, id)| (*size, id.snapshot(ctx))).collect())
+    }
+}
+
+#[derive(Eq, PartialEq)]
+struct AllocationSnapshot<'a> {
+    bytes: &'a [u8],
+    relocations: RelocationsSnapshot<'a>,
+    undef_mask: &'a UndefMask,
+    align: &'a Align,
+    runtime_mutability: &'a Mutability,
+}
+
+impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = AllocationSnapshot<'a>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        let Allocation { bytes, relocations, undef_mask, align, runtime_mutability } = self;
+
+        AllocationSnapshot {
+            bytes,
+            undef_mask,
+            align,
+            runtime_mutability,
+            relocations: relocations.snapshot(ctx),
+        }
+    }
+}
+
+#[derive(Eq, PartialEq)]
+struct FrameSnapshot<'a, 'tcx> {
+    instance: &'a ty::Instance<'tcx>,
+    span: &'a Span,
+    return_to_block: &'a StackPopCleanup,
+    return_place: PlaceSnapshot<'a>,
+    locals: IndexVec<mir::Local, LocalValueSnapshot<'a>>,
+    block: &'a mir::BasicBlock,
+    stmt: usize,
+}
+
+impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
+    where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
+{
+    type Item = FrameSnapshot<'a, 'tcx>;
+
+    fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
+        let Frame {
+            mir: _,
+            instance,
+            span,
+            return_to_block,
+            return_place,
+            locals,
+            block,
+            stmt,
+        } = self;
+
+        FrameSnapshot {
+            instance,
+            span,
+            return_to_block,
+            block,
+            stmt: *stmt,
+            return_place: return_place.snapshot(ctx),
+            locals: locals.iter().map(|local| local.snapshot(ctx)).collect(),
+        }
+    }
+}
+
+#[derive(Eq, PartialEq)]
+struct MemorySnapshot<'a, 'mir: 'a, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx> + 'a> {
+    data: &'a M::MemoryData,
+}
 
 /// The virtual machine state during const-evaluation at a given point in time.
 #[derive(Eq, PartialEq)]