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