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