1c8cfa8d0SDanilo Krummrich // SPDX-License-Identifier: GPL-2.0 2c8cfa8d0SDanilo Krummrich 3c8cfa8d0SDanilo Krummrich //! Implementation of [`Box`]. 4c8cfa8d0SDanilo Krummrich 5c8cfa8d0SDanilo Krummrich #[allow(unused_imports)] // Used in doc comments. 6c8cfa8d0SDanilo Krummrich use super::allocator::{KVmalloc, Kmalloc, Vmalloc}; 7c8cfa8d0SDanilo Krummrich use super::{AllocError, Allocator, Flags}; 8c8cfa8d0SDanilo Krummrich use core::alloc::Layout; 9c8cfa8d0SDanilo Krummrich use core::fmt; 10c8cfa8d0SDanilo Krummrich use core::marker::PhantomData; 11c8cfa8d0SDanilo Krummrich use core::mem::ManuallyDrop; 12c8cfa8d0SDanilo Krummrich use core::mem::MaybeUninit; 13c8cfa8d0SDanilo Krummrich use core::ops::{Deref, DerefMut}; 14c8cfa8d0SDanilo Krummrich use core::pin::Pin; 15c8cfa8d0SDanilo Krummrich use core::ptr::NonNull; 16c8cfa8d0SDanilo Krummrich use core::result::Result; 17c8cfa8d0SDanilo Krummrich 18c8cfa8d0SDanilo Krummrich use crate::init::{InPlaceInit, InPlaceWrite, Init, PinInit}; 19c8cfa8d0SDanilo Krummrich use crate::types::ForeignOwnable; 20c8cfa8d0SDanilo Krummrich 21c8cfa8d0SDanilo Krummrich /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. 22c8cfa8d0SDanilo Krummrich /// 23c8cfa8d0SDanilo Krummrich /// This is the kernel's version of the Rust stdlib's `Box`. There are several differences, 24c8cfa8d0SDanilo Krummrich /// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not 25c8cfa8d0SDanilo Krummrich /// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`] 26c8cfa8d0SDanilo Krummrich /// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions 27c8cfa8d0SDanilo Krummrich /// that may allocate memory are fallible. 28c8cfa8d0SDanilo Krummrich /// 29c8cfa8d0SDanilo Krummrich /// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]. 30c8cfa8d0SDanilo Krummrich /// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]). 31c8cfa8d0SDanilo Krummrich /// 32c8cfa8d0SDanilo Krummrich /// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed. 33c8cfa8d0SDanilo Krummrich /// 34c8cfa8d0SDanilo Krummrich /// # Examples 35c8cfa8d0SDanilo Krummrich /// 36c8cfa8d0SDanilo Krummrich /// ``` 37c8cfa8d0SDanilo Krummrich /// let b = KBox::<u64>::new(24_u64, GFP_KERNEL)?; 38c8cfa8d0SDanilo Krummrich /// 39c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 40c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 41c8cfa8d0SDanilo Krummrich /// ``` 42c8cfa8d0SDanilo Krummrich /// 43c8cfa8d0SDanilo Krummrich /// ``` 44c8cfa8d0SDanilo Krummrich /// # use kernel::bindings; 45c8cfa8d0SDanilo Krummrich /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 46c8cfa8d0SDanilo Krummrich /// struct Huge([u8; SIZE]); 47c8cfa8d0SDanilo Krummrich /// 48c8cfa8d0SDanilo Krummrich /// assert!(KBox::<Huge>::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()); 49c8cfa8d0SDanilo Krummrich /// ``` 50c8cfa8d0SDanilo Krummrich /// 51c8cfa8d0SDanilo Krummrich /// ``` 52c8cfa8d0SDanilo Krummrich /// # use kernel::bindings; 53c8cfa8d0SDanilo Krummrich /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 54c8cfa8d0SDanilo Krummrich /// struct Huge([u8; SIZE]); 55c8cfa8d0SDanilo Krummrich /// 56c8cfa8d0SDanilo Krummrich /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 57c8cfa8d0SDanilo Krummrich /// ``` 58c8cfa8d0SDanilo Krummrich /// 59c8cfa8d0SDanilo Krummrich /// # Invariants 60c8cfa8d0SDanilo Krummrich /// 61c8cfa8d0SDanilo Krummrich /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 62c8cfa8d0SDanilo Krummrich /// zero-sized types, is a dangling, well aligned pointer. 63c8cfa8d0SDanilo Krummrich #[repr(transparent)] 64c8cfa8d0SDanilo Krummrich pub struct Box<T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>); 65c8cfa8d0SDanilo Krummrich 66c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 67c8cfa8d0SDanilo Krummrich /// 68c8cfa8d0SDanilo Krummrich /// # Examples 69c8cfa8d0SDanilo Krummrich /// 70c8cfa8d0SDanilo Krummrich /// ``` 71c8cfa8d0SDanilo Krummrich /// let b = KBox::new(24_u64, GFP_KERNEL)?; 72c8cfa8d0SDanilo Krummrich /// 73c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 74c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 75c8cfa8d0SDanilo Krummrich /// ``` 76c8cfa8d0SDanilo Krummrich pub type KBox<T> = Box<T, super::allocator::Kmalloc>; 77c8cfa8d0SDanilo Krummrich 78c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`Vmalloc`] allocator. 79c8cfa8d0SDanilo Krummrich /// 80c8cfa8d0SDanilo Krummrich /// # Examples 81c8cfa8d0SDanilo Krummrich /// 82c8cfa8d0SDanilo Krummrich /// ``` 83c8cfa8d0SDanilo Krummrich /// let b = VBox::new(24_u64, GFP_KERNEL)?; 84c8cfa8d0SDanilo Krummrich /// 85c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 86c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 87c8cfa8d0SDanilo Krummrich /// ``` 88c8cfa8d0SDanilo Krummrich pub type VBox<T> = Box<T, super::allocator::Vmalloc>; 89c8cfa8d0SDanilo Krummrich 90c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`KVmalloc`] allocator. 91c8cfa8d0SDanilo Krummrich /// 92c8cfa8d0SDanilo Krummrich /// # Examples 93c8cfa8d0SDanilo Krummrich /// 94c8cfa8d0SDanilo Krummrich /// ``` 95c8cfa8d0SDanilo Krummrich /// let b = KVBox::new(24_u64, GFP_KERNEL)?; 96c8cfa8d0SDanilo Krummrich /// 97c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 98c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 99c8cfa8d0SDanilo Krummrich /// ``` 100c8cfa8d0SDanilo Krummrich pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 101c8cfa8d0SDanilo Krummrich 102c8cfa8d0SDanilo Krummrich // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. 103c8cfa8d0SDanilo Krummrich unsafe impl<T, A> Send for Box<T, A> 104c8cfa8d0SDanilo Krummrich where 105c8cfa8d0SDanilo Krummrich T: Send + ?Sized, 106c8cfa8d0SDanilo Krummrich A: Allocator, 107c8cfa8d0SDanilo Krummrich { 108c8cfa8d0SDanilo Krummrich } 109c8cfa8d0SDanilo Krummrich 110c8cfa8d0SDanilo Krummrich // SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`. 111c8cfa8d0SDanilo Krummrich unsafe impl<T, A> Sync for Box<T, A> 112c8cfa8d0SDanilo Krummrich where 113c8cfa8d0SDanilo Krummrich T: Sync + ?Sized, 114c8cfa8d0SDanilo Krummrich A: Allocator, 115c8cfa8d0SDanilo Krummrich { 116c8cfa8d0SDanilo Krummrich } 117c8cfa8d0SDanilo Krummrich 118c8cfa8d0SDanilo Krummrich impl<T, A> Box<T, A> 119c8cfa8d0SDanilo Krummrich where 120c8cfa8d0SDanilo Krummrich T: ?Sized, 121c8cfa8d0SDanilo Krummrich A: Allocator, 122c8cfa8d0SDanilo Krummrich { 123c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` from a raw pointer. 124c8cfa8d0SDanilo Krummrich /// 125c8cfa8d0SDanilo Krummrich /// # Safety 126c8cfa8d0SDanilo Krummrich /// 127c8cfa8d0SDanilo Krummrich /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently 128c8cfa8d0SDanilo Krummrich /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the 129c8cfa8d0SDanilo Krummrich /// `Box`. 130c8cfa8d0SDanilo Krummrich /// 131c8cfa8d0SDanilo Krummrich /// For ZSTs, `raw` must be a dangling, well aligned pointer. 132c8cfa8d0SDanilo Krummrich #[inline] 133c8cfa8d0SDanilo Krummrich pub const unsafe fn from_raw(raw: *mut T) -> Self { 134c8cfa8d0SDanilo Krummrich // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function. 135c8cfa8d0SDanilo Krummrich // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer. 136c8cfa8d0SDanilo Krummrich Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData) 137c8cfa8d0SDanilo Krummrich } 138c8cfa8d0SDanilo Krummrich 139c8cfa8d0SDanilo Krummrich /// Consumes the `Box<T, A>` and returns a raw pointer. 140c8cfa8d0SDanilo Krummrich /// 141c8cfa8d0SDanilo Krummrich /// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive 142c8cfa8d0SDanilo Krummrich /// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the 143c8cfa8d0SDanilo Krummrich /// allocation, if any. 144c8cfa8d0SDanilo Krummrich /// 145c8cfa8d0SDanilo Krummrich /// # Examples 146c8cfa8d0SDanilo Krummrich /// 147c8cfa8d0SDanilo Krummrich /// ``` 148c8cfa8d0SDanilo Krummrich /// let x = KBox::new(24, GFP_KERNEL)?; 149c8cfa8d0SDanilo Krummrich /// let ptr = KBox::into_raw(x); 150c8cfa8d0SDanilo Krummrich /// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`. 151c8cfa8d0SDanilo Krummrich /// let x = unsafe { KBox::from_raw(ptr) }; 152c8cfa8d0SDanilo Krummrich /// 153c8cfa8d0SDanilo Krummrich /// assert_eq!(*x, 24); 154c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 155c8cfa8d0SDanilo Krummrich /// ``` 156c8cfa8d0SDanilo Krummrich #[inline] 157c8cfa8d0SDanilo Krummrich pub fn into_raw(b: Self) -> *mut T { 158c8cfa8d0SDanilo Krummrich ManuallyDrop::new(b).0.as_ptr() 159c8cfa8d0SDanilo Krummrich } 160c8cfa8d0SDanilo Krummrich 161c8cfa8d0SDanilo Krummrich /// Consumes and leaks the `Box<T, A>` and returns a mutable reference. 162c8cfa8d0SDanilo Krummrich /// 163c8cfa8d0SDanilo Krummrich /// See [`Box::into_raw`] for more details. 164c8cfa8d0SDanilo Krummrich #[inline] 165c8cfa8d0SDanilo Krummrich pub fn leak<'a>(b: Self) -> &'a mut T { 166c8cfa8d0SDanilo Krummrich // SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer 167c8cfa8d0SDanilo Krummrich // which points to an initialized instance of `T`. 168c8cfa8d0SDanilo Krummrich unsafe { &mut *Box::into_raw(b) } 169c8cfa8d0SDanilo Krummrich } 170c8cfa8d0SDanilo Krummrich } 171c8cfa8d0SDanilo Krummrich 172c8cfa8d0SDanilo Krummrich impl<T, A> Box<MaybeUninit<T>, A> 173c8cfa8d0SDanilo Krummrich where 174c8cfa8d0SDanilo Krummrich A: Allocator, 175c8cfa8d0SDanilo Krummrich { 176c8cfa8d0SDanilo Krummrich /// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`. 177c8cfa8d0SDanilo Krummrich /// 178c8cfa8d0SDanilo Krummrich /// It is undefined behavior to call this function while the value inside of `b` is not yet 179c8cfa8d0SDanilo Krummrich /// fully initialized. 180c8cfa8d0SDanilo Krummrich /// 181c8cfa8d0SDanilo Krummrich /// # Safety 182c8cfa8d0SDanilo Krummrich /// 183c8cfa8d0SDanilo Krummrich /// Callers must ensure that the value inside of `b` is in an initialized state. 184c8cfa8d0SDanilo Krummrich pub unsafe fn assume_init(self) -> Box<T, A> { 185c8cfa8d0SDanilo Krummrich let raw = Self::into_raw(self); 186c8cfa8d0SDanilo Krummrich 187c8cfa8d0SDanilo Krummrich // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements 188c8cfa8d0SDanilo Krummrich // of this function, the value inside the `Box` is in an initialized state. Hence, it is 189c8cfa8d0SDanilo Krummrich // safe to reconstruct the `Box` as `Box<T, A>`. 190c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(raw.cast()) } 191c8cfa8d0SDanilo Krummrich } 192c8cfa8d0SDanilo Krummrich 193c8cfa8d0SDanilo Krummrich /// Writes the value and converts to `Box<T, A>`. 194c8cfa8d0SDanilo Krummrich pub fn write(mut self, value: T) -> Box<T, A> { 195c8cfa8d0SDanilo Krummrich (*self).write(value); 196c8cfa8d0SDanilo Krummrich 197c8cfa8d0SDanilo Krummrich // SAFETY: We've just initialized `b`'s value. 198c8cfa8d0SDanilo Krummrich unsafe { self.assume_init() } 199c8cfa8d0SDanilo Krummrich } 200c8cfa8d0SDanilo Krummrich } 201c8cfa8d0SDanilo Krummrich 202c8cfa8d0SDanilo Krummrich impl<T, A> Box<T, A> 203c8cfa8d0SDanilo Krummrich where 204c8cfa8d0SDanilo Krummrich A: Allocator, 205c8cfa8d0SDanilo Krummrich { 206c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` and initializes its contents with `x`. 207c8cfa8d0SDanilo Krummrich /// 208c8cfa8d0SDanilo Krummrich /// New memory is allocated with `A`. The allocation may fail, in which case an error is 209c8cfa8d0SDanilo Krummrich /// returned. For ZSTs no memory is allocated. 210c8cfa8d0SDanilo Krummrich pub fn new(x: T, flags: Flags) -> Result<Self, AllocError> { 211c8cfa8d0SDanilo Krummrich let b = Self::new_uninit(flags)?; 212c8cfa8d0SDanilo Krummrich Ok(Box::write(b, x)) 213c8cfa8d0SDanilo Krummrich } 214c8cfa8d0SDanilo Krummrich 215c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` with uninitialized contents. 216c8cfa8d0SDanilo Krummrich /// 217c8cfa8d0SDanilo Krummrich /// New memory is allocated with `A`. The allocation may fail, in which case an error is 218c8cfa8d0SDanilo Krummrich /// returned. For ZSTs no memory is allocated. 219c8cfa8d0SDanilo Krummrich /// 220c8cfa8d0SDanilo Krummrich /// # Examples 221c8cfa8d0SDanilo Krummrich /// 222c8cfa8d0SDanilo Krummrich /// ``` 223c8cfa8d0SDanilo Krummrich /// let b = KBox::<u64>::new_uninit(GFP_KERNEL)?; 224c8cfa8d0SDanilo Krummrich /// let b = KBox::write(b, 24); 225c8cfa8d0SDanilo Krummrich /// 226c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 227c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 228c8cfa8d0SDanilo Krummrich /// ``` 229c8cfa8d0SDanilo Krummrich pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> { 230c8cfa8d0SDanilo Krummrich let layout = Layout::new::<MaybeUninit<T>>(); 231c8cfa8d0SDanilo Krummrich let ptr = A::alloc(layout, flags)?; 232c8cfa8d0SDanilo Krummrich 233c8cfa8d0SDanilo Krummrich // INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`, 234c8cfa8d0SDanilo Krummrich // which is sufficient in size and alignment for storing a `T`. 235c8cfa8d0SDanilo Krummrich Ok(Box(ptr.cast(), PhantomData)) 236c8cfa8d0SDanilo Krummrich } 237c8cfa8d0SDanilo Krummrich 238c8cfa8d0SDanilo Krummrich /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be 239c8cfa8d0SDanilo Krummrich /// pinned in memory and can't be moved. 240c8cfa8d0SDanilo Krummrich #[inline] 241c8cfa8d0SDanilo Krummrich pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> 242c8cfa8d0SDanilo Krummrich where 243c8cfa8d0SDanilo Krummrich A: 'static, 244c8cfa8d0SDanilo Krummrich { 245c8cfa8d0SDanilo Krummrich Ok(Self::new(x, flags)?.into()) 246c8cfa8d0SDanilo Krummrich } 247c8cfa8d0SDanilo Krummrich 248c8cfa8d0SDanilo Krummrich /// Forgets the contents (does not run the destructor), but keeps the allocation. 249c8cfa8d0SDanilo Krummrich fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> { 250c8cfa8d0SDanilo Krummrich let ptr = Self::into_raw(this); 251c8cfa8d0SDanilo Krummrich 252c8cfa8d0SDanilo Krummrich // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 253c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(ptr.cast()) } 254c8cfa8d0SDanilo Krummrich } 255c8cfa8d0SDanilo Krummrich 256c8cfa8d0SDanilo Krummrich /// Drops the contents, but keeps the allocation. 257c8cfa8d0SDanilo Krummrich /// 258c8cfa8d0SDanilo Krummrich /// # Examples 259c8cfa8d0SDanilo Krummrich /// 260c8cfa8d0SDanilo Krummrich /// ``` 261c8cfa8d0SDanilo Krummrich /// let value = KBox::new([0; 32], GFP_KERNEL)?; 262c8cfa8d0SDanilo Krummrich /// assert_eq!(*value, [0; 32]); 263c8cfa8d0SDanilo Krummrich /// let value = KBox::drop_contents(value); 264c8cfa8d0SDanilo Krummrich /// // Now we can re-use `value`: 265c8cfa8d0SDanilo Krummrich /// let value = KBox::write(value, [1; 32]); 266c8cfa8d0SDanilo Krummrich /// assert_eq!(*value, [1; 32]); 267c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 268c8cfa8d0SDanilo Krummrich /// ``` 269c8cfa8d0SDanilo Krummrich pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> { 270c8cfa8d0SDanilo Krummrich let ptr = this.0.as_ptr(); 271c8cfa8d0SDanilo Krummrich 272c8cfa8d0SDanilo Krummrich // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the 273c8cfa8d0SDanilo Krummrich // value stored in `this` again. 274c8cfa8d0SDanilo Krummrich unsafe { core::ptr::drop_in_place(ptr) }; 275c8cfa8d0SDanilo Krummrich 276c8cfa8d0SDanilo Krummrich Self::forget_contents(this) 277c8cfa8d0SDanilo Krummrich } 278c8cfa8d0SDanilo Krummrich 279c8cfa8d0SDanilo Krummrich /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. 280c8cfa8d0SDanilo Krummrich pub fn into_inner(b: Self) -> T { 281c8cfa8d0SDanilo Krummrich // SAFETY: By the type invariant `&*b` is valid for `read`. 282c8cfa8d0SDanilo Krummrich let value = unsafe { core::ptr::read(&*b) }; 283c8cfa8d0SDanilo Krummrich let _ = Self::forget_contents(b); 284c8cfa8d0SDanilo Krummrich value 285c8cfa8d0SDanilo Krummrich } 286c8cfa8d0SDanilo Krummrich } 287c8cfa8d0SDanilo Krummrich 288c8cfa8d0SDanilo Krummrich impl<T, A> From<Box<T, A>> for Pin<Box<T, A>> 289c8cfa8d0SDanilo Krummrich where 290c8cfa8d0SDanilo Krummrich T: ?Sized, 291c8cfa8d0SDanilo Krummrich A: Allocator, 292c8cfa8d0SDanilo Krummrich { 293c8cfa8d0SDanilo Krummrich /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then 294c8cfa8d0SDanilo Krummrich /// `*b` will be pinned in memory and can't be moved. 295c8cfa8d0SDanilo Krummrich /// 296c8cfa8d0SDanilo Krummrich /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. 297c8cfa8d0SDanilo Krummrich fn from(b: Box<T, A>) -> Self { 298c8cfa8d0SDanilo Krummrich // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long 299c8cfa8d0SDanilo Krummrich // as `T` does not implement `Unpin`. 300c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(b) } 301c8cfa8d0SDanilo Krummrich } 302c8cfa8d0SDanilo Krummrich } 303c8cfa8d0SDanilo Krummrich 304c8cfa8d0SDanilo Krummrich impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A> 305c8cfa8d0SDanilo Krummrich where 306c8cfa8d0SDanilo Krummrich A: Allocator + 'static, 307c8cfa8d0SDanilo Krummrich { 308c8cfa8d0SDanilo Krummrich type Initialized = Box<T, A>; 309c8cfa8d0SDanilo Krummrich 310c8cfa8d0SDanilo Krummrich fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { 311c8cfa8d0SDanilo Krummrich let slot = self.as_mut_ptr(); 312c8cfa8d0SDanilo Krummrich // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 313c8cfa8d0SDanilo Krummrich // slot is valid. 314c8cfa8d0SDanilo Krummrich unsafe { init.__init(slot)? }; 315c8cfa8d0SDanilo Krummrich // SAFETY: All fields have been initialized. 316c8cfa8d0SDanilo Krummrich Ok(unsafe { Box::assume_init(self) }) 317c8cfa8d0SDanilo Krummrich } 318c8cfa8d0SDanilo Krummrich 319c8cfa8d0SDanilo Krummrich fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { 320c8cfa8d0SDanilo Krummrich let slot = self.as_mut_ptr(); 321c8cfa8d0SDanilo Krummrich // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 322c8cfa8d0SDanilo Krummrich // slot is valid and will not be moved, because we pin it later. 323c8cfa8d0SDanilo Krummrich unsafe { init.__pinned_init(slot)? }; 324c8cfa8d0SDanilo Krummrich // SAFETY: All fields have been initialized. 325c8cfa8d0SDanilo Krummrich Ok(unsafe { Box::assume_init(self) }.into()) 326c8cfa8d0SDanilo Krummrich } 327c8cfa8d0SDanilo Krummrich } 328c8cfa8d0SDanilo Krummrich 329c8cfa8d0SDanilo Krummrich impl<T, A> InPlaceInit<T> for Box<T, A> 330c8cfa8d0SDanilo Krummrich where 331c8cfa8d0SDanilo Krummrich A: Allocator + 'static, 332c8cfa8d0SDanilo Krummrich { 333c8cfa8d0SDanilo Krummrich type PinnedSelf = Pin<Self>; 334c8cfa8d0SDanilo Krummrich 335c8cfa8d0SDanilo Krummrich #[inline] 336c8cfa8d0SDanilo Krummrich fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> 337c8cfa8d0SDanilo Krummrich where 338c8cfa8d0SDanilo Krummrich E: From<AllocError>, 339c8cfa8d0SDanilo Krummrich { 340c8cfa8d0SDanilo Krummrich Box::<_, A>::new_uninit(flags)?.write_pin_init(init) 341c8cfa8d0SDanilo Krummrich } 342c8cfa8d0SDanilo Krummrich 343c8cfa8d0SDanilo Krummrich #[inline] 344c8cfa8d0SDanilo Krummrich fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 345c8cfa8d0SDanilo Krummrich where 346c8cfa8d0SDanilo Krummrich E: From<AllocError>, 347c8cfa8d0SDanilo Krummrich { 348c8cfa8d0SDanilo Krummrich Box::<_, A>::new_uninit(flags)?.write_init(init) 349c8cfa8d0SDanilo Krummrich } 350c8cfa8d0SDanilo Krummrich } 351c8cfa8d0SDanilo Krummrich 352c8cfa8d0SDanilo Krummrich impl<T: 'static, A> ForeignOwnable for Box<T, A> 353c8cfa8d0SDanilo Krummrich where 354c8cfa8d0SDanilo Krummrich A: Allocator, 355c8cfa8d0SDanilo Krummrich { 356c8cfa8d0SDanilo Krummrich type Borrowed<'a> = &'a T; 357c8cfa8d0SDanilo Krummrich 358*d072acdaSGary Guo fn into_foreign(self) -> *const crate::ffi::c_void { 359c8cfa8d0SDanilo Krummrich Box::into_raw(self) as _ 360c8cfa8d0SDanilo Krummrich } 361c8cfa8d0SDanilo Krummrich 362*d072acdaSGary Guo unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { 363c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 364c8cfa8d0SDanilo Krummrich // call to `Self::into_foreign`. 365c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(ptr as _) } 366c8cfa8d0SDanilo Krummrich } 367c8cfa8d0SDanilo Krummrich 368*d072acdaSGary Guo unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T { 369c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this method ensure that the object remains alive and 370c8cfa8d0SDanilo Krummrich // immutable for the duration of 'a. 371c8cfa8d0SDanilo Krummrich unsafe { &*ptr.cast() } 372c8cfa8d0SDanilo Krummrich } 373c8cfa8d0SDanilo Krummrich } 374c8cfa8d0SDanilo Krummrich 375c8cfa8d0SDanilo Krummrich impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 376c8cfa8d0SDanilo Krummrich where 377c8cfa8d0SDanilo Krummrich A: Allocator, 378c8cfa8d0SDanilo Krummrich { 379c8cfa8d0SDanilo Krummrich type Borrowed<'a> = Pin<&'a T>; 380c8cfa8d0SDanilo Krummrich 381*d072acdaSGary Guo fn into_foreign(self) -> *const crate::ffi::c_void { 382c8cfa8d0SDanilo Krummrich // SAFETY: We are still treating the box as pinned. 383c8cfa8d0SDanilo Krummrich Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ 384c8cfa8d0SDanilo Krummrich } 385c8cfa8d0SDanilo Krummrich 386*d072acdaSGary Guo unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { 387c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 388c8cfa8d0SDanilo Krummrich // call to `Self::into_foreign`. 389c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } 390c8cfa8d0SDanilo Krummrich } 391c8cfa8d0SDanilo Krummrich 392*d072acdaSGary Guo unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> { 393c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements for this function ensure that the object is still alive, 394c8cfa8d0SDanilo Krummrich // so it is safe to dereference the raw pointer. 395c8cfa8d0SDanilo Krummrich // The safety requirements of `from_foreign` also ensure that the object remains alive for 396c8cfa8d0SDanilo Krummrich // the lifetime of the returned value. 397c8cfa8d0SDanilo Krummrich let r = unsafe { &*ptr.cast() }; 398c8cfa8d0SDanilo Krummrich 399c8cfa8d0SDanilo Krummrich // SAFETY: This pointer originates from a `Pin<Box<T>>`. 400c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(r) } 401c8cfa8d0SDanilo Krummrich } 402c8cfa8d0SDanilo Krummrich } 403c8cfa8d0SDanilo Krummrich 404c8cfa8d0SDanilo Krummrich impl<T, A> Deref for Box<T, A> 405c8cfa8d0SDanilo Krummrich where 406c8cfa8d0SDanilo Krummrich T: ?Sized, 407c8cfa8d0SDanilo Krummrich A: Allocator, 408c8cfa8d0SDanilo Krummrich { 409c8cfa8d0SDanilo Krummrich type Target = T; 410c8cfa8d0SDanilo Krummrich 411c8cfa8d0SDanilo Krummrich fn deref(&self) -> &T { 412c8cfa8d0SDanilo Krummrich // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 413c8cfa8d0SDanilo Krummrich // instance of `T`. 414c8cfa8d0SDanilo Krummrich unsafe { self.0.as_ref() } 415c8cfa8d0SDanilo Krummrich } 416c8cfa8d0SDanilo Krummrich } 417c8cfa8d0SDanilo Krummrich 418c8cfa8d0SDanilo Krummrich impl<T, A> DerefMut for Box<T, A> 419c8cfa8d0SDanilo Krummrich where 420c8cfa8d0SDanilo Krummrich T: ?Sized, 421c8cfa8d0SDanilo Krummrich A: Allocator, 422c8cfa8d0SDanilo Krummrich { 423c8cfa8d0SDanilo Krummrich fn deref_mut(&mut self) -> &mut T { 424c8cfa8d0SDanilo Krummrich // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 425c8cfa8d0SDanilo Krummrich // instance of `T`. 426c8cfa8d0SDanilo Krummrich unsafe { self.0.as_mut() } 427c8cfa8d0SDanilo Krummrich } 428c8cfa8d0SDanilo Krummrich } 429c8cfa8d0SDanilo Krummrich 430c8cfa8d0SDanilo Krummrich impl<T, A> fmt::Debug for Box<T, A> 431c8cfa8d0SDanilo Krummrich where 432c8cfa8d0SDanilo Krummrich T: ?Sized + fmt::Debug, 433c8cfa8d0SDanilo Krummrich A: Allocator, 434c8cfa8d0SDanilo Krummrich { 435c8cfa8d0SDanilo Krummrich fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 436c8cfa8d0SDanilo Krummrich fmt::Debug::fmt(&**self, f) 437c8cfa8d0SDanilo Krummrich } 438c8cfa8d0SDanilo Krummrich } 439c8cfa8d0SDanilo Krummrich 440c8cfa8d0SDanilo Krummrich impl<T, A> Drop for Box<T, A> 441c8cfa8d0SDanilo Krummrich where 442c8cfa8d0SDanilo Krummrich T: ?Sized, 443c8cfa8d0SDanilo Krummrich A: Allocator, 444c8cfa8d0SDanilo Krummrich { 445c8cfa8d0SDanilo Krummrich fn drop(&mut self) { 446c8cfa8d0SDanilo Krummrich let layout = Layout::for_value::<T>(self); 447c8cfa8d0SDanilo Krummrich 448c8cfa8d0SDanilo Krummrich // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. 449c8cfa8d0SDanilo Krummrich unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) }; 450c8cfa8d0SDanilo Krummrich 451c8cfa8d0SDanilo Krummrich // SAFETY: 452c8cfa8d0SDanilo Krummrich // - `self.0` was previously allocated with `A`. 453c8cfa8d0SDanilo Krummrich // - `layout` is equal to the `Layout´ `self.0` was allocated with. 454c8cfa8d0SDanilo Krummrich unsafe { A::free(self.0.cast(), layout) }; 455c8cfa8d0SDanilo Krummrich } 456c8cfa8d0SDanilo Krummrich } 457