1 use crate::error::OutOfMemory; 2 use crate::prelude::*; 3 use crate::runtime::vm::SendSyncPtr; 4 use core::ptr::NonNull; 5 6 /// A `Box<T>` lookalike for memory that's stored in a `Store<T>` 7 /// 8 /// This is intended to be quite similar to a `Box<T>` except without the 9 /// `Deref` implementations. The main motivation for this type's existence is to 10 /// appease the aliasing rules in miri to ensure that `StoreBox` can be moved 11 /// around without invalidating pointers to the contents within the box. The 12 /// standard `Box<T>` type does not implement this for example and moving that 13 /// will invalidate derived pointers. 14 pub struct StoreBox<T: ?Sized>(SendSyncPtr<T>); 15 16 impl<T> StoreBox<T> { 17 /// Allocates space on the heap to store `val` and returns a pointer to it 18 /// living on the heap. new(val: T) -> Result<StoreBox<T>, OutOfMemory>19 pub fn new(val: T) -> Result<StoreBox<T>, OutOfMemory> { 20 let ptr = Box::into_raw(try_new(val)?); 21 Ok(StoreBox(SendSyncPtr::from(NonNull::new(ptr).unwrap()))) 22 } 23 } 24 25 impl<T: ?Sized> StoreBox<T> { 26 /// Returns the underlying pointer to `T` which is owned by the store. get(&self) -> NonNull<T>27 pub fn get(&self) -> NonNull<T> { 28 self.0.as_non_null() 29 } 30 } 31 32 impl<T: ?Sized> Drop for StoreBox<T> { drop(&mut self)33 fn drop(&mut self) { 34 unsafe { 35 drop(Box::from_raw(self.0.as_ptr())); 36 } 37 } 38 } 39