From: Oliver Schneider Date: Wed, 6 Dec 2017 14:03:24 +0000 (+0100) Subject: Remove type_size and type_align calls X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=eccf680b5d191bb39ef2fc5ae51bf3909c312bbe;p=rust.git Remove type_size and type_align calls --- diff --git a/miri/fn_call.rs b/miri/fn_call.rs index 1d02c979ba7..8961ae4d202 100644 --- a/miri/fn_call.rs +++ b/miri/fn_call.rs @@ -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 @@ fn call_c_abi( 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 @@ fn call_c_abi( 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 @@ fn call_c_abi( 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 @@ fn call_c_abi( }; // 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; diff --git a/miri/helpers.rs b/miri/helpers.rs index 3ee148afb2b..9ca85a6018e 100644 --- a/miri/helpers.rs +++ b/miri/helpers.rs @@ -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 @@ 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) } @@ -53,9 +52,7 @@ fn pointer_offset( }; } // 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. diff --git a/miri/intrinsic.rs b/miri/intrinsic.rs index 0db3f4f2542..a509606aaaa 100644 --- a/miri/intrinsic.rs +++ b/miri/intrinsic.rs @@ -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 @@ fn call_intrinsic( "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 @@ fn call_intrinsic( "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 @@ fn call_intrinsic( 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 @@ fn call_intrinsic( "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 @@ fn call_intrinsic( "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 @@ fn call_intrinsic( } "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 @@ fn call_intrinsic( } "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 @@ fn call_intrinsic( "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)?; } } diff --git a/miri/lib.rs b/miri/lib.rs index 399418f6734..398062b8c22 100644 --- a/miri/lib.rs +++ b/miri/lib.rs @@ -11,7 +11,7 @@ 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 @@ fn run_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 @@ fn run_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, 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 @@ fn box_alloc<'a>( 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 @@ fn box_alloc<'a>( 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 @@ fn box_alloc<'a>( 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,