make (de)reference hooks more consistent
This commit is contained in:
parent
1982f1887a
commit
048900c5b6
@ -472,7 +472,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
|||||||
_ptr: Pointer<Self::PointerTag>,
|
_ptr: Pointer<Self::PointerTag>,
|
||||||
_pointee_ty: Ty<'tcx>,
|
_pointee_ty: Ty<'tcx>,
|
||||||
_pointee_size: Size,
|
_pointee_size: Size,
|
||||||
_borrow_kind: Option<mir::BorrowKind>,
|
_borrow_kind: Option<hir::Mutability>,
|
||||||
) -> EvalResult<'tcx, Self::PointerTag> {
|
) -> EvalResult<'tcx, Self::PointerTag> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -481,7 +481,9 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
|||||||
fn tag_dereference(
|
fn tag_dereference(
|
||||||
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
||||||
_ptr: Pointer<Self::PointerTag>,
|
_ptr: Pointer<Self::PointerTag>,
|
||||||
_ptr_ty: Ty<'tcx>,
|
_pointee_ty: Ty<'tcx>,
|
||||||
|
_pointee_size: Size,
|
||||||
|
_borrow_kind: Option<hir::Mutability>,
|
||||||
) -> EvalResult<'tcx, Self::PointerTag> {
|
) -> EvalResult<'tcx, Self::PointerTag> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::{self, def_id::DefId};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
|
use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
|
||||||
|
|
||||||
@ -206,21 +206,24 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
|
|||||||
|
|
||||||
/// Executed when evaluating the `&` operator: Creating a new reference.
|
/// Executed when evaluating the `&` operator: Creating a new reference.
|
||||||
/// This has the chance to adjust the tag.
|
/// This has the chance to adjust the tag.
|
||||||
/// `borrow_kind` can be `None` in case a raw ptr is being created.
|
/// `mutability` can be `None` in case a raw ptr is being created.
|
||||||
fn tag_reference(
|
fn tag_reference(
|
||||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||||
ptr: Pointer<Self::PointerTag>,
|
ptr: Pointer<Self::PointerTag>,
|
||||||
pointee_ty: Ty<'tcx>,
|
pointee_ty: Ty<'tcx>,
|
||||||
pointee_size: Size,
|
pointee_size: Size,
|
||||||
borrow_kind: Option<mir::BorrowKind>,
|
mutability: Option<hir::Mutability>,
|
||||||
) -> EvalResult<'tcx, Self::PointerTag>;
|
) -> EvalResult<'tcx, Self::PointerTag>;
|
||||||
|
|
||||||
/// Executed when evaluating the `*` operator: Following a reference.
|
/// Executed when evaluating the `*` operator: Following a reference.
|
||||||
/// This has the change to adjust the tag.
|
/// This has the change to adjust the tag.
|
||||||
|
/// `mutability` can be `None` in case a raw ptr is being dereferenced.
|
||||||
fn tag_dereference(
|
fn tag_dereference(
|
||||||
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
||||||
ptr: Pointer<Self::PointerTag>,
|
ptr: Pointer<Self::PointerTag>,
|
||||||
ptr_ty: Ty<'tcx>,
|
pointee_ty: Ty<'tcx>,
|
||||||
|
pointee_size: Size,
|
||||||
|
mutability: Option<hir::Mutability>,
|
||||||
) -> EvalResult<'tcx, Self::PointerTag>;
|
) -> EvalResult<'tcx, Self::PointerTag>;
|
||||||
|
|
||||||
/// Execute a validation operation
|
/// Execute a validation operation
|
||||||
|
@ -217,6 +217,16 @@ impl<'tcx, Tag> Value<Tag> {
|
|||||||
Value::ScalarPair(ptr, _) => ptr.not_undef(),
|
Value::ScalarPair(ptr, _) => ptr.not_undef(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the value into its metadata.
|
||||||
|
/// Throws away the first half of a ScalarPair!
|
||||||
|
#[inline]
|
||||||
|
pub fn to_meta(self) -> EvalResult<'tcx, Option<Scalar<Tag>>> {
|
||||||
|
Ok(match self {
|
||||||
|
Value::Scalar(_) => None,
|
||||||
|
Value::ScalarPair(_, meta) => Some(meta.not_undef()?),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScalarPair needs a type to interpret, so we often have a value and a type together
|
// ScalarPair needs a type to interpret, so we often have a value and a type together
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use rustc::hir;
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout};
|
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout};
|
||||||
@ -270,26 +271,31 @@ where
|
|||||||
&self,
|
&self,
|
||||||
val: ValTy<'tcx, M::PointerTag>,
|
val: ValTy<'tcx, M::PointerTag>,
|
||||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
|
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
||||||
|
let layout = self.layout_of(pointee_type)?;
|
||||||
|
|
||||||
|
let align = layout.align;
|
||||||
|
let meta = val.to_meta()?;
|
||||||
|
|
||||||
let ptr = match val.to_scalar_ptr()? {
|
let ptr = match val.to_scalar_ptr()? {
|
||||||
Scalar::Ptr(ptr) if M::ENABLE_PTR_TRACKING_HOOKS => {
|
Scalar::Ptr(ptr) if M::ENABLE_PTR_TRACKING_HOOKS => {
|
||||||
// Machine might want to track the `*` operator
|
// Machine might want to track the `*` operator
|
||||||
let tag = M::tag_dereference(self, ptr, val.layout.ty)?;
|
let (size, _) = self.size_and_align_of(meta, layout)?
|
||||||
|
.expect("ref_to_mplace cannot determine size");
|
||||||
|
let mutbl = match val.layout.ty.sty {
|
||||||
|
// `builtin_deref` considers boxes immutable, that's useless for our purposes
|
||||||
|
ty::Ref(_, _, mutbl) => Some(mutbl),
|
||||||
|
ty::Adt(def, _) if def.is_box() => Some(hir::MutMutable),
|
||||||
|
ty::RawPtr(_) => None,
|
||||||
|
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
|
||||||
|
};
|
||||||
|
let tag = M::tag_dereference(self, ptr, pointee_type, size, mutbl)?;
|
||||||
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
||||||
}
|
}
|
||||||
other => other,
|
other => other,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
Ok(MPlaceTy { mplace: MemPlace { ptr, align, meta }, layout })
|
||||||
let layout = self.layout_of(pointee_type)?;
|
|
||||||
let align = layout.align;
|
|
||||||
|
|
||||||
let mplace = match *val {
|
|
||||||
Value::Scalar(_) =>
|
|
||||||
MemPlace { ptr, align, meta: None },
|
|
||||||
Value::ScalarPair(_, meta) =>
|
|
||||||
MemPlace { ptr, align, meta: Some(meta.not_undef()?) },
|
|
||||||
};
|
|
||||||
Ok(MPlaceTy { mplace, layout })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
|
/// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
|
||||||
@ -304,7 +310,12 @@ where
|
|||||||
// Machine might want to track the `&` operator
|
// Machine might want to track the `&` operator
|
||||||
let (size, _) = self.size_and_align_of_mplace(place)?
|
let (size, _) = self.size_and_align_of_mplace(place)?
|
||||||
.expect("create_ref cannot determine size");
|
.expect("create_ref cannot determine size");
|
||||||
let tag = M::tag_reference(self, ptr, place.layout.ty, size, borrow_kind)?;
|
let mutbl = match borrow_kind {
|
||||||
|
Some(mir::BorrowKind::Mut { .. }) => Some(hir::MutMutable),
|
||||||
|
Some(_) => Some(hir::MutImmutable),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
let tag = M::tag_reference(self, ptr, place.layout.ty, size, mutbl)?;
|
||||||
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
||||||
},
|
},
|
||||||
other => other,
|
other => other,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user