Eliminate the Pointer
wrapper type
This commit is contained in:
parent
6436de89fe
commit
03a92b61ec
@ -473,8 +473,6 @@ impl_stable_hash_for!(enum ::syntax::ast::Mutability {
|
||||
Mutable
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct mir::interpret::Pointer{primval});
|
||||
|
||||
impl_stable_hash_for!(enum mir::interpret::Scalar {
|
||||
Bytes(b),
|
||||
Ptr(p),
|
||||
|
@ -10,7 +10,7 @@ mod value;
|
||||
|
||||
pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
|
||||
|
||||
pub use self::value::{Scalar, ScalarKind, Value, Pointer, ConstValue};
|
||||
pub use self::value::{Scalar, ScalarKind, Value, ConstValue};
|
||||
|
||||
use std::fmt;
|
||||
use mir;
|
||||
|
@ -78,7 +78,7 @@ impl<'tcx> ConstValue<'tcx> {
|
||||
/// operations and fat pointers. This idea was taken from rustc's codegen.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub enum Value {
|
||||
ByRef(Pointer, Align),
|
||||
ByRef(Scalar, Align),
|
||||
Scalar(Scalar),
|
||||
ScalarPair(Scalar, Scalar),
|
||||
}
|
||||
@ -92,73 +92,49 @@ impl<'tcx> ty::TypeFoldable<'tcx> for Value {
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper type around `Scalar` that cannot be turned back into a `Scalar` accidentally.
|
||||
/// This type clears up a few APIs where having a `Scalar` argument for something that is
|
||||
/// potentially an integer pointer or a pointer to an allocation was unclear.
|
||||
///
|
||||
/// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
|
||||
/// the representation of pointers. Also all the sites that convert between primvals and pointers
|
||||
/// are explicit now (and rare!)
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
|
||||
pub struct Pointer {
|
||||
pub primval: Scalar,
|
||||
}
|
||||
|
||||
impl<'tcx> Pointer {
|
||||
pub fn null() -> Self {
|
||||
Scalar::Bytes(0).into()
|
||||
}
|
||||
pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
|
||||
self.primval.to_ptr()
|
||||
}
|
||||
pub fn into_inner_primval(self) -> Scalar {
|
||||
self.primval
|
||||
impl<'tcx> Scalar {
|
||||
pub fn ptr_null() -> Self {
|
||||
Scalar::Bytes(0)
|
||||
}
|
||||
|
||||
pub fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
|
||||
pub fn ptr_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
|
||||
let layout = cx.data_layout();
|
||||
match self.primval {
|
||||
match self {
|
||||
Scalar::Bytes(b) => {
|
||||
assert_eq!(b as u64 as u128, b);
|
||||
Ok(Pointer::from(
|
||||
Scalar::Bytes(layout.signed_offset(b as u64, i)? as u128),
|
||||
))
|
||||
Ok(Scalar::Bytes(layout.signed_offset(b as u64, i)? as u128))
|
||||
}
|
||||
Scalar::Ptr(ptr) => ptr.signed_offset(i, layout).map(Pointer::from),
|
||||
Scalar::Ptr(ptr) => ptr.signed_offset(i, layout).map(Scalar::Ptr),
|
||||
Scalar::Undef => err!(ReadUndefBytes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
|
||||
pub fn ptr_offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
|
||||
let layout = cx.data_layout();
|
||||
match self.primval {
|
||||
match self {
|
||||
Scalar::Bytes(b) => {
|
||||
assert_eq!(b as u64 as u128, b);
|
||||
Ok(Pointer::from(
|
||||
Scalar::Bytes(layout.offset(b as u64, i.bytes())? as u128),
|
||||
))
|
||||
Ok(Scalar::Bytes(layout.offset(b as u64, i.bytes())? as u128))
|
||||
}
|
||||
Scalar::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
|
||||
Scalar::Ptr(ptr) => ptr.offset(i, layout).map(Scalar::Ptr),
|
||||
Scalar::Undef => err!(ReadUndefBytes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
|
||||
pub fn ptr_wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
|
||||
let layout = cx.data_layout();
|
||||
match self.primval {
|
||||
match self {
|
||||
Scalar::Bytes(b) => {
|
||||
assert_eq!(b as u64 as u128, b);
|
||||
Ok(Pointer::from(Scalar::Bytes(
|
||||
layout.wrapping_signed_offset(b as u64, i) as u128,
|
||||
)))
|
||||
Ok(Scalar::Bytes(layout.wrapping_signed_offset(b as u64, i) as u128))
|
||||
}
|
||||
Scalar::Ptr(ptr) => Ok(Pointer::from(ptr.wrapping_signed_offset(i, layout))),
|
||||
Scalar::Ptr(ptr) => Ok(Scalar::Ptr(ptr.wrapping_signed_offset(i, layout))),
|
||||
Scalar::Undef => err!(ReadUndefBytes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_null(self) -> EvalResult<'tcx, bool> {
|
||||
match self.primval {
|
||||
match self {
|
||||
Scalar::Bytes(b) => Ok(b == 0),
|
||||
Scalar::Ptr(_) => Ok(false),
|
||||
Scalar::Undef => err!(ReadUndefBytes),
|
||||
@ -166,27 +142,21 @@ impl<'tcx> Pointer {
|
||||
}
|
||||
|
||||
pub fn to_value_with_len(self, len: u64) -> Value {
|
||||
Value::ScalarPair(self.primval, Scalar::from_u128(len as u128))
|
||||
Value::ScalarPair(self, Scalar::from_u128(len as u128))
|
||||
}
|
||||
|
||||
pub fn to_value_with_vtable(self, vtable: MemoryPointer) -> Value {
|
||||
Value::ScalarPair(self.primval, Scalar::Ptr(vtable))
|
||||
Value::ScalarPair(self, Scalar::Ptr(vtable))
|
||||
}
|
||||
|
||||
pub fn to_value(self) -> Value {
|
||||
Value::Scalar(self.primval)
|
||||
Value::Scalar(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<Scalar> for Pointer {
|
||||
fn from(primval: Scalar) -> Self {
|
||||
Pointer { primval }
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<MemoryPointer> for Pointer {
|
||||
impl From<MemoryPointer> for Scalar {
|
||||
fn from(ptr: MemoryPointer) -> Self {
|
||||
Scalar::Ptr(ptr).into()
|
||||
Scalar::Ptr(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
|
||||
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
|
||||
llvals.push(primval_to_llvm(
|
||||
cx,
|
||||
Scalar::Ptr(MemoryPointer { alloc_id, offset: Size::from_bytes(ptr_offset) }),
|
||||
MemoryPointer { alloc_id, offset: Size::from_bytes(ptr_offset) }.into(),
|
||||
&layout::Scalar {
|
||||
value: layout::Primitive::Pointer,
|
||||
valid_range: 0..=!0
|
||||
|
@ -191,7 +191,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||
LitKind::ByteStr(ref data) => {
|
||||
let id = self.tcx.allocate_bytes(data);
|
||||
let ptr = MemoryPointer::zero(id);
|
||||
ConstValue::Scalar(Scalar::Ptr(ptr))
|
||||
ConstValue::Scalar(ptr.into())
|
||||
},
|
||||
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bytes(n as u128)),
|
||||
LitKind::Int(n, _) if neg => {
|
||||
|
@ -1137,7 +1137,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
|
||||
LitKind::ByteStr(ref data) => {
|
||||
let id = tcx.allocate_bytes(data);
|
||||
let ptr = MemoryPointer::zero(id);
|
||||
ConstValue::Scalar(Scalar::Ptr(ptr))
|
||||
ConstValue::Scalar(ptr.into())
|
||||
},
|
||||
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bytes(n as u128)),
|
||||
LitKind::Int(n, _) => {
|
||||
|
@ -107,7 +107,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
// Casting to a reference or fn pointer is not permitted by rustc, no need to support it here.
|
||||
TyRawPtr(_) |
|
||||
TyInt(IntTy::Isize) |
|
||||
TyUint(UintTy::Usize) => Ok(Scalar::Ptr(ptr)),
|
||||
TyUint(UintTy::Usize) => Ok(ptr.into()),
|
||||
TyInt(_) | TyUint(_) => err!(ReadPointerAsBytes),
|
||||
_ => err!(Unimplemented(format!("ptr to {:?} cast", ty))),
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use syntax::codemap::DUMMY_SP;
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
EvalResult, EvalError, EvalErrorKind, GlobalId,
|
||||
Value, Pointer, Scalar, AllocId, Allocation, ConstValue,
|
||||
Value, Scalar, AllocId, Allocation, ConstValue,
|
||||
};
|
||||
use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, MemoryKind};
|
||||
|
||||
@ -65,7 +65,7 @@ pub fn eval_promoted<'a, 'mir, 'tcx>(
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: &'mir mir::Mir<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<(Value, Pointer, Ty<'tcx>)> {
|
||||
) -> Option<(Value, Scalar, Ty<'tcx>)> {
|
||||
ecx.with_fresh_body(|ecx| {
|
||||
let res = eval_body_using_ecx(ecx, cid, Some(mir), param_env);
|
||||
match res {
|
||||
@ -82,7 +82,7 @@ pub fn eval_body<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cid: GlobalId<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<(Value, Pointer, Ty<'tcx>)> {
|
||||
) -> Option<(Value, Scalar, Ty<'tcx>)> {
|
||||
let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env);
|
||||
match res {
|
||||
Ok(val) => Some(val),
|
||||
@ -111,7 +111,7 @@ pub fn value_to_const_value<'tcx>(
|
||||
Value::Scalar(val) => Ok(ConstValue::Scalar(val)),
|
||||
Value::ScalarPair(a, b) => Ok(ConstValue::ScalarPair(a, b)),
|
||||
Value::ByRef(ptr, align) => {
|
||||
let ptr = ptr.primval.to_ptr().unwrap();
|
||||
let ptr = ptr.to_ptr().unwrap();
|
||||
let alloc = ecx.memory.get(ptr.alloc_id)?;
|
||||
assert!(alloc.align.abi() >= align.abi());
|
||||
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= layout.size.bytes());
|
||||
@ -136,7 +136,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: Option<&'mir mir::Mir<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> (EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>) {
|
||||
) -> (EvalResult<'tcx, (Value, Scalar, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>) {
|
||||
debug!("eval_body_and_ecx: {:?}, {:?}", cid, param_env);
|
||||
// we start out with the best span we have
|
||||
// and try improving it down the road when more information is available
|
||||
@ -152,7 +152,7 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: Option<&'mir mir::Mir<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)> {
|
||||
) -> EvalResult<'tcx, (Value, Scalar, Ty<'tcx>)> {
|
||||
debug!("eval_body: {:?}, {:?}", cid, param_env);
|
||||
let tcx = ecx.tcx.tcx;
|
||||
let mut mir = match mir {
|
||||
@ -471,8 +471,7 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||
let (ptr, align) = match value {
|
||||
Value::ScalarPair(..) | Value::Scalar(_) => {
|
||||
let layout = ecx.layout_of(ty)?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?;
|
||||
let ptr: Pointer = ptr.into();
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?.into();
|
||||
ecx.write_value_to_ptr(value, ptr, layout.align, ty)?;
|
||||
(ptr, layout.align)
|
||||
},
|
||||
|
@ -14,7 +14,7 @@ use rustc::middle::const_val::FrameInfo;
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::ast::Mutability;
|
||||
use rustc::mir::interpret::{
|
||||
GlobalId, Value, Pointer, Scalar, ScalarKind,
|
||||
GlobalId, Value, Scalar, ScalarKind,
|
||||
EvalError, EvalResult, EvalErrorKind, MemoryPointer, ConstValue,
|
||||
};
|
||||
use std::mem;
|
||||
@ -596,7 +596,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
|
||||
// FIXME: speed up repeat filling
|
||||
for i in 0..length {
|
||||
let elem_dest = dest.offset(elem_size * i as u64, &self)?;
|
||||
let elem_dest = dest.ptr_offset(elem_size * i as u64, &self)?;
|
||||
self.write_value_to_ptr(value, elem_dest, dest_align, elem_ty)?;
|
||||
}
|
||||
}
|
||||
@ -729,7 +729,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
).ok_or_else(|| EvalErrorKind::TypeckError.into());
|
||||
let fn_ptr = self.memory.create_fn_alloc(instance?);
|
||||
let valty = ValTy {
|
||||
value: Value::Scalar(Scalar::Ptr(fn_ptr)),
|
||||
value: Value::Scalar(fn_ptr.into()),
|
||||
ty: dest_ty,
|
||||
};
|
||||
self.write_value(valty, dest)?;
|
||||
@ -765,7 +765,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
);
|
||||
let fn_ptr = self.memory.create_fn_alloc(instance);
|
||||
let valty = ValTy {
|
||||
value: Value::Scalar(Scalar::Ptr(fn_ptr)),
|
||||
value: Value::Scalar(fn_ptr.into()),
|
||||
ty: dest_ty,
|
||||
};
|
||||
self.write_value(valty, dest)?;
|
||||
@ -1104,7 +1104,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_ptr(&mut self, dest: Place, val: Pointer, dest_ty: Ty<'tcx>) -> EvalResult<'tcx> {
|
||||
pub fn write_ptr(&mut self, dest: Place, val: Scalar, dest_ty: Ty<'tcx>) -> EvalResult<'tcx> {
|
||||
let valty = ValTy {
|
||||
value: val.to_value(),
|
||||
ty: dest_ty,
|
||||
@ -1201,7 +1201,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
pub fn write_value_to_ptr(
|
||||
&mut self,
|
||||
value: Value,
|
||||
dest: Pointer,
|
||||
dest: Scalar,
|
||||
dest_align: Align,
|
||||
dest_ty: Ty<'tcx>,
|
||||
) -> EvalResult<'tcx> {
|
||||
@ -1231,7 +1231,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
let (a_size, b_size) = (a.size(&self), b.size(&self));
|
||||
let a_ptr = dest;
|
||||
let b_offset = a_size.abi_align(b.align(&self));
|
||||
let b_ptr = dest.offset(b_offset, &self)?.into();
|
||||
let b_ptr = dest.ptr_offset(b_offset, &self)?.into();
|
||||
// TODO: What about signedess?
|
||||
self.memory.write_primval(a_ptr, dest_align, a_val, a_size, false)?;
|
||||
self.memory.write_primval(b_ptr, dest_align, b_val, b_size, false)
|
||||
@ -1319,7 +1319,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_value(&self, ptr: Pointer, align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
||||
pub fn read_value(&self, ptr: Scalar, align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
|
||||
if let Some(val) = self.try_read_value(ptr, align, ty)? {
|
||||
Ok(val)
|
||||
} else {
|
||||
@ -1334,7 +1334,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
pointee_ty: Ty<'tcx>,
|
||||
) -> EvalResult<'tcx, Value> {
|
||||
let ptr_size = self.memory.pointer_size();
|
||||
let p: Pointer = self.memory.read_ptr_sized(ptr, ptr_align)?.into();
|
||||
let p: Scalar = self.memory.read_ptr_sized(ptr, ptr_align)?.into();
|
||||
if self.type_is_sized(pointee_ty) {
|
||||
Ok(p.to_value())
|
||||
} else {
|
||||
@ -1414,7 +1414,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
pub fn try_read_value(&self, ptr: Pointer, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
|
||||
pub fn try_read_value(&self, ptr: Scalar, ptr_align: Align, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
|
||||
let layout = self.layout_of(ty)?;
|
||||
self.memory.check_align(ptr, ptr_align)?;
|
||||
|
||||
@ -1614,7 +1614,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
}
|
||||
}
|
||||
Ok(Value::ByRef(ptr, align)) => {
|
||||
match ptr.into_inner_primval() {
|
||||
match ptr {
|
||||
Scalar::Ptr(ptr) => {
|
||||
write!(msg, " by align({}) ref:", align.abi()).unwrap();
|
||||
allocs.push(ptr.alloc_id);
|
||||
@ -1643,7 +1643,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
self.memory.dump_allocs(allocs);
|
||||
}
|
||||
Place::Ptr { ptr, align, .. } => {
|
||||
match ptr.into_inner_primval() {
|
||||
match ptr {
|
||||
Scalar::Ptr(ptr) => {
|
||||
trace!("by align({}) ref:", align.abi());
|
||||
self.memory.dump_alloc(ptr.alloc_id);
|
||||
|
@ -10,7 +10,7 @@ use syntax::ast::Mutability;
|
||||
use rustc::middle::const_val::{ConstVal, ErrKind};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc::mir::interpret::{MemoryPointer, AllocId, Allocation, AccessKind, Value, Pointer,
|
||||
use rustc::mir::interpret::{MemoryPointer, AllocId, Allocation, AccessKind, Value,
|
||||
EvalResult, Scalar, EvalErrorKind, GlobalId, AllocType};
|
||||
pub use rustc::mir::interpret::{write_target_uint, write_target_int, read_target_uint};
|
||||
|
||||
@ -228,9 +228,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
}
|
||||
|
||||
/// Check that the pointer is aligned AND non-NULL.
|
||||
pub fn check_align(&self, ptr: Pointer, required_align: Align) -> EvalResult<'tcx> {
|
||||
pub fn check_align(&self, ptr: Scalar, required_align: Align) -> EvalResult<'tcx> {
|
||||
// Check non-NULL/Undef, extract offset
|
||||
let (offset, alloc_align) = match ptr.into_inner_primval() {
|
||||
let (offset, alloc_align) = match ptr {
|
||||
Scalar::Ptr(ptr) => {
|
||||
let alloc = self.get(ptr.alloc_id)?;
|
||||
(ptr.offset.bytes(), alloc.align)
|
||||
@ -594,9 +594,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
|
||||
pub fn copy(
|
||||
&mut self,
|
||||
src: Pointer,
|
||||
src: Scalar,
|
||||
src_align: Align,
|
||||
dest: Pointer,
|
||||
dest: Scalar,
|
||||
dest_align: Align,
|
||||
size: Size,
|
||||
nonoverlapping: bool,
|
||||
@ -671,7 +671,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_bytes(&self, ptr: Pointer, size: Size) -> EvalResult<'tcx, &[u8]> {
|
||||
pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> {
|
||||
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
|
||||
let align = Align::from_bytes(1, 1).unwrap();
|
||||
self.check_align(ptr, align)?;
|
||||
@ -681,7 +681,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
self.get_bytes(ptr.to_ptr()?, size, align)
|
||||
}
|
||||
|
||||
pub fn write_bytes(&mut self, ptr: Pointer, src: &[u8]) -> EvalResult<'tcx> {
|
||||
pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> {
|
||||
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
|
||||
let align = Align::from_bytes(1, 1).unwrap();
|
||||
self.check_align(ptr, align)?;
|
||||
@ -693,7 +693,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_repeat(&mut self, ptr: Pointer, val: u8, count: Size) -> EvalResult<'tcx> {
|
||||
pub fn write_repeat(&mut self, ptr: Scalar, val: u8, count: Size) -> EvalResult<'tcx> {
|
||||
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
|
||||
let align = Align::from_bytes(1, 1).unwrap();
|
||||
self.check_align(ptr, align)?;
|
||||
@ -726,7 +726,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
} else {
|
||||
let alloc = self.get(ptr.alloc_id)?;
|
||||
match alloc.relocations.get(&ptr.offset) {
|
||||
Some(&alloc_id) => return Ok(Scalar::Ptr(MemoryPointer::new(alloc_id, Size::from_bytes(bytes as u64)))),
|
||||
Some(&alloc_id) => return Ok(MemoryPointer::new(alloc_id, Size::from_bytes(bytes as u64)).into()),
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
@ -738,7 +738,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
self.read_primval(ptr, ptr_align, self.pointer_size())
|
||||
}
|
||||
|
||||
pub fn write_primval(&mut self, ptr: Pointer, ptr_align: Align, val: Scalar, size: Size, signed: bool) -> EvalResult<'tcx> {
|
||||
pub fn write_primval(&mut self, ptr: Scalar, ptr_align: Align, val: Scalar, size: Size, signed: bool) -> EvalResult<'tcx> {
|
||||
let endianness = self.endianness();
|
||||
|
||||
let bytes = match val {
|
||||
@ -896,7 +896,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
|
||||
pub fn mark_definedness(
|
||||
&mut self,
|
||||
ptr: Pointer,
|
||||
ptr: Scalar,
|
||||
size: Size,
|
||||
new_state: bool,
|
||||
) -> EvalResult<'tcx> {
|
||||
@ -927,7 +927,7 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
|
||||
fn into_ptr(
|
||||
&self,
|
||||
value: Value,
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
) -> EvalResult<'tcx, Scalar> {
|
||||
Ok(match value {
|
||||
Value::ByRef(ptr, align) => {
|
||||
self.memory().read_ptr_sized(ptr.to_ptr()?, align)?
|
||||
@ -940,13 +940,13 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
|
||||
fn into_ptr_vtable_pair(
|
||||
&self,
|
||||
value: Value,
|
||||
) -> EvalResult<'tcx, (Pointer, MemoryPointer)> {
|
||||
) -> EvalResult<'tcx, (Scalar, MemoryPointer)> {
|
||||
match value {
|
||||
Value::ByRef(ref_ptr, align) => {
|
||||
let mem = self.memory();
|
||||
let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into();
|
||||
let vtable = mem.read_ptr_sized(
|
||||
ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
|
||||
ref_ptr.ptr_offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
|
||||
align
|
||||
)?.to_ptr()?;
|
||||
Ok((ptr, vtable))
|
||||
@ -962,13 +962,13 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
|
||||
fn into_slice(
|
||||
&self,
|
||||
value: Value,
|
||||
) -> EvalResult<'tcx, (Pointer, u64)> {
|
||||
) -> EvalResult<'tcx, (Scalar, u64)> {
|
||||
match value {
|
||||
Value::ByRef(ref_ptr, align) => {
|
||||
let mem = self.memory();
|
||||
let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into();
|
||||
let len = mem.read_ptr_sized(
|
||||
ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
|
||||
ref_ptr.ptr_offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
|
||||
align
|
||||
)?.to_bytes()? as u64;
|
||||
Ok((ptr, len))
|
||||
|
@ -3,7 +3,7 @@ use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
use rustc::mir::interpret::{GlobalId, Value, Scalar, EvalResult, Pointer, MemoryPointer};
|
||||
use rustc::mir::interpret::{GlobalId, Value, Scalar, EvalResult, MemoryPointer};
|
||||
use super::{EvalContext, Machine, ValTy};
|
||||
use interpret::memory::HasMemory;
|
||||
|
||||
@ -14,7 +14,7 @@ pub enum Place {
|
||||
/// A place may have an invalid (integral or undef) pointer,
|
||||
/// since it might be turned back into a reference
|
||||
/// before ever being dereferenced.
|
||||
ptr: Pointer,
|
||||
ptr: Scalar,
|
||||
align: Align,
|
||||
extra: PlaceExtra,
|
||||
},
|
||||
@ -38,7 +38,7 @@ impl<'tcx> Place {
|
||||
Self::from_primval_ptr(Scalar::Undef.into(), Align::from_bytes(1, 1).unwrap())
|
||||
}
|
||||
|
||||
pub fn from_primval_ptr(ptr: Pointer, align: Align) -> Self {
|
||||
pub fn from_primval_ptr(ptr: Scalar, align: Align) -> Self {
|
||||
Place::Ptr {
|
||||
ptr,
|
||||
align,
|
||||
@ -50,7 +50,7 @@ impl<'tcx> Place {
|
||||
Self::from_primval_ptr(ptr.into(), align)
|
||||
}
|
||||
|
||||
pub fn to_ptr_align_extra(self) -> (Pointer, Align, PlaceExtra) {
|
||||
pub fn to_ptr_align_extra(self) -> (Scalar, Align, PlaceExtra) {
|
||||
match self {
|
||||
Place::Ptr { ptr, align, extra } => (ptr, align, extra),
|
||||
_ => bug!("to_ptr_and_extra: expected Place::Ptr, got {:?}", self),
|
||||
@ -58,7 +58,7 @@ impl<'tcx> Place {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_ptr_align(self) -> (Pointer, Align) {
|
||||
pub fn to_ptr_align(self) -> (Scalar, Align) {
|
||||
let (ptr, align, _extra) = self.to_ptr_align_extra();
|
||||
(ptr, align)
|
||||
}
|
||||
@ -272,7 +272,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
_ => offset,
|
||||
};
|
||||
|
||||
let ptr = base_ptr.offset(offset, &self)?;
|
||||
let ptr = base_ptr.ptr_offset(offset, &self)?;
|
||||
let align = base_align.min(base_layout.align).min(field.align);
|
||||
let extra = if !field.is_unsized() {
|
||||
PlaceExtra::None
|
||||
@ -332,7 +332,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
n,
|
||||
len
|
||||
);
|
||||
let ptr = base_ptr.offset(elem_size * n, &*self)?;
|
||||
let ptr = base_ptr.ptr_offset(elem_size * n, &*self)?;
|
||||
Ok(Place::Ptr {
|
||||
ptr,
|
||||
align,
|
||||
@ -410,7 +410,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
u64::from(offset)
|
||||
};
|
||||
|
||||
let ptr = base_ptr.offset(elem_size * index, &self)?;
|
||||
let ptr = base_ptr.ptr_offset(elem_size * index, &self)?;
|
||||
Ok(Place::Ptr { ptr, align, extra: PlaceExtra::None })
|
||||
}
|
||||
|
||||
@ -422,7 +422,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
let (elem_ty, n) = base.elem_ty_and_len(base_ty, self.tcx.tcx);
|
||||
let elem_size = self.layout_of(elem_ty)?.size;
|
||||
assert!(u64::from(from) <= n - u64::from(to));
|
||||
let ptr = base_ptr.offset(elem_size * u64::from(from), &self)?;
|
||||
let ptr = base_ptr.ptr_offset(elem_size * u64::from(from), &self)?;
|
||||
// sublicing arrays produces arrays
|
||||
let extra = if self.type_is_sized(base_ty) {
|
||||
PlaceExtra::None
|
||||
|
@ -342,7 +342,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
for (i, arg_local) in arg_locals.enumerate() {
|
||||
let field = layout.field(&self, i)?;
|
||||
let offset = layout.fields.offset(i);
|
||||
let arg = Value::ByRef(ptr.offset(offset, &self)?,
|
||||
let arg = Value::ByRef(ptr.ptr_offset(offset, &self)?,
|
||||
align.min(field.align));
|
||||
let dest =
|
||||
self.eval_place(&mir::Place::Local(arg_local))?;
|
||||
|
@ -35,7 +35,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
|
||||
let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
|
||||
let drop = self.memory.create_fn_alloc(drop);
|
||||
self.memory.write_ptr_sized_unsigned(vtable, ptr_align, Scalar::Ptr(drop))?;
|
||||
self.memory.write_ptr_sized_unsigned(vtable, ptr_align, drop.into())?;
|
||||
|
||||
let size_ptr = vtable.offset(ptr_size, &self)?;
|
||||
self.memory.write_ptr_sized_unsigned(size_ptr, ptr_align, Scalar::Bytes(size as u128))?;
|
||||
@ -47,7 +47,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
let fn_ptr = self.memory.create_fn_alloc(instance);
|
||||
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
|
||||
self.memory.write_ptr_sized_unsigned(method_ptr, ptr_align, Scalar::Ptr(fn_ptr))?;
|
||||
self.memory.write_ptr_sized_unsigned(method_ptr, ptr_align, fn_ptr.into())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user