1 use core::fmt;
2 use core::hash::{Hash, Hasher};
3 use core::ptr::{self, NonNull};
4 
5 /// A helper type in Wasmtime to store a raw pointer to `T` while automatically
6 /// inferring the `Send` and `Sync` traits for the container based on the
7 /// properties of `T`.
8 #[repr(transparent)]
9 pub struct SendSyncPtr<T: ?Sized>(NonNull<T>);
10 
11 unsafe impl<T: Send + ?Sized> Send for SendSyncPtr<T> {}
12 unsafe impl<T: Sync + ?Sized> Sync for SendSyncPtr<T> {}
13 
14 impl<T: ?Sized> SendSyncPtr<T> {
15     /// Creates a new pointer wrapping the non-nullable pointer provided.
16     #[inline]
new(ptr: NonNull<T>) -> SendSyncPtr<T>17     pub fn new(ptr: NonNull<T>) -> SendSyncPtr<T> {
18         SendSyncPtr(ptr)
19     }
20 
21     /// Returns the underlying raw pointer.
22     #[inline]
as_ptr(&self) -> *mut T23     pub fn as_ptr(&self) -> *mut T {
24         self.0.as_ptr()
25     }
26 
27     /// Unsafely assert that this is a pointer to valid contents and it's also
28     /// valid to get a shared reference to it at this time.
29     #[inline]
as_ref<'a>(&self) -> &'a T30     pub unsafe fn as_ref<'a>(&self) -> &'a T {
31         unsafe { self.0.as_ref() }
32     }
33 
34     /// Unsafely assert that this is a pointer to valid contents and it's also
35     /// valid to get a mutable reference to it at this time.
36     #[inline]
as_mut<'a>(&mut self) -> &'a mut T37     pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
38         unsafe { self.0.as_mut() }
39     }
40 
41     /// Returns the underlying `NonNull<T>` wrapper.
42     #[inline]
as_non_null(&self) -> NonNull<T>43     pub fn as_non_null(&self) -> NonNull<T> {
44         self.0
45     }
46 
47     /// Cast this to a pointer to a `U`.
48     #[inline]
cast<U>(&self) -> SendSyncPtr<U>49     pub fn cast<U>(&self) -> SendSyncPtr<U> {
50         SendSyncPtr(self.0.cast::<U>())
51     }
52 }
53 
54 impl<T> SendSyncPtr<[T]> {
55     /// Returns the slice's length component of the pointer.
56     #[inline]
len(&self) -> usize57     pub fn len(&self) -> usize {
58         self.0.len()
59     }
60 }
61 
62 impl<T: ?Sized, U> From<U> for SendSyncPtr<T>
63 where
64     U: Into<NonNull<T>>,
65 {
66     #[inline]
from(ptr: U) -> SendSyncPtr<T>67     fn from(ptr: U) -> SendSyncPtr<T> {
68         SendSyncPtr::new(ptr.into())
69     }
70 }
71 
72 impl<T: ?Sized> fmt::Debug for SendSyncPtr<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result73     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74         self.as_ptr().fmt(f)
75     }
76 }
77 
78 impl<T: ?Sized> fmt::Pointer for SendSyncPtr<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result79     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80         self.as_ptr().fmt(f)
81     }
82 }
83 
84 impl<T: ?Sized> Clone for SendSyncPtr<T> {
85     #[inline]
clone(&self) -> Self86     fn clone(&self) -> Self {
87         *self
88     }
89 }
90 
91 impl<T: ?Sized> Copy for SendSyncPtr<T> {}
92 
93 impl<T: ?Sized> PartialEq for SendSyncPtr<T> {
94     #[inline]
eq(&self, other: &SendSyncPtr<T>) -> bool95     fn eq(&self, other: &SendSyncPtr<T>) -> bool {
96         ptr::eq(self.0.as_ptr(), other.0.as_ptr())
97     }
98 }
99 
100 impl<T: ?Sized> Eq for SendSyncPtr<T> {}
101 
102 impl<T: ?Sized> Hash for SendSyncPtr<T> {
hash<H: Hasher>(&self, state: &mut H)103     fn hash<H: Hasher>(&self, state: &mut H) {
104         self.as_ptr().hash(state);
105     }
106 }
107