xref: /wasmtime-44.0.1/crates/core/src/error/ptr.rs (revision 5afb6030)
1*8325e1ecSAlex Crichton //! Newtype wrappers over raw pointers that document ownership. We use these in
2*8325e1ecSAlex Crichton //! various places instead of safe references because our type-punning would
3*8325e1ecSAlex Crichton //! trigger UB otherwise.
4*8325e1ecSAlex Crichton 
5*8325e1ecSAlex Crichton use core::{marker::PhantomData, ptr::NonNull};
6*8325e1ecSAlex Crichton use std_alloc::boxed::Box;
7*8325e1ecSAlex Crichton 
8*8325e1ecSAlex Crichton /// A raw, owned pointer.
9*8325e1ecSAlex Crichton ///
10*8325e1ecSAlex Crichton /// You are required to call `T`'s `Drop` and deallocate the pointer, this won't
11*8325e1ecSAlex Crichton /// automatically do it for you like `Box`.
12*8325e1ecSAlex Crichton #[repr(transparent)]
13*8325e1ecSAlex Crichton pub(crate) struct OwnedPtr<T>
14*8325e1ecSAlex Crichton where
15*8325e1ecSAlex Crichton     T: ?Sized,
16*8325e1ecSAlex Crichton {
17*8325e1ecSAlex Crichton     ptr: NonNull<T>,
18*8325e1ecSAlex Crichton }
19*8325e1ecSAlex Crichton 
20*8325e1ecSAlex Crichton impl<T> OwnedPtr<T> {
new(ptr: NonNull<T>) -> Self21*8325e1ecSAlex Crichton     pub(crate) fn new(ptr: NonNull<T>) -> Self {
22*8325e1ecSAlex Crichton         OwnedPtr { ptr }
23*8325e1ecSAlex Crichton     }
24*8325e1ecSAlex Crichton 
cast<U>(self) -> OwnedPtr<U>25*8325e1ecSAlex Crichton     pub(crate) fn cast<U>(self) -> OwnedPtr<U> {
26*8325e1ecSAlex Crichton         OwnedPtr::new(self.ptr.cast())
27*8325e1ecSAlex Crichton     }
28*8325e1ecSAlex Crichton 
29*8325e1ecSAlex Crichton     /// Make a raw copy of this pointer.
raw_copy(&self) -> Self30*8325e1ecSAlex Crichton     pub(crate) fn raw_copy(&self) -> Self {
31*8325e1ecSAlex Crichton         Self::new(self.ptr)
32*8325e1ecSAlex Crichton     }
33*8325e1ecSAlex Crichton 
into_non_null(self) -> NonNull<T>34*8325e1ecSAlex Crichton     pub(crate) fn into_non_null(self) -> NonNull<T> {
35*8325e1ecSAlex Crichton         self.ptr
36*8325e1ecSAlex Crichton     }
37*8325e1ecSAlex Crichton 
38*8325e1ecSAlex Crichton     /// # Safety
39*8325e1ecSAlex Crichton     ///
40*8325e1ecSAlex Crichton     /// It must be valid to call `NonNull::<T>::as_ref` on our underlying pointer.
as_ref(&self) -> &T41*8325e1ecSAlex Crichton     pub(crate) unsafe fn as_ref(&self) -> &T {
42*8325e1ecSAlex Crichton         unsafe { self.ptr.as_ref() }
43*8325e1ecSAlex Crichton     }
44*8325e1ecSAlex Crichton 
45*8325e1ecSAlex Crichton     /// # Safety
46*8325e1ecSAlex Crichton     ///
47*8325e1ecSAlex Crichton     /// It must be valid to call `Box::<T>::from_raw` on our underlying pointer.
into_box(self) -> Box<T>48*8325e1ecSAlex Crichton     pub(crate) unsafe fn into_box(self) -> Box<T> {
49*8325e1ecSAlex Crichton         // Safety: same as our safety contract.
50*8325e1ecSAlex Crichton         unsafe { Box::from_raw(self.ptr.as_ptr()) }
51*8325e1ecSAlex Crichton     }
52*8325e1ecSAlex Crichton }
53*8325e1ecSAlex Crichton 
54*8325e1ecSAlex Crichton /// A raw pointer that is semantically a shared borrow.
55*8325e1ecSAlex Crichton #[repr(transparent)]
56*8325e1ecSAlex Crichton pub(crate) struct SharedPtr<'a, T>
57*8325e1ecSAlex Crichton where
58*8325e1ecSAlex Crichton     T: ?Sized,
59*8325e1ecSAlex Crichton {
60*8325e1ecSAlex Crichton     ptr: NonNull<T>,
61*8325e1ecSAlex Crichton     _lifetime: PhantomData<&'a T>,
62*8325e1ecSAlex Crichton }
63*8325e1ecSAlex Crichton 
64*8325e1ecSAlex Crichton impl<'a, T> core::fmt::Debug for SharedPtr<'a, T>
65*8325e1ecSAlex Crichton where
66*8325e1ecSAlex Crichton     T: ?Sized,
67*8325e1ecSAlex Crichton {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result68*8325e1ecSAlex Crichton     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69*8325e1ecSAlex Crichton         f.debug_struct("SharedPtr").field("ptr", &self.ptr).finish()
70*8325e1ecSAlex Crichton     }
71*8325e1ecSAlex Crichton }
72*8325e1ecSAlex Crichton 
73*8325e1ecSAlex Crichton impl<T> Clone for SharedPtr<'_, T>
74*8325e1ecSAlex Crichton where
75*8325e1ecSAlex Crichton     T: ?Sized,
76*8325e1ecSAlex Crichton {
clone(&self) -> Self77*8325e1ecSAlex Crichton     fn clone(&self) -> Self {
78*8325e1ecSAlex Crichton         *self
79*8325e1ecSAlex Crichton     }
80*8325e1ecSAlex Crichton }
81*8325e1ecSAlex Crichton 
82*8325e1ecSAlex Crichton impl<'a, T> SharedPtr<'a, T>
83*8325e1ecSAlex Crichton where
84*8325e1ecSAlex Crichton     T: ?Sized,
85*8325e1ecSAlex Crichton {
new(ptr: NonNull<T>) -> Self86*8325e1ecSAlex Crichton     pub(crate) fn new(ptr: NonNull<T>) -> Self {
87*8325e1ecSAlex Crichton         SharedPtr {
88*8325e1ecSAlex Crichton             ptr,
89*8325e1ecSAlex Crichton             _lifetime: PhantomData,
90*8325e1ecSAlex Crichton         }
91*8325e1ecSAlex Crichton     }
92*8325e1ecSAlex Crichton 
cast<U>(self) -> SharedPtr<'a, U>93*8325e1ecSAlex Crichton     pub(crate) fn cast<U>(self) -> SharedPtr<'a, U> {
94*8325e1ecSAlex Crichton         SharedPtr::new(self.ptr.cast())
95*8325e1ecSAlex Crichton     }
96*8325e1ecSAlex Crichton 
97*8325e1ecSAlex Crichton     /// # Safety
98*8325e1ecSAlex Crichton     ///
99*8325e1ecSAlex Crichton     /// It must be valid to call `NonNull::<T>::as_ref` on the underlying
100*8325e1ecSAlex Crichton     /// pointer.
as_ref(self) -> &'a T101*8325e1ecSAlex Crichton     pub(crate) unsafe fn as_ref(self) -> &'a T {
102*8325e1ecSAlex Crichton         unsafe { self.ptr.as_ref() }
103*8325e1ecSAlex Crichton     }
104*8325e1ecSAlex Crichton }
105*8325e1ecSAlex Crichton 
106*8325e1ecSAlex Crichton impl<T> Copy for SharedPtr<'_, T> where T: ?Sized {}
107*8325e1ecSAlex Crichton 
108*8325e1ecSAlex Crichton /// A raw pointer that is semantically an exclusive borrow.
109*8325e1ecSAlex Crichton #[repr(transparent)]
110*8325e1ecSAlex Crichton pub(crate) struct MutPtr<'a, T>
111*8325e1ecSAlex Crichton where
112*8325e1ecSAlex Crichton     T: ?Sized,
113*8325e1ecSAlex Crichton {
114*8325e1ecSAlex Crichton     ptr: NonNull<T>,
115*8325e1ecSAlex Crichton     _lifetime: PhantomData<&'a mut T>,
116*8325e1ecSAlex Crichton }
117*8325e1ecSAlex Crichton 
118*8325e1ecSAlex Crichton impl<'a, T> MutPtr<'a, T>
119*8325e1ecSAlex Crichton where
120*8325e1ecSAlex Crichton     T: ?Sized,
121*8325e1ecSAlex Crichton {
new(ptr: NonNull<T>) -> Self122*8325e1ecSAlex Crichton     pub(crate) fn new(ptr: NonNull<T>) -> Self {
123*8325e1ecSAlex Crichton         MutPtr {
124*8325e1ecSAlex Crichton             ptr,
125*8325e1ecSAlex Crichton             _lifetime: PhantomData,
126*8325e1ecSAlex Crichton         }
127*8325e1ecSAlex Crichton     }
128*8325e1ecSAlex Crichton 
129*8325e1ecSAlex Crichton     /// Make a raw copy of this pointer.
raw_copy(&self) -> Self130*8325e1ecSAlex Crichton     pub(crate) fn raw_copy(&self) -> Self {
131*8325e1ecSAlex Crichton         Self::new(self.ptr)
132*8325e1ecSAlex Crichton     }
133*8325e1ecSAlex Crichton 
cast<U>(self) -> MutPtr<'a, U>134*8325e1ecSAlex Crichton     pub(crate) fn cast<U>(self) -> MutPtr<'a, U> {
135*8325e1ecSAlex Crichton         MutPtr::new(self.ptr.cast())
136*8325e1ecSAlex Crichton     }
137*8325e1ecSAlex Crichton 
138*8325e1ecSAlex Crichton     /// # Safety
139*8325e1ecSAlex Crichton     ///
140*8325e1ecSAlex Crichton     /// It must be valid to call `NonNull::<T>::as_ref` on the underlying pointer.
as_ref(&self) -> &'a T141*8325e1ecSAlex Crichton     pub(crate) unsafe fn as_ref(&self) -> &'a T {
142*8325e1ecSAlex Crichton         unsafe { self.ptr.as_ref() }
143*8325e1ecSAlex Crichton     }
144*8325e1ecSAlex Crichton 
145*8325e1ecSAlex Crichton     /// # Safety
146*8325e1ecSAlex Crichton     ///
147*8325e1ecSAlex Crichton     /// It must be valid to call `NonNull::<T>::as_mut` on the underlying pointer.
as_mut(&mut self) -> &'a mut T148*8325e1ecSAlex Crichton     pub(crate) unsafe fn as_mut(&mut self) -> &'a mut T {
149*8325e1ecSAlex Crichton         unsafe { self.ptr.as_mut() }
150*8325e1ecSAlex Crichton     }
151*8325e1ecSAlex Crichton }
152