also hook dereferencing
This commit is contained in:
parent
5f20b16934
commit
d61db93c15
3 changed files with 49 additions and 19 deletions
|
@ -19,8 +19,8 @@ use std::collections::hash_map::Entry;
|
|||
use rustc::hir::{self, def_id::DefId};
|
||||
use rustc::mir::interpret::ConstEvalErr;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
|
||||
use rustc::ty::layout::{self, LayoutOf, TyLayout};
|
||||
use rustc::ty::{self, Ty, TyCtxt, Instance, query::TyCtxtAt};
|
||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -28,13 +28,10 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use syntax::ast::Mutability;
|
||||
use syntax::source_map::{Span, DUMMY_SP};
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
EvalResult, EvalError, EvalErrorKind, GlobalId,
|
||||
Scalar, Allocation, AllocId, ConstValue,
|
||||
};
|
||||
use interpret::{self,
|
||||
PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Value,
|
||||
EvalContext, StackPopCleanup, MemoryKind,
|
||||
PlaceTy, MemPlace, OpTy, Operand, Value, Pointer, Scalar, ConstValue,
|
||||
EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup,
|
||||
Allocation, AllocId, MemoryKind,
|
||||
snapshot,
|
||||
};
|
||||
|
||||
|
@ -468,11 +465,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
|||
#[inline(always)]
|
||||
fn tag_reference(
|
||||
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
_place: MPlaceTy<'tcx, Self::PointerTag>,
|
||||
_ptr: Pointer<Self::PointerTag>,
|
||||
_pointee_ty: Ty<'tcx>,
|
||||
_pointee_size: Size,
|
||||
_borrow_kind: mir::BorrowKind,
|
||||
) -> EvalResult<'tcx, Self::PointerTag> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn tag_dereference(
|
||||
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
_ptr: Pointer<Self::PointerTag>,
|
||||
_ptr_ty: Ty<'tcx>,
|
||||
) -> EvalResult<'tcx, Self::PointerTag> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Project to a field of a (variant of a) const
|
||||
|
|
|
@ -17,11 +17,11 @@ use std::hash::Hash;
|
|||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, layout::{Size, TyLayout}, query::TyCtxtAt};
|
||||
use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
|
||||
|
||||
use super::{
|
||||
Allocation, AllocId, EvalResult, Scalar,
|
||||
EvalContext, PlaceTy, OpTy, MPlaceTy, Pointer, MemoryKind,
|
||||
EvalContext, PlaceTy, OpTy, Pointer, MemoryKind,
|
||||
};
|
||||
|
||||
/// Classifying memory accesses
|
||||
|
@ -199,14 +199,23 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
|
|||
}
|
||||
|
||||
/// Executed when evaluating the `&` operator: Creating a new reference.
|
||||
/// This has the chance to adjust the tag. It is only ever called if the
|
||||
/// pointer in `place` is really a pointer, not another scalar.
|
||||
/// This has the chance to adjust the tag.
|
||||
fn tag_reference(
|
||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
place: MPlaceTy<'tcx, Self::PointerTag>,
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
pointee_ty: Ty<'tcx>,
|
||||
pointee_size: Size,
|
||||
borrow_kind: mir::BorrowKind,
|
||||
) -> EvalResult<'tcx, Self::PointerTag>;
|
||||
|
||||
/// Executed when evaluating the `*` operator: Following a reference.
|
||||
/// This has the change to adjust the tag.
|
||||
fn tag_dereference(
|
||||
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
ptr_ty: Ty<'tcx>,
|
||||
) -> EvalResult<'tcx, Self::PointerTag>;
|
||||
|
||||
/// Execute a validation operation
|
||||
#[inline]
|
||||
fn validation_op(
|
||||
|
|
|
@ -264,14 +264,24 @@ where
|
|||
&self,
|
||||
val: ValTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let ptr = match val.to_scalar_ptr()? {
|
||||
Scalar::Ptr(ptr) => {
|
||||
// Machine might want to track the `*` operator
|
||||
let tag = M::tag_dereference(self, ptr, val.layout.ty)?;
|
||||
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
||||
}
|
||||
scalar @ Scalar::Bits { .. } => scalar,
|
||||
};
|
||||
|
||||
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
let layout = self.layout_of(pointee_type)?;
|
||||
let align = layout.align;
|
||||
|
||||
let mplace = match *val {
|
||||
Value::Scalar(ptr) =>
|
||||
MemPlace { ptr: ptr.not_undef()?, align, meta: None },
|
||||
Value::ScalarPair(ptr, meta) =>
|
||||
MemPlace { ptr: ptr.not_undef()?, align, meta: Some(meta.not_undef()?) },
|
||||
Value::Scalar(_) =>
|
||||
MemPlace { ptr, align, meta: None },
|
||||
Value::ScalarPair(_, meta) =>
|
||||
MemPlace { ptr, align, meta: Some(meta.not_undef()?) },
|
||||
};
|
||||
Ok(MPlaceTy { mplace, layout })
|
||||
}
|
||||
|
@ -285,7 +295,10 @@ where
|
|||
) -> EvalResult<'tcx, Value<M::PointerTag>> {
|
||||
let ptr = match place.ptr {
|
||||
Scalar::Ptr(ptr) => {
|
||||
let tag = M::tag_reference(self, place, borrow_kind)?;
|
||||
// Machine might want to track the `&` operator
|
||||
let (size, _) = self.size_and_align_of_mplace(place)?
|
||||
.expect("create_ref cannot determine size");
|
||||
let tag = M::tag_reference(self, ptr, place.layout.ty, size, borrow_kind)?;
|
||||
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
|
||||
},
|
||||
scalar @ Scalar::Bits { .. } => scalar,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue