]> git.lizzy.rs Git - rust.git/commitdiff
refactor memory write API to match read API
authorRalf Jung <post@ralfj.de>
Fri, 25 Aug 2017 16:25:05 +0000 (18:25 +0200)
committerRalf Jung <post@ralfj.de>
Fri, 25 Aug 2017 17:08:04 +0000 (19:08 +0200)
miri/fn_call.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/step.rs
src/librustc_mir/interpret/traits.rs

index cb7ee73e9961852d353014621fea4fbf7c2cbecd..7dc8f54849f0af0d359882f6bb7f3aabd5e9d45b 100644 (file)
@@ -421,11 +421,11 @@ fn call_c_abi(
                 if key_size.bits() < 128 && key >= (1u128 << key_size.bits() as u128) {
                     return err!(OutOfTls);
                 }
-                // TODO: Does this need checking for alignment?
-                self.memory.write_uint(
+                self.memory.write_primval(
                     key_ptr.to_ptr()?,
-                    key,
+                    PrimVal::Bytes(key),
                     key_size.bytes(),
+                    false,
                 )?;
 
                 // Return success (0)
index 1841e155405682328c423cd72c019f164c5deb54..19dc2bdf847d3246199f4ba4bbc9b072fe8bfba5 100644 (file)
@@ -579,12 +579,13 @@ pub fn assign_discr_and_fields(
         discr_val: u128,
         variant_idx: usize,
         discr_size: u64,
+        discr_signed: bool,
     ) -> EvalResult<'tcx> {
         // FIXME(solson)
         let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
 
         let discr_dest = dest_ptr.offset(discr_offset, &self)?;
-        self.memory.write_uint(discr_dest, discr_val, discr_size)?;
+        self.memory.write_primval(discr_dest, PrimVal::Bytes(discr_val), discr_size, discr_signed)?;
 
         let dest = Lvalue::Ptr {
             ptr: PtrAndAlign {
@@ -724,6 +725,7 @@ pub(super) fn eval_rvalue_into_lvalue(
                                 discr_val,
                                 variant,
                                 discr_size,
+                                false,
                             )?;
                         } else {
                             bug!("tried to assign {:?} to Layout::General", kind);
@@ -783,7 +785,8 @@ pub(super) fn eval_rvalue_into_lvalue(
                                 );
                                 self.memory.write_maybe_aligned_mut(
                                     !nonnull.packed,
-                                    |mem| mem.write_int(dest, 0, dest_size),
+                                    // The sign does not matter for 0
+                                    |mem| mem.write_primval(dest, PrimVal::Bytes(0), dest_size, false),
                                 )?;
                             }
                         } else {
@@ -1607,7 +1610,20 @@ pub fn write_value_to_ptr(
             }
             Value::ByVal(primval) => {
                 let size = self.type_size(dest_ty)?.expect("dest type must be sized");
-                self.memory.write_primval(dest, primval, size)
+                // TODO: This fn gets called with sizes like 6, which cannot be a primitive type
+                // and hence is not supported by write_primval.
+                // (E.g. in the arrays.rs testcase.)  That seems to only happen for Undef though,
+                // so we special-case that here.
+                match primval {
+                    PrimVal::Undef => {
+                        self.memory.mark_definedness(dest, size, false)?;
+                    }
+                    _ => {
+                        // TODO: Do we need signedness?
+                        self.memory.write_primval(dest.to_ptr()?, primval, size, false)?;
+                    }
+                }
+                Ok(())
             }
             Value::ByValPair(a, b) => self.write_pair_to_ptr(a, b, dest.to_ptr()?, dest_ty),
         }
@@ -1645,11 +1661,12 @@ pub fn write_pair_to_ptr(
         );
         let field_0_ptr = ptr.offset(field_0.bytes(), &self)?.into();
         let field_1_ptr = ptr.offset(field_1.bytes(), &self)?.into();
+        // TODO: What about signedess?
         self.write_maybe_aligned_mut(!packed, |ectx| {
-            ectx.memory.write_primval(field_0_ptr, a, field_0_size)
+            ectx.memory.write_primval(field_0_ptr, a, field_0_size, false)
         })?;
         self.write_maybe_aligned_mut(!packed, |ectx| {
-            ectx.memory.write_primval(field_1_ptr, b, field_1_size)
+            ectx.memory.write_primval(field_1_ptr, b, field_1_size, false)
         })?;
         Ok(())
     }
index d24f469de405ec17bc0f4d3122ea277cfd9e7973..d8a4ae66cf6792a1c793ab23e76257b9d4a7a965 100644 (file)
@@ -1206,20 +1206,15 @@ pub fn read_ptr_sized_unsigned(&self, ptr: MemoryPointer) -> EvalResult<'tcx, Pr
         self.read_primval(ptr, self.pointer_size(), false)
     }
 
-    pub fn write_ptr(&mut self, dest: MemoryPointer, ptr: MemoryPointer) -> EvalResult<'tcx> {
-        self.write_usize(dest, ptr.offset as u64)?;
-        self.get_mut(dest.alloc_id)?.relocations.insert(
-            dest.offset,
-            ptr.alloc_id,
-        );
-        Ok(())
-    }
+    pub fn write_primval(&mut self, ptr: MemoryPointer, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
+        trace!("Writing {:?}, size {}", val, size);
+        let align = self.int_align(size)?;
+        let endianess = self.endianess();
 
-    pub fn write_primval(&mut self, dest: Pointer, val: PrimVal, size: u64) -> EvalResult<'tcx> {
-        match val {
-            PrimVal::Ptr(ptr) => {
+        let bytes = match val {
+            PrimVal::Ptr(val) => {
                 assert_eq!(size, self.pointer_size());
-                self.write_ptr(dest.to_ptr()?, ptr)
+                val.offset as u128
             }
 
             PrimVal::Bytes(bytes) => {
@@ -1233,11 +1228,41 @@ pub fn write_primval(&mut self, dest: Pointer, val: PrimVal, size: u64) -> EvalR
                     16 => !0,
                     n => bug!("unexpected PrimVal::Bytes size: {}", n),
                 };
-                self.write_uint(dest.to_ptr()?, bytes & mask, size)
+                bytes & mask
             }
 
-            PrimVal::Undef => self.mark_definedness(dest, size, false),
+            PrimVal::Undef => {
+                self.mark_definedness(PrimVal::Ptr(ptr).into(), size, false)?;
+                return Ok(());
+            }
+        };
+
+        {
+            let dst = self.get_bytes_mut(ptr, size, align)?;
+            if signed {
+                write_target_int(endianess, dst, bytes as i128).unwrap();
+            } else {
+                write_target_uint(endianess, dst, bytes).unwrap();
+            }
+        }
+
+        // See if we have to also write a relocation
+        match val {
+            PrimVal::Ptr(val) => {
+                self.get_mut(ptr.alloc_id)?.relocations.insert(
+                    ptr.offset,
+                    val.alloc_id,
+                );
+            }
+            _ => {}
         }
+
+        Ok(())
+    }
+
+    pub fn write_ptr_sized_unsigned(&mut self, ptr: MemoryPointer, val: PrimVal) -> EvalResult<'tcx> {
+        let ptr_size = self.pointer_size();
+        self.write_primval(ptr, val, ptr_size, false)
     }
 
     pub fn read_bool(&self, ptr: MemoryPointer) -> EvalResult<'tcx, bool> {
@@ -1269,32 +1294,6 @@ fn int_align(&self, size: u64) -> EvalResult<'tcx, u64> {
         }
     }
 
-    pub fn write_int(&mut self, ptr: MemoryPointer, n: i128, size: u64) -> EvalResult<'tcx> {
-        let align = self.int_align(size)?;
-        let endianess = self.endianess();
-        let b = self.get_bytes_mut(ptr, size, align)?;
-        write_target_int(endianess, b, n).unwrap();
-        Ok(())
-    }
-
-    pub fn write_uint(&mut self, ptr: MemoryPointer, n: u128, size: u64) -> EvalResult<'tcx> {
-        let align = self.int_align(size)?;
-        let endianess = self.endianess();
-        let b = self.get_bytes_mut(ptr, size, align)?;
-        write_target_uint(endianess, b, n).unwrap();
-        Ok(())
-    }
-
-    pub fn write_isize(&mut self, ptr: MemoryPointer, n: i64) -> EvalResult<'tcx> {
-        let size = self.pointer_size();
-        self.write_int(ptr, n as i128, size)
-    }
-
-    pub fn write_usize(&mut self, ptr: MemoryPointer, n: u64) -> EvalResult<'tcx> {
-        let size = self.pointer_size();
-        self.write_uint(ptr, n as u128, size)
-    }
-
     pub fn write_f32(&mut self, ptr: MemoryPointer, f: f32) -> EvalResult<'tcx> {
         let endianess = self.endianess();
         let align = self.layout.f32_align.abi();
index c43ad18e0d874a6f770aedf6e3c53b66d059fe8c..9a6f72c7bfde02d1770ba18588127cb4e6609304 100644 (file)
@@ -12,7 +12,7 @@
 use rustc::ty::subst::Substs;
 
 use super::{EvalResult, EvalContext, StackPopCleanup, TyAndPacked, PtrAndAlign, GlobalId, Lvalue,
-            HasMemory, MemoryKind, Machine};
+            HasMemory, MemoryKind, Machine, PrimVal};
 
 use syntax::codemap::Span;
 use syntax::ast::Mutability;
@@ -106,10 +106,11 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
                     Layout::General { discr, .. } => {
                         let discr_size = discr.size().bytes();
                         let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
-                        self.memory.write_uint(
+                        self.memory.write_primval(
                             dest_ptr,
-                            variant_index as u128,
+                            PrimVal::Bytes(variant_index as u128),
                             discr_size,
+                            false
                         )?
                     }
 
@@ -124,6 +125,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
                         ref discrfield_source,
                         ..
                     } => {
+                        // TODO: There's some duplication between here and eval_rvalue_into_lvalue
                         if variant_index as u64 != nndiscr {
                             let (offset, TyAndPacked { ty, packed }) = self.nonnull_offset_and_ty(
                                 dest_ty,
@@ -140,7 +142,8 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
                                 "bad StructWrappedNullablePointer discrfield",
                             );
                             self.write_maybe_aligned_mut(!packed, |ectx| {
-                                ectx.memory.write_uint(nonnull, 0, discr_size)
+                                // We're writing 0, signedness does not matter
+                                ectx.memory.write_primval(nonnull, PrimVal::Bytes(0), discr_size, false)
                             })?;
                         }
                     }
@@ -229,7 +232,7 @@ fn global_item(
                 ptr_size,
                 MemoryKind::UninitializedStatic,
             )?;
-            self.memory.write_usize(ptr, 0)?;
+            self.memory.write_ptr_sized_unsigned(ptr, PrimVal::Bytes(0))?;
             self.memory.mark_static_initalized(ptr.alloc_id, mutability)?;
             self.globals.insert(
                 cid,
index 284e9811c9fd3f46f5efe47d4f265a2d691b7ec3..3f7e10a9eaff0bd929247141b34c3f4690300bfb 100644 (file)
@@ -63,19 +63,19 @@ pub fn get_vtable(
 
         let drop = eval_context::resolve_drop_in_place(self.tcx, ty);
         let drop = self.memory.create_fn_alloc(drop);
-        self.memory.write_ptr(vtable, drop)?;
+        self.memory.write_ptr_sized_unsigned(vtable, PrimVal::Ptr(drop))?;
 
         let size_ptr = vtable.offset(ptr_size, &self)?;
-        self.memory.write_usize(size_ptr, size)?;
+        self.memory.write_ptr_sized_unsigned(size_ptr, PrimVal::Bytes(size as u128))?;
         let align_ptr = vtable.offset(ptr_size * 2, &self)?;
-        self.memory.write_usize(align_ptr, align)?;
+        self.memory.write_ptr_sized_unsigned(align_ptr, PrimVal::Bytes(align as u128))?;
 
         for (i, method) in ::rustc::traits::get_vtable_methods(self.tcx, trait_ref).enumerate() {
             if let Some((def_id, substs)) = method {
                 let instance = eval_context::resolve(self.tcx, def_id, substs);
                 let fn_ptr = self.memory.create_fn_alloc(instance);
                 let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
-                self.memory.write_ptr(method_ptr, fn_ptr)?;
+                self.memory.write_ptr_sized_unsigned(method_ptr, PrimVal::Ptr(fn_ptr))?;
             }
         }