From 98cd2ad4ea84408ecd9d064f4bd90fe406fb7ddd Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 12 Nov 2018 08:30:52 +0100 Subject: [PATCH] Move some methods from `Memory` to `Allocation` --- src/librustc/mir/interpret/allocation.rs | 84 ++++++++++++++++++++++++ src/librustc_mir/interpret/memory.rs | 84 ------------------------ 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 3250ea266a58..1a88a959b4eb 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -49,6 +49,90 @@ pub struct Allocation { pub extra: Extra, } +/// Byte accessors +impl<'tcx, Tag, Extra> Allocation { + /// The last argument controls whether we error out when there are undefined + /// or pointer bytes. You should never call this, call `get_bytes` or + /// `get_bytes_with_undef_and_ptr` instead, + /// + /// This function also guarantees that the resulting pointer will remain stable + /// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies + /// on that. + fn get_bytes_internal( + &self, + ptr: Pointer, + size: Size, + align: Align, + check_defined_and_ptr: bool, + ) -> EvalResult<'tcx, &[u8]> { + assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); + self.check_align(ptr.into(), align)?; + self.check_bounds(ptr, size, InboundsCheck::Live)?; + + if check_defined_and_ptr { + self.check_defined(ptr, size)?; + self.check_relocations(ptr, size)?; + } else { + // We still don't want relocations on the *edges* + self.check_relocation_edges(ptr, size)?; + } + + let alloc = self.get(ptr.alloc_id)?; + AllocationExtra::memory_read(alloc, ptr, size)?; + + assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); + assert_eq!(size.bytes() as usize as u64, size.bytes()); + let offset = ptr.offset.bytes() as usize; + Ok(&alloc.bytes[offset..offset + size.bytes() as usize]) + } + + #[inline] + fn get_bytes( + &self, + ptr: Pointer, + size: Size, + align: Align + ) -> EvalResult<'tcx, &[u8]> { + self.get_bytes_internal(ptr, size, align, true) + } + + /// It is the caller's responsibility to handle undefined and pointer bytes. + /// However, this still checks that there are no relocations on the *edges*. + #[inline] + fn get_bytes_with_undef_and_ptr( + &self, + ptr: Pointer, + size: Size, + align: Align + ) -> EvalResult<'tcx, &[u8]> { + self.get_bytes_internal(ptr, size, align, false) + } + + /// Just calling this already marks everything as defined and removes relocations, + /// so be sure to actually put data there! + fn get_bytes_mut( + &mut self, + ptr: Pointer, + size: Size, + align: Align, + ) -> EvalResult<'tcx, &mut [u8]> { + assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); + self.check_align(ptr.into(), align)?; + self.check_bounds(ptr, size, InboundsCheck::Live)?; + + self.mark_definedness(ptr, size, true)?; + self.clear_relocations(ptr, size)?; + + let alloc = self.get_mut(ptr.alloc_id)?; + AllocationExtra::memory_written(alloc, ptr, size)?; + + assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); + assert_eq!(size.bytes() as usize as u64, size.bytes()); + let offset = ptr.offset.bytes() as usize; + Ok(&mut alloc.bytes[offset..offset + size.bytes() as usize]) + } +} + pub trait AllocationExtra: ::std::fmt::Debug + Default + Clone { /// Hook for performing extra checks on a memory read access. /// diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 898600d8322d..759892451bd9 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -609,90 +609,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } } -/// Byte accessors -impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { - /// The last argument controls whether we error out when there are undefined - /// or pointer bytes. You should never call this, call `get_bytes` or - /// `get_bytes_with_undef_and_ptr` instead, - /// - /// This function also guarantees that the resulting pointer will remain stable - /// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies - /// on that. - fn get_bytes_internal( - &self, - ptr: Pointer, - size: Size, - align: Align, - check_defined_and_ptr: bool, - ) -> EvalResult<'tcx, &[u8]> { - assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); - self.check_align(ptr.into(), align)?; - self.check_bounds(ptr, size, InboundsCheck::Live)?; - - if check_defined_and_ptr { - self.check_defined(ptr, size)?; - self.check_relocations(ptr, size)?; - } else { - // We still don't want relocations on the *edges* - self.check_relocation_edges(ptr, size)?; - } - - let alloc = self.get(ptr.alloc_id)?; - AllocationExtra::memory_read(alloc, ptr, size)?; - - assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); - assert_eq!(size.bytes() as usize as u64, size.bytes()); - let offset = ptr.offset.bytes() as usize; - Ok(&alloc.bytes[offset..offset + size.bytes() as usize]) - } - - #[inline] - fn get_bytes( - &self, - ptr: Pointer, - size: Size, - align: Align - ) -> EvalResult<'tcx, &[u8]> { - self.get_bytes_internal(ptr, size, align, true) - } - - /// It is the caller's responsibility to handle undefined and pointer bytes. - /// However, this still checks that there are no relocations on the *edges*. - #[inline] - fn get_bytes_with_undef_and_ptr( - &self, - ptr: Pointer, - size: Size, - align: Align - ) -> EvalResult<'tcx, &[u8]> { - self.get_bytes_internal(ptr, size, align, false) - } - - /// Just calling this already marks everything as defined and removes relocations, - /// so be sure to actually put data there! - fn get_bytes_mut( - &mut self, - ptr: Pointer, - size: Size, - align: Align, - ) -> EvalResult<'tcx, &mut [u8]> { - assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); - self.check_align(ptr.into(), align)?; - self.check_bounds(ptr, size, InboundsCheck::Live)?; - - self.mark_definedness(ptr, size, true)?; - self.clear_relocations(ptr, size)?; - - let alloc = self.get_mut(ptr.alloc_id)?; - AllocationExtra::memory_written(alloc, ptr, size)?; - - assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); - assert_eq!(size.bytes() as usize as u64, size.bytes()); - let offset = ptr.offset.bytes() as usize; - Ok(&mut alloc.bytes[offset..offset + size.bytes() as usize]) - } -} - /// Interning (for CTFE) impl<'a, 'mir, 'tcx, M> Memory<'a, 'mir, 'tcx, M> where