interpret: rename Tag/PointerTag to Prov/Provenance
Let's avoid using two different terms for the same thing -- let's just call it "provenance" everywhere. In Miri, provenance consists of an AllocId and an SbTag (Stacked Borrows tag), which made this even more confusing.
This commit is contained in:
parent
29c5a028b0
commit
0ec3269db8
24 changed files with 606 additions and 601 deletions
|
@ -85,11 +85,11 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
type MemoryKind: Debug + std::fmt::Display + MayLeak + Eq + 'static;
|
||||
|
||||
/// Pointers are "tagged" with provenance information; typically the `AllocId` they belong to.
|
||||
type PointerTag: Provenance + Eq + Hash + 'static;
|
||||
type Provenance: Provenance + Eq + Hash + 'static;
|
||||
|
||||
/// When getting the AllocId of a pointer, some extra data is also obtained from the tag
|
||||
/// When getting the AllocId of a pointer, some extra data is also obtained from the provenance
|
||||
/// that is passed to memory access hooks so they can do things with it.
|
||||
type TagExtra: Copy + 'static;
|
||||
type ProvenanceExtra: Copy + 'static;
|
||||
|
||||
/// Machines can define extra (non-instance) things that represent values of function pointers.
|
||||
/// For example, Miri uses this to return a function pointer from `dlsym`
|
||||
|
@ -105,7 +105,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// Memory's allocation map
|
||||
type MemoryMap: AllocMap<
|
||||
AllocId,
|
||||
(MemoryKind<Self::MemoryKind>, Allocation<Self::PointerTag, Self::AllocExtra>),
|
||||
(MemoryKind<Self::MemoryKind>, Allocation<Self::Provenance, Self::AllocExtra>),
|
||||
> + Default
|
||||
+ Clone;
|
||||
|
||||
|
@ -113,7 +113,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// or None if such memory should not be mutated and thus any such attempt will cause
|
||||
/// a `ModifiedStatic` error to be raised.
|
||||
/// Statics are copied under two circumstances: When they are mutated, and when
|
||||
/// `tag_allocation` (see below) returns an owned allocation
|
||||
/// `adjust_allocation` (see below) returns an owned allocation
|
||||
/// that is added to the memory so that the work is not done twice.
|
||||
const GLOBAL_KIND: Option<Self::MemoryKind>;
|
||||
|
||||
|
@ -126,7 +126,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// Whether, when checking alignment, we should `force_int` and thus support
|
||||
/// custom alignment logic based on whatever the integer address happens to be.
|
||||
///
|
||||
/// Requires PointerTag::OFFSET_IS_ADDR to be true.
|
||||
/// Requires Provenance::OFFSET_IS_ADDR to be true.
|
||||
fn force_int_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
||||
|
||||
/// Whether to enforce the validity invariant
|
||||
|
@ -170,8 +170,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
abi: CallAbi,
|
||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
||||
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
||||
args: &[OpTy<'tcx, Self::Provenance>],
|
||||
destination: &PlaceTy<'tcx, Self::Provenance>,
|
||||
target: Option<mir::BasicBlock>,
|
||||
unwind: StackPopUnwind,
|
||||
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>;
|
||||
|
@ -182,8 +182,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
fn_val: Self::ExtraFnVal,
|
||||
abi: CallAbi,
|
||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
||||
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
||||
args: &[OpTy<'tcx, Self::Provenance>],
|
||||
destination: &PlaceTy<'tcx, Self::Provenance>,
|
||||
target: Option<mir::BasicBlock>,
|
||||
unwind: StackPopUnwind,
|
||||
) -> InterpResult<'tcx>;
|
||||
|
@ -193,8 +193,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn call_intrinsic(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
||||
destination: &PlaceTy<'tcx, Self::PointerTag>,
|
||||
args: &[OpTy<'tcx, Self::Provenance>],
|
||||
destination: &PlaceTy<'tcx, Self::Provenance>,
|
||||
target: Option<mir::BasicBlock>,
|
||||
unwind: StackPopUnwind,
|
||||
) -> InterpResult<'tcx>;
|
||||
|
@ -217,18 +217,18 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn binary_ptr_op(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx, Self::PointerTag>,
|
||||
right: &ImmTy<'tcx, Self::PointerTag>,
|
||||
) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool, Ty<'tcx>)>;
|
||||
left: &ImmTy<'tcx, Self::Provenance>,
|
||||
right: &ImmTy<'tcx, Self::Provenance>,
|
||||
) -> InterpResult<'tcx, (Scalar<Self::Provenance>, bool, Ty<'tcx>)>;
|
||||
|
||||
/// Called to read the specified `local` from the `frame`.
|
||||
/// Since reading a ZST is not actually accessing memory or locals, this is never invoked
|
||||
/// for ZST reads.
|
||||
#[inline]
|
||||
fn access_local<'a>(
|
||||
frame: &'a Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>,
|
||||
frame: &'a Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
|
||||
local: mir::Local,
|
||||
) -> InterpResult<'tcx, &'a Operand<Self::PointerTag>>
|
||||
) -> InterpResult<'tcx, &'a Operand<Self::Provenance>>
|
||||
where
|
||||
'tcx: 'mir,
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
|
||||
frame: usize,
|
||||
local: mir::Local,
|
||||
) -> InterpResult<'tcx, &'a mut Operand<Self::PointerTag>>
|
||||
) -> InterpResult<'tcx, &'a mut Operand<Self::Provenance>>
|
||||
where
|
||||
'tcx: 'mir,
|
||||
{
|
||||
|
@ -275,7 +275,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn thread_local_static_base_pointer(
|
||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
|
||||
throw_unsup!(ThreadLocalStatic(def_id))
|
||||
}
|
||||
|
||||
|
@ -283,35 +283,35 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn extern_static_base_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Self::PointerTag>>;
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// Return a "base" pointer for the given allocation: the one that is used for direct
|
||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||
///
|
||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||
fn tag_alloc_base_pointer(
|
||||
fn adjust_alloc_base_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
) -> Pointer<Self::PointerTag>;
|
||||
) -> Pointer<Self::Provenance>;
|
||||
|
||||
/// "Int-to-pointer cast"
|
||||
fn ptr_from_addr_cast(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
addr: u64,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Self::PointerTag>>>;
|
||||
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>>;
|
||||
|
||||
/// Hook for returning a pointer from a transmute-like operation on an addr.
|
||||
/// This is only needed to support Miri's (unsound) "allow-ptr-int-transmute" flag.
|
||||
fn ptr_from_addr_transmute(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
addr: u64,
|
||||
) -> Pointer<Option<Self::PointerTag>>;
|
||||
) -> Pointer<Option<Self::Provenance>>;
|
||||
|
||||
/// Marks a pointer as exposed, allowing it's provenance
|
||||
/// to be recovered. "Pointer-to-int cast"
|
||||
fn expose_ptr(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
ptr: Pointer<Self::Provenance>,
|
||||
) -> InterpResult<'tcx>;
|
||||
|
||||
/// Convert a pointer with provenance into an allocation-offset pair
|
||||
|
@ -322,30 +322,30 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// When this fails, that means the pointer does not point to a live allocation.
|
||||
fn ptr_get_alloc(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
) -> Option<(AllocId, Size, Self::TagExtra)>;
|
||||
ptr: Pointer<Self::Provenance>,
|
||||
) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
|
||||
|
||||
/// Called to initialize the "extra" state of an allocation and make the pointers
|
||||
/// it contains (in relocations) tagged. The way we construct allocations is
|
||||
/// to always first construct it without extra and then add the extra.
|
||||
/// This keeps uniform code paths for handling both allocations created by CTFE
|
||||
/// for globals, and allocations created by Miri during evaluation.
|
||||
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
|
||||
///
|
||||
/// `kind` is the kind of the allocation being tagged; it can be `None` when
|
||||
/// The way we construct allocations is to always first construct it without extra and then add
|
||||
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
|
||||
/// globals, and allocations created by Miri during evaluation.
|
||||
///
|
||||
/// `kind` is the kind of the allocation being adjusted; it can be `None` when
|
||||
/// it's a global and `GLOBAL_KIND` is `None`.
|
||||
///
|
||||
/// This should avoid copying if no work has to be done! If this returns an owned
|
||||
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
|
||||
/// allocation (because a copy had to be done to adjust things), machine memory will
|
||||
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
|
||||
/// owned allocation to the map even when the map is shared.)
|
||||
///
|
||||
/// This must only fail if `alloc` contains relocations.
|
||||
fn init_allocation_extra<'b>(
|
||||
fn adjust_allocation<'b>(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
id: AllocId,
|
||||
alloc: Cow<'b, Allocation>,
|
||||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>>;
|
||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>>;
|
||||
|
||||
/// Hook for performing extra checks on a memory read access.
|
||||
///
|
||||
|
@ -357,7 +357,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
_tcx: TyCtxt<'tcx>,
|
||||
_machine: &Self,
|
||||
_alloc_extra: &Self::AllocExtra,
|
||||
_tag: (AllocId, Self::TagExtra),
|
||||
_prov: (AllocId, Self::ProvenanceExtra),
|
||||
_range: AllocRange,
|
||||
) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
|
@ -369,7 +369,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
_tcx: TyCtxt<'tcx>,
|
||||
_machine: &mut Self,
|
||||
_alloc_extra: &mut Self::AllocExtra,
|
||||
_tag: (AllocId, Self::TagExtra),
|
||||
_prov: (AllocId, Self::ProvenanceExtra),
|
||||
_range: AllocRange,
|
||||
) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
|
@ -381,7 +381,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
_tcx: TyCtxt<'tcx>,
|
||||
_machine: &mut Self,
|
||||
_alloc_extra: &mut Self::AllocExtra,
|
||||
_tag: (AllocId, Self::TagExtra),
|
||||
_prov: (AllocId, Self::ProvenanceExtra),
|
||||
_range: AllocRange,
|
||||
) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
|
@ -392,7 +392,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn retag(
|
||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
_kind: mir::RetagKind,
|
||||
_place: &PlaceTy<'tcx, Self::PointerTag>,
|
||||
_place: &PlaceTy<'tcx, Self::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -400,18 +400,18 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// Called immediately before a new stack frame gets pushed.
|
||||
fn init_frame_extra(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
frame: Frame<'mir, 'tcx, Self::PointerTag>,
|
||||
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;
|
||||
frame: Frame<'mir, 'tcx, Self::Provenance>,
|
||||
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>>;
|
||||
|
||||
/// Borrow the current thread's stack.
|
||||
fn stack<'a>(
|
||||
ecx: &'a InterpCx<'mir, 'tcx, Self>,
|
||||
) -> &'a [Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>];
|
||||
) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>];
|
||||
|
||||
/// Mutably borrow the current thread's stack.
|
||||
fn stack_mut<'a>(
|
||||
ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
|
||||
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;
|
||||
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>>;
|
||||
|
||||
/// Called immediately after a stack frame got pushed and its locals got initialized.
|
||||
fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
|
||||
|
@ -422,7 +422,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
/// The `locals` have already been destroyed!
|
||||
fn after_stack_pop(
|
||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
_frame: Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>,
|
||||
_frame: Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
|
||||
unwinding: bool,
|
||||
) -> InterpResult<'tcx, StackPopJump> {
|
||||
// By default, we do not support unwinding from panics
|
||||
|
@ -434,8 +434,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
|
||||
// (CTFE and ConstProp) use the same instance. Here, we share that code.
|
||||
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||
type PointerTag = AllocId;
|
||||
type TagExtra = ();
|
||||
type Provenance = AllocId;
|
||||
type ProvenanceExtra = ();
|
||||
|
||||
type ExtraFnVal = !;
|
||||
|
||||
|
@ -485,7 +485,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
fn_val: !,
|
||||
_abi: CallAbi,
|
||||
_args: &[OpTy<$tcx>],
|
||||
_destination: &PlaceTy<$tcx, Self::PointerTag>,
|
||||
_destination: &PlaceTy<$tcx, Self::Provenance>,
|
||||
_target: Option<mir::BasicBlock>,
|
||||
_unwind: StackPopUnwind,
|
||||
) -> InterpResult<$tcx> {
|
||||
|
@ -493,13 +493,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn init_allocation_extra<'b>(
|
||||
fn adjust_allocation<'b>(
|
||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
_id: AllocId,
|
||||
alloc: Cow<'b, Allocation>,
|
||||
_kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<$tcx, Cow<'b, Allocation<Self::PointerTag>>> {
|
||||
// We do not use a tag so we can just cheaply forward the allocation
|
||||
) -> InterpResult<$tcx, Cow<'b, Allocation<Self::Provenance>>> {
|
||||
Ok(alloc)
|
||||
}
|
||||
|
||||
|
@ -512,7 +511,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn tag_alloc_base_pointer(
|
||||
fn adjust_alloc_base_pointer(
|
||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
ptr: Pointer<AllocId>,
|
||||
) -> Pointer<AllocId> {
|
||||
|
@ -541,7 +540,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
fn ptr_get_alloc(
|
||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
ptr: Pointer<AllocId>,
|
||||
) -> Option<(AllocId, Size, Self::TagExtra)> {
|
||||
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
|
||||
// We know `offset` is relative to the allocation, so we can use `into_parts`.
|
||||
let (alloc_id, offset) = ptr.into_parts();
|
||||
Some((alloc_id, offset, ()))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue