]> git.lizzy.rs Git - rust.git/commitdiff
Choose pointer size dynamically.
authorScott Olson <scott@solson.me>
Thu, 17 Mar 2016 13:53:26 +0000 (07:53 -0600)
committerScott Olson <scott@solson.me>
Thu, 17 Mar 2016 13:53:26 +0000 (07:53 -0600)
src/interpreter.rs
src/memory.rs

index afd6f78a0dca4794d1a762832e910bf2178a21e9..6c1144b6b9c16b1fac7b047822987f7f42033e87 100644 (file)
@@ -582,13 +582,13 @@ fn ty_to_repr(&self, ty: ty::Ty<'tcx>) -> &'arena Repr {
         use syntax::ast::{IntTy, UintTy};
         let repr = match ty.sty {
             ty::TyBool => Repr::Primitive { size: 1 },
-            ty::TyInt(IntTy::Is)  => Repr::isize(),
+            ty::TyInt(IntTy::Is)  => Repr::Primitive { size: self.memory.pointer_size },
             ty::TyInt(IntTy::I8)  => Repr::Primitive { size: 1 },
             ty::TyInt(IntTy::I16) => Repr::Primitive { size: 2 },
             ty::TyInt(IntTy::I32) => Repr::Primitive { size: 4 },
             ty::TyInt(IntTy::I64) => Repr::Primitive { size: 8 },
 
-            ty::TyUint(UintTy::Us)  => Repr::usize(),
+            ty::TyUint(UintTy::Us)  => Repr::Primitive { size: self.memory.pointer_size },
             ty::TyUint(UintTy::U8)  => Repr::Primitive { size: 1 },
             ty::TyUint(UintTy::U16) => Repr::Primitive { size: 2 },
             ty::TyUint(UintTy::U32) => Repr::Primitive { size: 4 },
@@ -613,9 +613,9 @@ fn ty_to_repr(&self, ty: ty::Ty<'tcx>) -> &'arena Repr {
             ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
             ty::TyBox(ty) => {
                 if ty.is_sized(&self.tcx.empty_parameter_environment(), DUMMY_SP) {
-                    Repr::Pointer
+                    Repr::Primitive { size: self.memory.pointer_size }
                 } else {
-                    Repr::FatPointer
+                    Repr::Primitive { size: self.memory.pointer_size * 2 }
                 }
             }
 
index d9d1a60111f410694050e7dc1b2a98c6de360a05..c563e84a90c5dc5d93f378dfdcd297a558e22108 100644 (file)
@@ -8,12 +8,10 @@
 use error::{EvalError, EvalResult};
 use primval::PrimVal;
 
-// TODO(tsion): How should this get set? Host or target pointer size?
-const POINTER_SIZE: usize = 8;
-
 pub struct Memory {
-    next_id: u64,
     alloc_map: HashMap<u64, Allocation>,
+    next_id: u64,
+    pub pointer_size: usize,
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -40,14 +38,11 @@ pub struct FieldRepr {
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum Repr {
-    /// Representation for a primitive type such as a boolean, integer, or character.
+    /// Representation for a non-aggregate type such as a boolean, integer, character or pointer.
     Primitive {
         size: usize
     },
 
-    Pointer,
-    FatPointer,
-
     /// The representation for aggregate types including structs, enums, and tuples.
     Aggregate {
         /// The size of the discriminant (an integer). Should be between 0 and 8. Always 0 for
@@ -71,7 +66,13 @@ pub enum Repr {
 
 impl Memory {
     pub fn new() -> Self {
-        Memory { next_id: 0, alloc_map: HashMap::new() }
+        Memory {
+            alloc_map: HashMap::new(),
+            next_id: 0,
+
+            // TODO(tsion): Should this be host's or target's usize?
+            pointer_size: mem::size_of::<usize>(),
+        }
     }
 
     pub fn allocate(&mut self, size: usize) -> Pointer {
@@ -145,8 +146,8 @@ pub fn copy(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<(
 
     pub fn read_ptr(&self, ptr: Pointer) -> EvalResult<Pointer> {
         let alloc = try!(self.get(ptr.alloc_id));
-        try!(alloc.check_relocation_edges(ptr.offset, ptr.offset + POINTER_SIZE));
-        let bytes = &alloc.bytes[ptr.offset..ptr.offset + POINTER_SIZE];
+        try!(alloc.check_relocation_edges(ptr.offset, ptr.offset + self.pointer_size));
+        let bytes = &alloc.bytes[ptr.offset..ptr.offset + self.pointer_size];
         let offset = byteorder::NativeEndian::read_u64(bytes) as usize;
 
         match alloc.relocations.get(&ptr.offset) {
@@ -158,7 +159,8 @@ pub fn read_ptr(&self, ptr: Pointer) -> EvalResult<Pointer> {
     // TODO(tsion): Detect invalid writes here and elsewhere.
     pub fn write_ptr(&mut self, dest: Pointer, ptr_val: Pointer) -> EvalResult<()> {
         {
-            let bytes = try!(self.get_bytes_mut(dest, POINTER_SIZE));
+            let size = self.pointer_size;
+            let bytes = try!(self.get_bytes_mut(dest, size));
             byteorder::NativeEndian::write_u64(bytes, ptr_val.offset as u64);
         }
         let alloc = try!(self.get_mut(dest.alloc_id));
@@ -180,8 +182,8 @@ pub fn read_primval(&self, ptr: Pointer, ty: ty::Ty) -> EvalResult<PrimVal> {
             ty::TyUint(UintTy::U64) => self.read_uint(ptr, 8).map(|n| PrimVal::U64(n as u64)),
 
             // TODO(tsion): Pick the PrimVal dynamically.
-            ty::TyInt(IntTy::Is)    => self.read_int(ptr, POINTER_SIZE).map(PrimVal::I64),
-            ty::TyUint(UintTy::Us)  => self.read_uint(ptr, POINTER_SIZE).map(PrimVal::U64),
+            ty::TyInt(IntTy::Is)    => self.read_int(ptr, self.pointer_size).map(PrimVal::I64),
+            ty::TyUint(UintTy::Us)  => self.read_uint(ptr, self.pointer_size).map(PrimVal::U64),
             _ => panic!("primitive read of non-primitive type: {:?}", ty),
         }
     }
@@ -241,7 +243,8 @@ fn check_bounds(&self, start: usize, end: usize) -> EvalResult<()> {
 
     fn count_overlapping_relocations(&self, start: usize, end: usize) -> usize {
         self.relocations.range(
-            Included(&start.saturating_sub(POINTER_SIZE - 1)),
+            // FIXME(tsion): Assuming pointer size is 8. Move this method to Memory.
+            Included(&start.saturating_sub(8 - 1)),
             Excluded(&end)
         ).count()
     }
@@ -275,23 +278,11 @@ pub fn offset(self, i: isize) -> Self {
 }
 
 impl Repr {
-    // TODO(tsion): Choice is based on host machine's type size. Should this be how miri works?
-    pub fn isize() -> Self {
-        Repr::Primitive { size: mem::size_of::<isize>() }
-    }
-
-    // TODO(tsion): Choice is based on host machine's type size. Should this be how miri works?
-    pub fn usize() -> Self {
-        Repr::Primitive { size: mem::size_of::<usize>() }
-    }
-
     pub fn size(&self) -> usize {
         match *self {
             Repr::Primitive { size } => size,
             Repr::Aggregate { size, .. } => size,
             Repr::Array { elem_size, length } => elem_size * length,
-            Repr::Pointer => POINTER_SIZE,
-            Repr::FatPointer => POINTER_SIZE * 2,
         }
     }
 }