1use core::{mem::MaybeUninit, ptr::NonNull, slice};
2
3use bytemuck::AnyBitPattern;
4
5use crate::{VmResult, vm_read_slice, vm_write_slice};
6
7pub trait VmPtr: Copy {
9 type Target;
11
12 #[doc(hidden)]
13 fn as_ptr(self) -> *const Self::Target;
14
15 fn nullable(self) -> Option<Self> {
17 if self.as_ptr().is_null() {
18 None
19 } else {
20 Some(self)
21 }
22 }
23
24 fn vm_read_uninit(self) -> VmResult<MaybeUninit<Self::Target>> {
28 let mut uninit = MaybeUninit::<Self::Target>::uninit();
29 vm_read_slice(self.as_ptr(), slice::from_mut(&mut uninit))?;
30 Ok(uninit)
31 }
32
33 fn vm_read(self) -> VmResult<Self::Target>
35 where
36 Self::Target: AnyBitPattern,
37 {
38 let uninit = self.vm_read_uninit()?;
39 Ok(unsafe { uninit.assume_init() })
41 }
42}
43
44impl<T> VmPtr for *const T {
45 type Target = T;
46
47 fn as_ptr(self) -> *const T {
48 self
49 }
50}
51
52impl<T> VmPtr for *mut T {
53 type Target = T;
54
55 fn as_ptr(self) -> *const T {
56 self
57 }
58}
59
60impl<T> VmPtr for NonNull<T> {
61 type Target = T;
62
63 fn as_ptr(self) -> *const T {
64 self.as_ptr()
65 }
66}
67
68pub trait VmMutPtr: VmPtr {
70 fn vm_write(self, value: Self::Target) -> VmResult {
72 vm_write_slice(self.as_ptr().cast_mut(), slice::from_ref(&value))
73 }
74}
75
76impl<T> VmMutPtr for *mut T {}
77
78impl<T> VmMutPtr for NonNull<T> {}