From a107f14ed8abee5a4e0b3776ca55fe92438cccfd Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 21 Nov 2017 13:32:40 +0100 Subject: [PATCH] Rustup after layout optimizations --- miri/fn_call.rs | 11 +++-- miri/intrinsic.rs | 102 +++++++++++++++++++++++----------------------- miri/lib.rs | 9 ++-- 3 files changed, 63 insertions(+), 59 deletions(-) diff --git a/miri/fn_call.rs b/miri/fn_call.rs index 6c393ded638..4c17b4db330 100644 --- a/miri/fn_call.rs +++ b/miri/fn_call.rs @@ -45,6 +45,8 @@ pub trait EvalContextExt<'tcx> { span: Span, sig: ty::FnSig<'tcx>, ) -> EvalResult<'tcx, bool>; + + fn write_null(&mut self, dest: Lvalue, dest_ty: Ty<'tcx>) -> EvalResult<'tcx>; } impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> { @@ -416,10 +418,7 @@ 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::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 = { - let layout = self.type_layout(key_type)?; - layout.size(&self.tcx.data_layout) - }; + let key_size = self.type_layout(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; @@ -655,4 +654,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.goto_block(dest_block); return Ok(()); } + + fn write_null(&mut self, dest: Lvalue, dest_ty: Ty<'tcx>) -> EvalResult<'tcx> { + self.write_primval(dest, PrimVal::Bytes(0), dest_ty) + } } diff --git a/miri/intrinsic.rs b/miri/intrinsic.rs index aa17422159c..79dc3c7fe2a 100644 --- a/miri/intrinsic.rs +++ b/miri/intrinsic.rs @@ -1,7 +1,7 @@ use rustc::mir; use rustc::traits::Reveal; -use rustc::ty::layout::Layout; -use rustc::ty::{self, Ty}; +use rustc::ty::layout::TyLayout; +use rustc::ty; use rustc::mir::interpret::{EvalResult, Lvalue, LvalueExtra, PrimVal, PrimValKind, Value, Pointer, HasMemory, AccessKind, EvalContext, PtrAndAlign, ValTy}; @@ -14,8 +14,7 @@ pub trait EvalContextExt<'tcx> { instance: ty::Instance<'tcx>, args: &[ValTy<'tcx>], dest: Lvalue, - dest_ty: Ty<'tcx>, - dest_layout: &'tcx Layout, + dest_layout: TyLayout<'tcx>, target: mir::BasicBlock, ) -> EvalResult<'tcx>; } @@ -26,8 +25,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> instance: ty::Instance<'tcx>, args: &[ValTy<'tcx>], dest: Lvalue, - dest_ty: Ty<'tcx>, - dest_layout: &'tcx Layout, + dest_layout: TyLayout<'tcx>, target: mir::BasicBlock, ) -> EvalResult<'tcx> { let substs = instance.substs; @@ -37,7 +35,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> "align_offset" => { // FIXME: return a real value in case the target allocation has an // alignment bigger than the one requested - self.write_primval(dest, PrimVal::Bytes(u128::max_value()), dest_ty)?; + self.write_primval(dest, PrimVal::Bytes(u128::max_value()), dest_layout.ty)?; }, "add_with_overflow" => { @@ -46,7 +44,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )? } @@ -56,7 +54,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )? } @@ -66,7 +64,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )? } @@ -74,7 +72,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let offset = self.value_to_primval(args[1])?.to_i128()? as i64; let ptr = args[0].into_ptr(&self.memory)?; let result_ptr = self.wrapping_pointer_offset(ptr, substs.type_at(0), offset)?; - self.write_ptr(dest, result_ptr, dest_ty)?; + self.write_ptr(dest, result_ptr, dest_layout.ty)?; } "assume" => { @@ -139,8 +137,11 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> Value::ByValPair(..) => bug!("atomic_cxchg doesn't work with nonprimitives"), }; let (val, _) = self.binary_op(mir::BinOp::Eq, old, ty, expect_old, ty)?; - let dest = self.force_allocation(dest)?.to_ptr()?; - self.write_pair_to_ptr(old, val, dest, dest_ty)?; + let valty = ValTy { + value: Value::ByValPair(old, val), + ty: dest_layout.ty, + }; + self.write_value(valty, dest)?; self.write_primval( Lvalue::from_primval_ptr(ptr), change, @@ -238,9 +239,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> "discriminant_value" => { let ty = substs.type_at(0); - let adt_ptr = args[0].into_ptr(&self.memory)?.to_ptr()?; - let discr_val = self.read_discriminant_value(adt_ptr, ty)?; - self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?; + let adt_ptr = args[0].into_ptr(&self.memory)?; + let lval = Lvalue::from_primval_ptr(adt_ptr); + let discr_val = self.read_discriminant_value(lval, ty)?; + self.write_primval(dest, PrimVal::Bytes(discr_val), dest_layout.ty)?; } "sinf32" | "fabsf32" | "cosf32" | "sqrtf32" | "expf32" | "exp2f32" | "logf32" | @@ -262,7 +264,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> "truncf32" => f.trunc(), _ => bug!(), }; - self.write_primval(dest, PrimVal::Bytes(f.to_bits() as u128), dest_ty)?; + self.write_primval(dest, PrimVal::Bytes(f.to_bits() as u128), dest_layout.ty)?; } "sinf64" | "fabsf64" | "cosf64" | "sqrtf64" | "expf64" | "exp2f64" | "logf64" | @@ -284,7 +286,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> "truncf64" => f.trunc(), _ => bug!(), }; - self.write_primval(dest, PrimVal::Bytes(f.to_bits() as u128), dest_ty)?; + self.write_primval(dest, PrimVal::Bytes(f.to_bits() as u128), dest_layout.ty)?; } "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { @@ -300,13 +302,13 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> _ => bug!(), }; let result = self.binary_op(op, a, ty, b, ty)?; - self.write_primval(dest, result.0, dest_ty)?; + self.write_primval(dest, result.0, dest_layout.ty)?; } "likely" | "unlikely" | "forget" => {} "init" => { - let size = self.type_size(dest_ty)?.expect("cannot zero unsized value"); + let size = self.type_size(dest_layout.ty)?.expect("cannot zero unsized value"); let init = |this: &mut Self, val: Value| { let zero_val = match val { Value::ByRef(PtrAndAlign { ptr, .. }) => { @@ -316,10 +318,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> } // TODO(solson): Revisit this, it's fishy to check for Undef here. Value::ByVal(PrimVal::Undef) => { - match this.ty_to_primval_kind(dest_ty) { + match this.ty_to_primval_kind(dest_layout.ty) { Ok(_) => Value::ByVal(PrimVal::Bytes(0)), Err(_) => { - let ptr = this.alloc_ptr_with_substs(dest_ty, substs)?; + let ptr = this.alloc_ptr_with_substs(dest_layout.ty, substs)?; let ptr = Pointer::from(PrimVal::Ptr(ptr)); this.memory.write_repeat(ptr, 0, size)?; Value::by_ref(ptr) @@ -349,15 +351,15 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let elem_ty = substs.type_at(0); let elem_align = self.type_align(elem_ty)?; let align_val = PrimVal::from_u128(elem_align as u128); - self.write_primval(dest, align_val, dest_ty)?; + 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 align = layout.align(&self.tcx.data_layout).pref(); + let align = layout.align.pref(); let align_val = PrimVal::from_u128(align as u128); - self.write_primval(dest, align_val, dest_ty)?; + self.write_primval(dest, align_val, dest_layout.ty)?; } "move_val_init" => { @@ -373,7 +375,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::from_bool(needs_drop), - dest_ty, + dest_layout.ty, )?; } @@ -381,7 +383,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let offset = self.value_to_primval(args[1])?.to_i128()? as i64; let ptr = args[0].into_ptr(&self.memory)?; let result_ptr = self.pointer_offset(ptr, substs.type_at(0), offset)?; - self.write_ptr(dest, result_ptr, dest_ty)?; + self.write_ptr(dest, result_ptr, dest_layout.ty)?; } "overflowing_sub" => { @@ -390,7 +392,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } @@ -400,7 +402,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } @@ -410,7 +412,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } @@ -422,7 +424,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes(f.powf(f2).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -434,7 +436,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes(f.powf(f2).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -448,7 +450,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes((a * b + c).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -462,7 +464,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes((a * b + c).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -473,7 +475,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes(f.powi(i as i32).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -484,7 +486,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> self.write_primval( dest, PrimVal::Bytes(f.powi(i as i32).to_bits() as u128), - dest_ty, + dest_layout.ty, )?; } @@ -493,7 +495,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let size = self.type_size(ty)?.expect( "size_of intrinsic called on unsized value", ) as u128; - self.write_primval(dest, PrimVal::from_u128(size), dest_ty)?; + self.write_primval(dest, PrimVal::from_u128(size), dest_layout.ty)?; } "size_of_val" => { @@ -501,8 +503,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let (size, _) = self.size_and_align_of_dst(ty, args[0].value)?; self.write_primval( dest, - PrimVal::from_u128(size as u128), - dest_ty, + PrimVal::from_u128(size.bytes() as u128), + dest_layout.ty, )?; } @@ -512,8 +514,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let (_, align) = self.size_and_align_of_dst(ty, args[0].value)?; self.write_primval( dest, - PrimVal::from_u128(align as u128), - dest_ty, + PrimVal::from_u128(align.pref() as u128), + dest_layout.ty, )?; } @@ -521,12 +523,12 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> let ty = substs.type_at(0); let ty_name = ty.to_string(); let value = self.str_to_value(&ty_name)?; - self.write_value(ValTy { value, ty: dest_ty }, dest)?; + self.write_value(ValTy { value, ty: dest_layout.ty }, dest)?; } "type_id" => { let ty = substs.type_at(0); let n = self.tcx.type_id_hash(ty); - self.write_primval(dest, PrimVal::Bytes(n as u128), dest_ty)?; + self.write_primval(dest, PrimVal::Bytes(n as u128), dest_layout.ty)?; } "transmute" => { @@ -542,7 +544,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> } "unchecked_shl" => { - let bits = self.type_size(dest_ty)?.expect( + let bits = self.type_size(dest_layout.ty)?.expect( "intrinsic can't be called on unsized type", ) as u128 * 8; let rhs = self.value_to_primval(args[1])? @@ -557,12 +559,12 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } "unchecked_shr" => { - let bits = self.type_size(dest_ty)?.expect( + let bits = self.type_size(dest_layout.ty)?.expect( "intrinsic can't be called on unsized type", ) as u128 * 8; let rhs = self.value_to_primval(args[1])? @@ -577,7 +579,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } @@ -592,7 +594,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } @@ -607,12 +609,12 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator> args[0], args[1], dest, - dest_ty, + dest_layout.ty, )?; } "uninit" => { - let size = dest_layout.size(&self.tcx.data_layout).bytes(); + let size = dest_layout.size.bytes(); let uninit = |this: &mut Self, val: Value| match val { Value::ByRef(PtrAndAlign { ptr, .. }) => { this.memory.mark_definedness(ptr, size, false)?; diff --git a/miri/lib.rs b/miri/lib.rs index 6e857155660..e5566bfe947 100644 --- a/miri/lib.rs +++ b/miri/lib.rs @@ -11,7 +11,7 @@ extern crate rustc; extern crate syntax; use rustc::ty::{self, TyCtxt}; -use rustc::ty::layout::Layout; +use rustc::ty::layout::TyLayout; use rustc::hir::def_id::DefId; use rustc::mir; use rustc::traits; @@ -50,7 +50,7 @@ pub fn eval_main<'a, 'tcx: 'a>( let main_mir = ecx.load_mir(main_instance.def)?; let mut cleanup_ptr = None; // Pointer to be deallocated when we are done - if !main_mir.return_ty.is_nil() || main_mir.arg_count != 0 { + if !main_mir.return_ty().is_nil() || main_mir.arg_count != 0 { return err!(Unimplemented( "miri does not support main functions without `fn()` type signatures" .to_owned(), @@ -208,11 +208,10 @@ impl<'tcx> Machine<'tcx> for Evaluator { instance: ty::Instance<'tcx>, args: &[ValTy<'tcx>], dest: Lvalue, - dest_ty: ty::Ty<'tcx>, - dest_layout: &'tcx Layout, + dest_layout: TyLayout<'tcx>, target: mir::BasicBlock, ) -> EvalResult<'tcx> { - ecx.call_intrinsic(instance, args, dest, dest_ty, dest_layout, target) + ecx.call_intrinsic(instance, args, dest, dest_layout, target) } fn try_ptr_op<'a>(