Skip to main content

starry_vm/
thin.rs

1use core::{mem::MaybeUninit, ptr::NonNull, slice};
2
3use bytemuck::AnyBitPattern;
4
5use crate::{VmResult, vm_read_slice, vm_write_slice};
6
7/// A virtual memory pointer.
8pub trait VmPtr: Copy {
9    /// The type of data that the pointer points to.
10    type Target;
11
12    #[doc(hidden)]
13    fn as_ptr(self) -> *const Self::Target;
14
15    /// Returns `None` if the pointer is null, otherwise returns `Some(self)`.
16    fn nullable(self) -> Option<Self> {
17        if self.as_ptr().is_null() {
18            None
19        } else {
20            Some(self)
21        }
22    }
23
24    /// Reads the value from this virtual memory pointer. In contrast to
25    /// [`VmPtr::vm_read`], this does not require that the value has to be
26    /// initialized.
27    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    /// Reads the value from this virtual memory pointer.
34    fn vm_read(self) -> VmResult<Self::Target>
35    where
36        Self::Target: AnyBitPattern,
37    {
38        let uninit = self.vm_read_uninit()?;
39        // SAFETY: `AnyBitPattern`
40        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
68/// A mutable virtual memory pointer.
69pub trait VmMutPtr: VmPtr {
70    /// Overwrites a virtual memory location with the given value.
71    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> {}