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;
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),
}
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));
}
}
}
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,
)
};
// 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;
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(
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)
}
};
}
// 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.
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,
"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(
"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, .. }) => {
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)
"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)?;
"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)?;
}
}
"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 {
}
"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 {
"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)?;
}
}
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;
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();
}
}
-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>,
}
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>,
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();
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,
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,