提交 4eb8d94c 编写于 作者: B Bruno Dutra

Add a convenience macro to reduce code duplication

上级 0a84ff07
...@@ -14,9 +14,7 @@ ...@@ -14,9 +14,7 @@
use super::{Frame, Memory, Machine, Operand, MemPlace, Place, Value}; use super::{Frame, Memory, Machine, Operand, MemPlace, Place, Value};
trait SnapshotContext<'a> { trait SnapshotContext<'a> {
type To; fn resolve(&'a self, id: &AllocId) -> Option<&'a Allocation>;
type From;
fn resolve(&'a self, id: &Self::From) -> Option<&'a Self::To>;
} }
trait Snapshot<'a, Ctx: SnapshotContext<'a>> { trait Snapshot<'a, Ctx: SnapshotContext<'a>> {
...@@ -24,6 +22,52 @@ trait Snapshot<'a, Ctx: SnapshotContext<'a>> { ...@@ -24,6 +22,52 @@ trait Snapshot<'a, Ctx: SnapshotContext<'a>> {
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item;
} }
macro_rules! __impl_snapshot_field {
($field:ident, $ctx:expr) => ($field.snapshot($ctx));
($field:ident, $ctx:expr, $delegate:expr) => ($delegate);
}
macro_rules! impl_snapshot_for {
// FIXME(mark-i-m): Some of these should be `?` rather than `*`.
(enum $enum_name:ident { $( $variant:ident $( ( $($field:ident $(-> $delegate:expr)*),* ) )* ),* $(,)* }) => {
impl<'a, Ctx> self::Snapshot<'a, Ctx> for $enum_name
where Ctx: self::SnapshotContext<'a>,
{
type Item = $enum_name<AllocIdSnapshot<'a>>;
#[inline]
fn snapshot(&self, __ctx: &'a Ctx) -> Self::Item {
match *self {
$(
$enum_name::$variant $( ( $(ref $field),* ) )* =>
$enum_name::$variant $( ( $( __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),* ), )*
)*
}
}
}
};
// FIXME(mark-i-m): same here.
(struct $struct_name:ident { $($field:ident $(-> $delegate:expr)*),* $(,)* }) => {
impl<'a, Ctx> self::Snapshot<'a, Ctx> for $struct_name
where Ctx: self::SnapshotContext<'a>,
{
type Item = $struct_name<AllocIdSnapshot<'a>>;
#[inline]
fn snapshot(&self, __ctx: &'a Ctx) -> Self::Item {
let $struct_name {
$(ref $field),*
} = *self;
$struct_name {
$( $field: __impl_snapshot_field!($field, __ctx $(, $delegate)*) ),*
}
}
}
};
}
impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option<T> impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option<T>
where Ctx: SnapshotContext<'a>, where Ctx: SnapshotContext<'a>,
T: Snapshot<'a, Ctx> T: Snapshot<'a, Ctx>
...@@ -42,7 +86,7 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { ...@@ -42,7 +86,7 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
struct AllocIdSnapshot<'a>(Option<AllocationSnapshot<'a>>); struct AllocIdSnapshot<'a>(Option<AllocationSnapshot<'a>>);
impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = AllocIdSnapshot<'a>; type Item = AllocIdSnapshot<'a>;
...@@ -51,34 +95,20 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { ...@@ -51,34 +95,20 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
} }
} }
type PointerSnapshot<'a> = Pointer<AllocIdSnapshot<'a>>; impl_snapshot_for!(struct Pointer {
alloc_id,
impl<'a, Ctx> Snapshot<'a, Ctx> for Pointer offset -> *offset,
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 impl<'a, Ctx> Snapshot<'a, Ctx> for Scalar
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = ScalarSnapshot<'a>; type Item = Scalar<AllocIdSnapshot<'a>>;
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
match self { match self {
Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)), Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)),
Scalar::Bits{ size, bits } => Scalar::Bits{ Scalar::Bits{ size, bits } => Scalar::Bits {
size: *size, size: *size,
bits: *bits, bits: *bits,
}, },
...@@ -86,45 +116,21 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { ...@@ -86,45 +116,21 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
} }
} }
type ScalarMaybeUndefSnapshot<'a> = ScalarMaybeUndef<AllocIdSnapshot<'a>>; impl_snapshot_for!(enum ScalarMaybeUndef {
Scalar(s),
impl<'a, Ctx> Snapshot<'a, Ctx> for ScalarMaybeUndef Undef,
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 { impl_snapshot_for!(struct MemPlace {
let MemPlace{ ptr, extra, align } = self; ptr,
extra,
MemPlaceSnapshot{ align -> *align,
ptr: ptr.snapshot(ctx), });
extra: extra.snapshot(ctx),
align: *align,
}
}
}
type PlaceSnapshot<'a> = Place<AllocIdSnapshot<'a>>;
impl<'a, Ctx> Snapshot<'a, Ctx> for Place impl<'a, Ctx> Snapshot<'a, Ctx> for Place
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = PlaceSnapshot<'a>; type Item = Place<AllocIdSnapshot<'a>>;
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
match self { match self {
...@@ -138,57 +144,25 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { ...@@ -138,57 +144,25 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
} }
} }
type ValueSnapshot<'a> = Value<AllocIdSnapshot<'a>>; impl_snapshot_for!(enum Value {
Scalar(s),
impl<'a, Ctx> Snapshot<'a, Ctx> for Value ScalarPair(s, t),
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_snapshot_for!(enum Operand {
Immediate(v),
Indirect(m),
});
impl<'a, Ctx> Snapshot<'a, Ctx> for Operand impl_snapshot_for!(enum LocalValue {
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, Live(v),
{ Dead,
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 impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = RelocationsSnapshot<'a>; type Item = Relocations<AllocIdSnapshot<'a>>;
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
Relocations::from_presorted(self.iter().map(|(size, id)| (*size, id.snapshot(ctx))).collect()) Relocations::from_presorted(self.iter().map(|(size, id)| (*size, id.snapshot(ctx))).collect())
...@@ -198,14 +172,14 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { ...@@ -198,14 +172,14 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq)]
struct AllocationSnapshot<'a> { struct AllocationSnapshot<'a> {
bytes: &'a [u8], bytes: &'a [u8],
relocations: RelocationsSnapshot<'a>, relocations: Relocations<AllocIdSnapshot<'a>>,
undef_mask: &'a UndefMask, undef_mask: &'a UndefMask,
align: &'a Align, align: &'a Align,
mutability: &'a Mutability, mutability: &'a Mutability,
} }
impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = AllocationSnapshot<'a>; type Item = AllocationSnapshot<'a>;
...@@ -227,14 +201,14 @@ struct FrameSnapshot<'a, 'tcx: 'a> { ...@@ -227,14 +201,14 @@ struct FrameSnapshot<'a, 'tcx: 'a> {
instance: &'a ty::Instance<'tcx>, instance: &'a ty::Instance<'tcx>,
span: &'a Span, span: &'a Span,
return_to_block: &'a StackPopCleanup, return_to_block: &'a StackPopCleanup,
return_place: PlaceSnapshot<'a>, return_place: Place<AllocIdSnapshot<'a>>,
locals: IndexVec<mir::Local, LocalValueSnapshot<'a>>, locals: IndexVec<mir::Local, LocalValue<AllocIdSnapshot<'a>>>,
block: &'a mir::BasicBlock, block: &'a mir::BasicBlock,
stmt: usize, stmt: usize,
} }
impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
where Ctx: SnapshotContext<'a, To=Allocation, From=AllocId>, where Ctx: SnapshotContext<'a>,
{ {
type Item = FrameSnapshot<'a, 'tcx>; type Item = FrameSnapshot<'a, 'tcx>;
...@@ -279,9 +253,7 @@ fn snapshot<'b: 'a>(&'b self) -> MemorySnapshot<'b, 'mir, 'tcx, M> { ...@@ -279,9 +253,7 @@ fn snapshot<'b: 'a>(&'b self) -> MemorySnapshot<'b, 'mir, 'tcx, M> {
impl<'a, 'b, 'mir, 'tcx, M> SnapshotContext<'b> for Memory<'a, 'mir, 'tcx, M> impl<'a, 'b, 'mir, 'tcx, M> SnapshotContext<'b> for Memory<'a, 'mir, 'tcx, M>
where M: Machine<'mir, 'tcx>, where M: Machine<'mir, 'tcx>,
{ {
type To = Allocation; fn resolve(&'b self, id: &AllocId) -> Option<&'b Allocation> {
type From = AllocId;
fn resolve(&'b self, id: &Self::From) -> Option<&'b Self::To> {
self.get(*id).ok() self.get(*id).ok()
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册