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