Remove type_size and type_align calls
This commit is contained in:
parent
dd630a2a26
commit
eccf680b5d
4 changed files with 30 additions and 48 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use rustc::mir;
|
||||
use syntax::attr;
|
||||
|
|
@ -261,7 +262,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
let result = {
|
||||
let name_ptr = args[0].into_ptr(&mut self.memory)?.to_ptr()?;
|
||||
let name = self.memory.read_c_str(name_ptr)?;
|
||||
match self.machine_data.env_vars.get(name) {
|
||||
match self.machine.env_vars.get(name) {
|
||||
Some(&var) => PrimVal::Ptr(var),
|
||||
None => PrimVal::Bytes(0),
|
||||
}
|
||||
|
|
@ -276,7 +277,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
if !name_ptr.is_null()? {
|
||||
let name = self.memory.read_c_str(name_ptr.to_ptr()?)?;
|
||||
if !name.is_empty() && !name.contains(&b'=') {
|
||||
success = Some(self.machine_data.env_vars.remove(name));
|
||||
success = Some(self.machine.env_vars.remove(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -313,7 +314,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
self.memory.write_bytes(value_copy.into(), &value)?;
|
||||
let trailing_zero_ptr = value_copy.offset(value.len() as u64, &self)?.into();
|
||||
self.memory.write_bytes(trailing_zero_ptr, &[0])?;
|
||||
if let Some(var) = self.machine_data.env_vars.insert(
|
||||
if let Some(var) = self.machine.env_vars.insert(
|
||||
name.to_owned(),
|
||||
value_copy,
|
||||
)
|
||||
|
|
@ -416,9 +417,9 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
};
|
||||
|
||||
// Figure out how large a pthread TLS key actually is. This is libc::pthread_key_t.
|
||||
let key_type = args[0].ty.builtin_deref(true, ty::PlacePreference::NoPreference)
|
||||
let key_type = args[0].ty.builtin_deref(true, ty::LvaluePreference::NoPreference)
|
||||
.ok_or(EvalErrorKind::AbiViolation("Wrong signature used for pthread_key_create: First argument must be a raw pointer.".to_owned()))?.ty;
|
||||
let key_size = self.type_layout(key_type)?.size;
|
||||
let key_size = self.layout_of(key_type)?.size;
|
||||
|
||||
// Create key and write it into the memory where key_ptr wants it
|
||||
let key = self.memory.create_tls_key(dtor) as u128;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc::mir::interpret::{Pointer, EvalResult, PrimVal, EvalContext};
|
||||
|
||||
use rustc::ty::Ty;
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
|
||||
pub trait EvalContextExt<'tcx> {
|
||||
fn wrapping_pointer_offset(
|
||||
|
|
@ -26,9 +27,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
offset: i64,
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
// FIXME: assuming here that type size is < i64::max_value()
|
||||
let pointee_size = self.type_size(pointee_ty)?.expect(
|
||||
"cannot offset a pointer to an unsized type",
|
||||
) as i64;
|
||||
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
|
||||
let offset = offset.overflowing_mul(pointee_size).0;
|
||||
ptr.wrapping_signed_offset(offset, self)
|
||||
}
|
||||
|
|
@ -53,9 +52,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
};
|
||||
}
|
||||
// FIXME: assuming here that type size is < i64::max_value()
|
||||
let pointee_size = self.type_size(pointee_ty)?.expect(
|
||||
"cannot offset a pointer to an unsized type",
|
||||
) as i64;
|
||||
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
|
||||
return if let Some(offset) = offset.checked_mul(pointee_size) {
|
||||
let ptr = ptr.signed_offset(offset, self)?;
|
||||
// Do not do bounds-checking for integers; they can never alias a normal pointer anyway.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::mir;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::ty::layout::TyLayout;
|
||||
use rustc::ty::layout::{TyLayout, LayoutOf};
|
||||
use rustc::ty;
|
||||
|
||||
use rustc::mir::interpret::{EvalResult, Place, PlaceExtra, PrimVal, PrimValKind, Value, Pointer,
|
||||
|
|
@ -204,12 +204,13 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
"copy" |
|
||||
"copy_nonoverlapping" => {
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_size = self.type_size(elem_ty)?.expect("cannot copy unsized value");
|
||||
let elem_layout = self.layout_of(elem_ty)?;
|
||||
let elem_size = elem_layout.size.bytes();
|
||||
let count = self.value_to_primval(args[2])?.to_u64()?;
|
||||
if count * elem_size != 0 {
|
||||
// TODO: We do not even validate alignment for the 0-bytes case. libstd relies on this in vec::IntoIter::next.
|
||||
// Also see the write_bytes intrinsic.
|
||||
let elem_align = self.type_align(elem_ty)?;
|
||||
let elem_align = elem_layout.align.abi();
|
||||
let src = args[0].into_ptr(&self.memory)?;
|
||||
let dest = args[1].into_ptr(&self.memory)?;
|
||||
self.memory.copy(
|
||||
|
|
@ -308,7 +309,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
"likely" | "unlikely" | "forget" => {}
|
||||
|
||||
"init" => {
|
||||
let size = self.type_size(dest_layout.ty)?.expect("cannot zero unsized value");
|
||||
let size = dest_layout.size.bytes();
|
||||
let init = |this: &mut Self, val: Value| {
|
||||
let zero_val = match val {
|
||||
Value::ByRef(PtrAndAlign { ptr, .. }) => {
|
||||
|
|
@ -321,7 +322,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
match this.ty_to_primval_kind(dest_layout.ty) {
|
||||
Ok(_) => Value::ByVal(PrimVal::Bytes(0)),
|
||||
Err(_) => {
|
||||
let ptr = this.alloc_ptr_with_substs(dest_layout.ty, substs)?;
|
||||
// FIXME(oli-obk): pass TyLayout to alloc_ptr instead of Ty
|
||||
let ptr = this.alloc_ptr(dest_layout.ty)?;
|
||||
let ptr = Pointer::from(PrimVal::Ptr(ptr));
|
||||
this.memory.write_repeat(ptr, 0, size)?;
|
||||
Value::by_ref(ptr)
|
||||
|
|
@ -349,14 +351,14 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
|
||||
"min_align_of" => {
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_align = self.type_align(elem_ty)?;
|
||||
let elem_align = self.layout_of(elem_ty)?.align.abi();
|
||||
let align_val = PrimVal::from_u128(elem_align as u128);
|
||||
self.write_primval(dest, align_val, dest_layout.ty)?;
|
||||
}
|
||||
|
||||
"pref_align_of" => {
|
||||
let ty = substs.type_at(0);
|
||||
let layout = self.type_layout(ty)?;
|
||||
let layout = self.layout_of(ty)?;
|
||||
let align = layout.align.pref();
|
||||
let align_val = PrimVal::from_u128(align as u128);
|
||||
self.write_primval(dest, align_val, dest_layout.ty)?;
|
||||
|
|
@ -492,9 +494,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
|
||||
"size_of" => {
|
||||
let ty = substs.type_at(0);
|
||||
let size = self.type_size(ty)?.expect(
|
||||
"size_of intrinsic called on unsized value",
|
||||
) as u128;
|
||||
let size = self.layout_of(ty)?.size.bytes().into();
|
||||
self.write_primval(dest, PrimVal::from_u128(size), dest_layout.ty)?;
|
||||
}
|
||||
|
||||
|
|
@ -544,9 +544,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
}
|
||||
|
||||
"unchecked_shl" => {
|
||||
let bits = self.type_size(dest_layout.ty)?.expect(
|
||||
"intrinsic can't be called on unsized type",
|
||||
) as u128 * 8;
|
||||
let bits = dest_layout.size.bytes() as u128 * 8;
|
||||
let rhs = self.value_to_primval(args[1])?
|
||||
.to_bytes()?;
|
||||
if rhs >= bits {
|
||||
|
|
@ -564,9 +562,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
}
|
||||
|
||||
"unchecked_shr" => {
|
||||
let bits = self.type_size(dest_layout.ty)?.expect(
|
||||
"intrinsic can't be called on unsized type",
|
||||
) as u128 * 8;
|
||||
let bits = dest_layout.size.bytes() as u128 * 8;
|
||||
let rhs = self.value_to_primval(args[1])?
|
||||
.to_bytes()?;
|
||||
if rhs >= bits {
|
||||
|
|
@ -636,18 +632,15 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||
|
||||
"write_bytes" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ty_align = self.type_align(ty)?;
|
||||
let ty_layout = self.layout_of(ty)?;
|
||||
let val_byte = self.value_to_primval(args[1])?.to_u128()? as u8;
|
||||
let size = self.type_size(ty)?.expect(
|
||||
"write_bytes() type must be sized",
|
||||
);
|
||||
let ptr = args[0].into_ptr(&self.memory)?;
|
||||
let count = self.value_to_primval(args[2])?.to_u64()?;
|
||||
if count > 0 {
|
||||
// HashMap relies on write_bytes on a NULL ptr with count == 0 to work
|
||||
// TODO: Should we, at least, validate the alignment? (Also see the copy intrinsic)
|
||||
self.memory.check_align(ptr, ty_align, Some(AccessKind::Write))?;
|
||||
self.memory.write_repeat(ptr, val_byte, size * count)?;
|
||||
self.memory.check_align(ptr, ty_layout.align.abi(), Some(AccessKind::Write))?;
|
||||
self.memory.write_repeat(ptr, val_byte, ty_layout.size.bytes() * count)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
21
miri/lib.rs
21
miri/lib.rs
|
|
@ -11,7 +11,7 @@ extern crate rustc;
|
|||
extern crate syntax;
|
||||
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty::layout::TyLayout;
|
||||
use rustc::ty::layout::{TyLayout, LayoutOf};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir;
|
||||
use rustc::traits;
|
||||
|
|
@ -141,7 +141,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
let mut ecx = EvalContext::new(tcx, limits, Default::default(), Default::default());
|
||||
let mut ecx = EvalContext::new(tcx, ty::ParamEnv::empty(traits::Reveal::All), limits, Default::default(), Default::default());
|
||||
match run_main(&mut ecx, main_id, start_wrapper) {
|
||||
Ok(()) => {
|
||||
let leaks = ecx.memory().leak_report();
|
||||
|
|
@ -155,9 +155,8 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Evaluator;
|
||||
#[derive(Default)]
|
||||
pub struct EvaluatorData {
|
||||
pub struct Evaluator {
|
||||
/// Environment variables set by `setenv`
|
||||
/// Miri does not expose env vars from the host to the emulated program
|
||||
pub(crate) env_vars: HashMap<Vec<u8>, MemoryPointer>,
|
||||
|
|
@ -181,16 +180,9 @@ pub struct MemoryData<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Machine<'tcx> for Evaluator {
|
||||
type Data = EvaluatorData;
|
||||
type MemoryData = MemoryData<'tcx>;
|
||||
type MemoryKinds = memory::MemoryKind;
|
||||
|
||||
fn param_env<'a>(
|
||||
_: &EvalContext<'a, 'tcx, Self>,
|
||||
) -> ty::ParamEnv<'tcx> {
|
||||
ty::ParamEnv::empty(traits::Reveal::All)
|
||||
}
|
||||
|
||||
/// Returns Ok() when the function was handled, fail otherwise
|
||||
fn eval_fn_call<'a>(
|
||||
ecx: &mut EvalContext<'a, 'tcx, Self>,
|
||||
|
|
@ -239,8 +231,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
|
|||
ty: ty::Ty<'tcx>,
|
||||
dest: Place,
|
||||
) -> EvalResult<'tcx> {
|
||||
let size = ecx.type_size(ty)?.expect("box only works with sized types");
|
||||
let align = ecx.type_align(ty)?;
|
||||
let layout = ecx.layout_of(ty)?;
|
||||
|
||||
// Call the `exchange_malloc` lang item
|
||||
let malloc = ecx.tcx.lang_items().exchange_malloc_fn().unwrap();
|
||||
|
|
@ -264,7 +255,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
|
|||
let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
|
||||
ecx.write_value(
|
||||
ValTy {
|
||||
value: Value::ByVal(PrimVal::Bytes(size as u128)),
|
||||
value: Value::ByVal(PrimVal::Bytes(layout.size.bytes().into())),
|
||||
ty: usize,
|
||||
},
|
||||
dest,
|
||||
|
|
@ -274,7 +265,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
|
|||
let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
|
||||
ecx.write_value(
|
||||
ValTy {
|
||||
value: Value::ByVal(PrimVal::Bytes(align as u128)),
|
||||
value: Value::ByVal(PrimVal::Bytes(layout.align.abi().into())),
|
||||
ty: usize,
|
||||
},
|
||||
dest,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue