Skip to content

Commit adb1965

Browse files
committed
Introduce Snapshot and SnapshotContext traits
1 parent 2f5c3fd commit adb1965

File tree

1 file changed

+265
-1
lines changed

1 file changed

+265
-1
lines changed

src/librustc_mir/interpret/snapshot.rs

Lines changed: 265 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,273 @@
11
use std::hash::{Hash, Hasher};
22

33
use rustc::ich::{StableHashingContext, StableHashingContextProvider};
4+
use rustc::mir;
5+
use rustc::mir::interpret::{AllocId, Pointer, Scalar, ScalarMaybeUndef, Relocations, Allocation, UndefMask};
6+
use rustc::ty;
7+
use rustc::ty::layout::Align;
8+
use rustc_data_structures::indexed_vec::IndexVec;
49
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
10+
use syntax::ast::Mutability;
11+
use syntax::source_map::Span;
512

6-
use super::{Frame, Memory, Machine};
13+
use super::eval_context::{LocalValue, StackPopCleanup};
14+
use super::{Frame, Memory, Machine, Operand, MemPlace, Place, PlaceExtra, Value};
15+
16+
trait SnapshotContext<'a> {
17+
type To;
18+
type From;
19+
fn resolve(&'a self, id: &Self::From) -> Option<&'a Self::To>;
20+
}
21+
22+
trait Snapshot<'a, Ctx: SnapshotContext<'a>> {
23+
type Item;
24+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item;
25+
}
26+
27+
#[derive(Eq, PartialEq)]
28+
struct AllocIdSnapshot<'a>(Option<AllocationSnapshot<'a>>);
29+
30+
impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId
31+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
32+
{
33+
type Item = AllocIdSnapshot<'a>;
34+
35+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
36+
AllocIdSnapshot(ctx.resolve(self).map(|alloc| alloc.snapshot(ctx)))
37+
}
38+
}
39+
40+
type PointerSnapshot<'a> = Pointer<AllocIdSnapshot<'a>>;
41+
42+
impl<'a, Ctx> Snapshot<'a, Ctx> for Pointer
43+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
44+
{
45+
type Item = PointerSnapshot<'a>;
46+
47+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
48+
let Pointer{ alloc_id, offset } = self;
49+
50+
Pointer {
51+
alloc_id: alloc_id.snapshot(ctx),
52+
offset: *offset,
53+
}
54+
}
55+
}
56+
57+
type ScalarSnapshot<'a> = Scalar<AllocIdSnapshot<'a>>;
58+
59+
impl<'a, Ctx> Snapshot<'a, Ctx> for Scalar
60+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
61+
{
62+
type Item = ScalarSnapshot<'a>;
63+
64+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
65+
match self {
66+
Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)),
67+
Scalar::Bits{ size, bits } => Scalar::Bits{
68+
size: *size,
69+
bits: *bits,
70+
},
71+
}
72+
}
73+
}
74+
75+
type ScalarMaybeUndefSnapshot<'a> = ScalarMaybeUndef<AllocIdSnapshot<'a>>;
76+
77+
impl<'a, Ctx> Snapshot<'a, Ctx> for ScalarMaybeUndef
78+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
79+
{
80+
type Item = ScalarMaybeUndefSnapshot<'a>;
81+
82+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
83+
match self {
84+
ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.snapshot(ctx)),
85+
ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef,
86+
}
87+
}
88+
}
89+
90+
type MemPlaceSnapshot<'a> = MemPlace<AllocIdSnapshot<'a>>;
91+
92+
impl<'a, Ctx> Snapshot<'a, Ctx> for MemPlace
93+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
94+
{
95+
type Item = MemPlaceSnapshot<'a>;
96+
97+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
98+
let MemPlace{ ptr, extra, align } = self;
99+
100+
MemPlaceSnapshot{
101+
ptr: ptr.snapshot(ctx),
102+
extra: extra.snapshot(ctx),
103+
align: *align,
104+
}
105+
}
106+
}
107+
108+
type PlaceSnapshot<'a> = Place<AllocIdSnapshot<'a>>;
109+
110+
impl<'a, Ctx> Snapshot<'a, Ctx> for Place
111+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
112+
{
113+
type Item = PlaceSnapshot<'a>;
114+
115+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
116+
match self {
117+
Place::Ptr(p) => Place::Ptr(p.snapshot(ctx)),
118+
119+
Place::Local{ frame, local } => Place::Local{
120+
frame: *frame,
121+
local: *local,
122+
},
123+
}
124+
}
125+
}
126+
127+
type PlaceExtraSnapshot<'a> = PlaceExtra<AllocIdSnapshot<'a>>;
128+
129+
impl<'a, Ctx> Snapshot<'a, Ctx> for PlaceExtra
130+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
131+
{
132+
type Item = PlaceExtraSnapshot<'a>;
133+
134+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
135+
match self {
136+
PlaceExtra::Vtable(p) => PlaceExtra::Vtable(p.snapshot(ctx)),
137+
PlaceExtra::Length(l) => PlaceExtra::Length(*l),
138+
PlaceExtra::None => PlaceExtra::None,
139+
}
140+
}
141+
}
142+
143+
type ValueSnapshot<'a> = Value<AllocIdSnapshot<'a>>;
144+
145+
impl<'a, Ctx> Snapshot<'a, Ctx> for Value
146+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
147+
{
148+
type Item = ValueSnapshot<'a>;
149+
150+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
151+
match self {
152+
Value::Scalar(s) => Value::Scalar(s.snapshot(ctx)),
153+
Value::ScalarPair(a, b) => Value::ScalarPair(a.snapshot(ctx), b.snapshot(ctx)),
154+
}
155+
}
156+
}
157+
158+
type OperandSnapshot<'a> = Operand<AllocIdSnapshot<'a>>;
159+
160+
impl<'a, Ctx> Snapshot<'a, Ctx> for Operand
161+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
162+
{
163+
type Item = OperandSnapshot<'a>;
164+
165+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
166+
match self {
167+
Operand::Immediate(v) => Operand::Immediate(v.snapshot(ctx)),
168+
Operand::Indirect(m) => Operand::Indirect(m.snapshot(ctx)),
169+
}
170+
}
171+
}
172+
173+
type LocalValueSnapshot<'a> = LocalValue<AllocIdSnapshot<'a>>;
174+
175+
impl<'a, Ctx> Snapshot<'a, Ctx> for LocalValue
176+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
177+
{
178+
type Item = LocalValueSnapshot<'a>;
179+
180+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
181+
match self {
182+
LocalValue::Live(v) => LocalValue::Live(v.snapshot(ctx)),
183+
LocalValue::Dead => LocalValue::Dead,
184+
}
185+
}
186+
}
187+
188+
type RelocationsSnapshot<'a> = Relocations<AllocIdSnapshot<'a>>;
189+
190+
impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations
191+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
192+
{
193+
type Item = RelocationsSnapshot<'a>;
194+
195+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
196+
Relocations::from_presorted(self.iter().map(|(size, id)| (*size, id.snapshot(ctx))).collect())
197+
}
198+
}
199+
200+
#[derive(Eq, PartialEq)]
201+
struct AllocationSnapshot<'a> {
202+
bytes: &'a [u8],
203+
relocations: RelocationsSnapshot<'a>,
204+
undef_mask: &'a UndefMask,
205+
align: &'a Align,
206+
runtime_mutability: &'a Mutability,
207+
}
208+
209+
impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
210+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
211+
{
212+
type Item = AllocationSnapshot<'a>;
213+
214+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
215+
let Allocation { bytes, relocations, undef_mask, align, runtime_mutability } = self;
216+
217+
AllocationSnapshot {
218+
bytes,
219+
undef_mask,
220+
align,
221+
runtime_mutability,
222+
relocations: relocations.snapshot(ctx),
223+
}
224+
}
225+
}
226+
227+
#[derive(Eq, PartialEq)]
228+
struct FrameSnapshot<'a, 'tcx> {
229+
instance: &'a ty::Instance<'tcx>,
230+
span: &'a Span,
231+
return_to_block: &'a StackPopCleanup,
232+
return_place: PlaceSnapshot<'a>,
233+
locals: IndexVec<mir::Local, LocalValueSnapshot<'a>>,
234+
block: &'a mir::BasicBlock,
235+
stmt: usize,
236+
}
237+
238+
impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
239+
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>,
240+
{
241+
type Item = FrameSnapshot<'a, 'tcx>;
242+
243+
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
244+
let Frame {
245+
mir: _,
246+
instance,
247+
span,
248+
return_to_block,
249+
return_place,
250+
locals,
251+
block,
252+
stmt,
253+
} = self;
254+
255+
FrameSnapshot {
256+
instance,
257+
span,
258+
return_to_block,
259+
block,
260+
stmt: *stmt,
261+
return_place: return_place.snapshot(ctx),
262+
locals: locals.iter().map(|local| local.snapshot(ctx)).collect(),
263+
}
264+
}
265+
}
266+
267+
#[derive(Eq, PartialEq)]
268+
struct MemorySnapshot<'a, 'mir: 'a, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx> + 'a> {
269+
data: &'a M::MemoryData,
270+
}
7271

8272
/// The virtual machine state during const-evaluation at a given point in time.
9273
#[derive(Eq, PartialEq)]

0 commit comments

Comments
 (0)