Eliminate the Pointer wrapper type

This commit is contained in:
Oliver Schneider 2018-05-21 00:30:00 +02:00
parent 6436de89fe
commit 03a92b61ec
13 changed files with 74 additions and 107 deletions

View File

@ -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),

View File

@ -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;

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 => {

View File

@ -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, _) => {

View File

@ -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))),
}

View File

@ -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)
},

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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))?;

View File

@ -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())?;
}
}