diff --git a/src/eval_context.rs b/src/eval_context.rs index 0e63e033cfb78fd207d9a8d51638d7024304f5de..4d7caaf6ff3ccf1e92f04d5a5b3c356e6135ad42 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -1460,7 +1460,7 @@ fn unsize_into_ptr( match (&src_pointee_ty.sty, &dest_pointee_ty.sty) { (&ty::TyArray(_, length), &ty::TySlice(_)) => { - let ptr = src.read_ptr(&self.memory)?; + let ptr = src.into_ptr(&self.memory)?; // u64 cast is from usize to u64, which is always good self.write_value(ptr.to_value_with_len(length as u64), dest, dest_ty) } @@ -1474,7 +1474,7 @@ fn unsize_into_ptr( let trait_ref = data.principal().unwrap().with_self_ty(self.tcx, src_pointee_ty); let trait_ref = self.tcx.erase_regions(&trait_ref); let vtable = self.get_vtable(src_pointee_ty, trait_ref)?; - let ptr = src.read_ptr(&self.memory)?; + let ptr = src.into_ptr(&self.memory)?; self.write_value(ptr.to_value_with_vtable(vtable), dest, dest_ty) }, diff --git a/src/lvalue.rs b/src/lvalue.rs index 18ec7a77cb8ce90708cb1a09449e93ae9230adf7..bff6f9f955ade0cffc40f49a328a2c01de162c1b 100644 --- a/src/lvalue.rs +++ b/src/lvalue.rs @@ -391,14 +391,14 @@ fn eval_lvalue_projection( match self.tcx.struct_tail(pointee_type).sty { ty::TyDynamic(..) => { - let (ptr, vtable) = val.expect_ptr_vtable_pair(&self.memory)?; + let (ptr, vtable) = val.into_ptr_vtable_pair(&self.memory)?; (ptr, LvalueExtra::Vtable(vtable), true) }, ty::TyStr | ty::TySlice(_) => { - let (ptr, len) = val.expect_slice(&self.memory)?; + let (ptr, len) = val.into_slice(&self.memory)?; (ptr, LvalueExtra::Length(len), true) }, - _ => (val.read_ptr(&self.memory)?, LvalueExtra::None, true), + _ => (val.into_ptr(&self.memory)?, LvalueExtra::None, true), } } diff --git a/src/terminator/intrinsic.rs b/src/terminator/intrinsic.rs index def080d5b206b199cff72e82f172bfd3e62e092a..7af678645550a8336ef111a4f814e7deb8b975b2 100644 --- a/src/terminator/intrinsic.rs +++ b/src/terminator/intrinsic.rs @@ -44,7 +44,7 @@ pub(super) fn call_intrinsic( "arith_offset" => { let offset = self.value_to_primval(arg_vals[1], isize)?.to_i128()? as i64; - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[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)?; } @@ -60,7 +60,7 @@ pub(super) fn call_intrinsic( "atomic_load_acq" | "volatile_load" => { let ty = substs.type_at(0); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; self.write_value(Value::ByRef(ptr), dest, ty)?; } @@ -69,7 +69,7 @@ pub(super) fn call_intrinsic( "atomic_store_rel" | "volatile_store" => { let ty = substs.type_at(0); - let dest = arg_vals[0].read_ptr(&self.memory)?; + let dest = arg_vals[0].into_ptr(&self.memory)?; self.write_value_to_ptr(arg_vals[1], dest, ty)?; } @@ -79,7 +79,7 @@ pub(super) fn call_intrinsic( _ if intrinsic_name.starts_with("atomic_xchg") => { let ty = substs.type_at(0); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; let change = self.value_to_primval(arg_vals[1], ty)?; let old = self.read_value(ptr, ty)?; let old = match old { @@ -93,7 +93,7 @@ pub(super) fn call_intrinsic( _ if intrinsic_name.starts_with("atomic_cxchg") => { let ty = substs.type_at(0); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; let expect_old = self.value_to_primval(arg_vals[1], ty)?; let change = self.value_to_primval(arg_vals[2], ty)?; let old = self.read_value(ptr, ty)?; @@ -114,7 +114,7 @@ pub(super) fn call_intrinsic( "atomic_xadd" | "atomic_xadd_acq" | "atomic_xadd_rel" | "atomic_xadd_acqrel" | "atomic_xadd_relaxed" | "atomic_xsub" | "atomic_xsub_acq" | "atomic_xsub_rel" | "atomic_xsub_acqrel" | "atomic_xsub_relaxed" => { let ty = substs.type_at(0); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; let change = self.value_to_primval(arg_vals[1], ty)?; let old = self.read_value(ptr, ty)?; let old = match old { @@ -144,8 +144,8 @@ pub(super) fn call_intrinsic( let elem_size = self.type_size(elem_ty)?.expect("cannot copy unsized value"); if elem_size != 0 { let elem_align = self.type_align(elem_ty)?; - let src = arg_vals[0].read_ptr(&self.memory)?; - let dest = arg_vals[1].read_ptr(&self.memory)?; + let src = arg_vals[0].into_ptr(&self.memory)?; + let dest = arg_vals[1].into_ptr(&self.memory)?; let count = self.value_to_primval(arg_vals[2], usize)?.to_u64()?; self.memory.copy(src, dest, count * elem_size, elem_align, intrinsic_name.ends_with("_nonoverlapping"))?; } @@ -173,7 +173,7 @@ pub(super) fn call_intrinsic( "discriminant_value" => { let ty = substs.type_at(0); - let adt_ptr = arg_vals[0].read_ptr(&self.memory)?.to_ptr()?; + let adt_ptr = arg_vals[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)?; } @@ -293,7 +293,7 @@ pub(super) fn call_intrinsic( "move_val_init" => { let ty = substs.type_at(0); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; self.write_value_to_ptr(arg_vals[1], ptr, ty)?; } @@ -306,7 +306,7 @@ pub(super) fn call_intrinsic( "offset" => { let offset = self.value_to_primval(arg_vals[1], isize)?.to_i128()? as i64; - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[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)?; } @@ -460,7 +460,7 @@ pub(super) fn call_intrinsic( let ty_align = self.type_align(ty)?; let val_byte = self.value_to_primval(arg_vals[1], u8)?.to_u128()? as u8; let size = self.type_size(ty)?.expect("write_bytes() type must be sized"); - let ptr = arg_vals[0].read_ptr(&self.memory)?; + let ptr = arg_vals[0].into_ptr(&self.memory)?; let count = self.value_to_primval(arg_vals[2], usize)?.to_u64()?; if count > 0 { // TODO: Should we, at least, validate the alignment? (Also see memory::copy) @@ -545,7 +545,7 @@ pub fn size_and_align_of_dst( Ok((size, align.abi())) } ty::TyDynamic(..) => { - let (_, vtable) = value.expect_ptr_vtable_pair(&self.memory)?; + let (_, vtable) = value.into_ptr_vtable_pair(&self.memory)?; // the second entry in the vtable is the dynamic size of the object. self.read_size_and_align_from_vtable(vtable) } @@ -553,7 +553,7 @@ pub fn size_and_align_of_dst( ty::TySlice(_) | ty::TyStr => { let elem_ty = ty.sequence_element_type(self.tcx); let elem_size = self.type_size(elem_ty)?.expect("slice element must be sized") as u64; - let (_, len) = value.expect_slice(&self.memory)?; + let (_, len) = value.into_slice(&self.memory)?; let align = self.type_align(elem_ty)?; Ok((len * elem_size, align as u64)) } diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index dc6610a2213b0bab513fcea3ec313b3e7afdb0a5..9a7619576c407361a8bd0424603b708f7ceedbdb 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -393,7 +393,7 @@ fn eval_fn_call( }, ty::InstanceDef::Virtual(_, idx) => { let ptr_size = self.memory.pointer_size(); - let (_, vtable) = self.eval_operand(&arg_operands[0])?.expect_ptr_vtable_pair(&self.memory)?; + let (_, vtable) = self.eval_operand(&arg_operands[0])?.into_ptr_vtable_pair(&self.memory)?; let fn_ptr = self.memory.read_ptr(vtable.offset(ptr_size * (idx as u64 + 3), self.memory.layout)?)?; let instance = self.memory.get_fn(fn_ptr.to_ptr()?)?; let mut arg_operands = arg_operands.to_vec(); @@ -572,7 +572,7 @@ fn call_missing_fn( self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?; } "alloc::heap::::__rust_dealloc" => { - let ptr = args[0].read_ptr(&self.memory)?.to_ptr()?; + let ptr = args[0].into_ptr(&self.memory)?.to_ptr()?; let old_size = self.value_to_primval(args[1], usize)?.to_u64()?; let align = self.value_to_primval(args[2], usize)?.to_u64()?; if old_size == 0 { @@ -584,7 +584,7 @@ fn call_missing_fn( self.memory.deallocate(ptr, Some((old_size, align)))?; } "alloc::heap::::__rust_realloc" => { - let ptr = args[0].read_ptr(&self.memory)?.to_ptr()?; + let ptr = args[0].into_ptr(&self.memory)?.to_ptr()?; let old_size = self.value_to_primval(args[1], usize)?.to_u64()?; let old_align = self.value_to_primval(args[2], usize)?.to_u64()?; let new_size = self.value_to_primval(args[3], usize)?.to_u64()?; @@ -660,7 +660,7 @@ fn call_c_abi( } "free" => { - let ptr = args[0].read_ptr(&self.memory)?; + let ptr = args[0].into_ptr(&self.memory)?; if !ptr.is_null()? { self.memory.deallocate(ptr.to_ptr()?, None)?; } @@ -674,8 +674,8 @@ fn call_c_abi( } "dlsym" => { - let _handle = args[0].read_ptr(&self.memory)?; - let symbol = args[1].read_ptr(&self.memory)?.to_ptr()?; + let _handle = args[0].into_ptr(&self.memory)?; + let symbol = args[1].into_ptr(&self.memory)?.to_ptr()?; let symbol_name = self.memory.read_c_str(symbol)?; let err = format!("bad c unicode symbol: {:?}", symbol_name); let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err); @@ -686,8 +686,8 @@ fn call_c_abi( // fn __rust_maybe_catch_panic(f: fn(*mut u8), data: *mut u8, data_ptr: *mut usize, vtable_ptr: *mut usize) -> u32 // We abort on panic, so not much is going on here, but we still have to call the closure let u8_ptr_ty = self.tcx.mk_mut_ptr(self.tcx.types.u8); - let f = args[0].read_ptr(&self.memory)?.to_ptr()?; - let data = args[1].read_ptr(&self.memory)?; + let f = args[0].into_ptr(&self.memory)?.to_ptr()?; + let data = args[1].into_ptr(&self.memory)?; let f_instance = self.memory.get_fn(f)?; self.write_null(dest, dest_ty)?; @@ -718,8 +718,8 @@ fn call_c_abi( } "memcmp" => { - let left = args[0].read_ptr(&self.memory)?; - let right = args[1].read_ptr(&self.memory)?; + let left = args[0].into_ptr(&self.memory)?; + let right = args[1].into_ptr(&self.memory)?; let n = self.value_to_primval(args[2], usize)?.to_u64()?; let result = { @@ -738,7 +738,7 @@ fn call_c_abi( } "memrchr" => { - let ptr = args[0].read_ptr(&self.memory)?; + let ptr = args[0].into_ptr(&self.memory)?; let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8; let num = self.value_to_primval(args[2], usize)?.to_u64()?; if let Some(idx) = self.memory.read_bytes(ptr, num)?.iter().rev().position(|&c| c == val) { @@ -750,7 +750,7 @@ fn call_c_abi( } "memchr" => { - let ptr = args[0].read_ptr(&self.memory)?; + let ptr = args[0].into_ptr(&self.memory)?; let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8; let num = self.value_to_primval(args[2], usize)?.to_u64()?; if let Some(idx) = self.memory.read_bytes(ptr, num)?.iter().position(|&c| c == val) { @@ -763,7 +763,7 @@ fn call_c_abi( "getenv" => { let result = { - let name_ptr = args[0].read_ptr(&self.memory)?.to_ptr()?; + let name_ptr = args[0].into_ptr(&self.memory)?.to_ptr()?; let name = self.memory.read_c_str(name_ptr)?; match self.env_vars.get(name) { Some(&var) => PrimVal::Ptr(var), @@ -776,7 +776,7 @@ fn call_c_abi( "unsetenv" => { let mut success = None; { - let name_ptr = args[0].read_ptr(&self.memory)?; + let name_ptr = args[0].into_ptr(&self.memory)?; if !name_ptr.is_null()? { let name = self.memory.read_c_str(name_ptr.to_ptr()?)?; if !name.is_empty() && !name.contains(&b'=') { @@ -797,8 +797,8 @@ fn call_c_abi( "setenv" => { let mut new = None; { - let name_ptr = args[0].read_ptr(&self.memory)?; - let value_ptr = args[1].read_ptr(&self.memory)?.to_ptr()?; + let name_ptr = args[0].into_ptr(&self.memory)?; + let value_ptr = args[1].into_ptr(&self.memory)?.to_ptr()?; let value = self.memory.read_c_str(value_ptr)?; if !name_ptr.is_null()? { let name = self.memory.read_c_str(name_ptr.to_ptr()?)?; @@ -823,7 +823,7 @@ fn call_c_abi( "write" => { let fd = self.value_to_primval(args[0], usize)?.to_u64()?; - let buf = args[1].read_ptr(&self.memory)?; + let buf = args[1].into_ptr(&self.memory)?; let n = self.value_to_primval(args[2], usize)?.to_u64()?; trace!("Called write({:?}, {:?}, {:?})", fd, buf, n); let result = if fd == 1 || fd == 2 { // stdout/stderr @@ -840,7 +840,7 @@ fn call_c_abi( } "strlen" => { - let ptr = args[0].read_ptr(&self.memory)?.to_ptr()?; + let ptr = args[0].into_ptr(&self.memory)?.to_ptr()?; let n = self.memory.read_c_str(ptr)?.len(); self.write_primval(dest, PrimVal::Bytes(n as u128), dest_ty)?; } @@ -863,10 +863,10 @@ fn call_c_abi( // Hook pthread calls that go to the thread-local storage memory subsystem "pthread_key_create" => { - let key_ptr = args[0].read_ptr(&self.memory)?; + let key_ptr = args[0].into_ptr(&self.memory)?; // Extract the function type out of the signature (that seems easier than constructing it ourselves...) - let dtor = match args[1].read_ptr(&self.memory)?.into_inner_primval() { + let dtor = match args[1].into_ptr(&self.memory)?.into_inner_primval() { PrimVal::Ptr(dtor_ptr) => Some(self.memory.get_fn(dtor_ptr)?), PrimVal::Bytes(0) => None, PrimVal::Bytes(_) => return Err(EvalError::ReadBytesAsPointer), @@ -908,7 +908,7 @@ fn call_c_abi( "pthread_setspecific" => { // The conversion into TlsKey here is a little fishy, but should work as long as usize >= libc::pthread_key_t let key = self.value_to_primval(args[0], usize)?.to_u64()? as TlsKey; - let new_ptr = args[1].read_ptr(&self.memory)?; + let new_ptr = args[1].into_ptr(&self.memory)?; self.memory.store_tls(key, new_ptr)?; // Return success (0) diff --git a/src/value.rs b/src/value.rs index 4bda56a2877f999a1f0737507da611320328a081..0e544456524f74673fdfa63b79bbd5454c0abf66 100644 --- a/src/value.rs +++ b/src/value.rs @@ -158,7 +158,9 @@ pub enum PrimValKind { } impl<'a, 'tcx: 'a> Value { - pub(super) fn read_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointer> { + /// Convert the value into a pointer (or a pointer-sized integer). If the value is a ByRef, + /// this may have to perform a load. + pub(super) fn into_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointer> { use self::Value::*; match *self { ByRef(ptr) => mem.read_ptr(ptr.to_ptr()?), @@ -166,7 +168,7 @@ pub(super) fn read_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointe } } - pub(super) fn expect_ptr_vtable_pair( + pub(super) fn into_ptr_vtable_pair( &self, mem: &Memory<'a, 'tcx> ) -> EvalResult<'tcx, (Pointer, MemoryPointer)> { @@ -184,7 +186,7 @@ pub(super) fn expect_ptr_vtable_pair( } } - pub(super) fn expect_slice(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, (Pointer, u64)> { + pub(super) fn into_slice(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, (Pointer, u64)> { use self::Value::*; match *self { ByRef(ref_ptr) => {