twizzler/ptr/resolved/
resolved_mut.rs

1use std::{
2    borrow::{Borrow, BorrowMut},
3    marker::PhantomData,
4    mem::MaybeUninit,
5    ops::{Deref, DerefMut},
6};
7
8use twizzler_rt_abi::object::ObjectHandle;
9
10use super::{LazyHandle, Ref};
11use crate::{object::RawObject, ptr::GlobalPtr, util::maybe_remap};
12
13pub struct RefMut<'obj, T> {
14    ptr: *mut T,
15    pub(super) lazy_handle: LazyHandle<'obj>,
16    _pd: PhantomData<&'obj mut T>,
17}
18
19impl<'obj, T> RefMut<'obj, T> {
20    pub(super) fn new(ptr: *mut T, lazy_handle: LazyHandle<'obj>) -> Self {
21        Self {
22            ptr,
23            lazy_handle,
24            _pd: PhantomData,
25        }
26    }
27
28    #[inline]
29    pub fn raw(&self) -> *mut T {
30        self.ptr
31    }
32
33    pub unsafe fn from_raw_parts(ptr: *mut T, handle: &'obj ObjectHandle) -> Self {
34        Self::new(ptr, LazyHandle::new_borrowed(handle))
35    }
36
37    pub fn from_handle(handle: ObjectHandle, ptr: *mut T) -> Self {
38        let (handle, ptr) = maybe_remap(handle, ptr);
39        Self::new(ptr, LazyHandle::new_owned(handle))
40    }
41
42    #[inline]
43    pub unsafe fn from_ptr(ptr: *mut T) -> Self {
44        Self::new(ptr, LazyHandle::default())
45    }
46
47    #[inline]
48    pub unsafe fn cast<U>(self) -> RefMut<'obj, U> {
49        RefMut::new(self.ptr.cast(), self.lazy_handle)
50    }
51
52    pub fn handle(&self) -> &ObjectHandle {
53        self.lazy_handle.handle(self.ptr.cast())
54    }
55
56    pub fn offset(&self) -> u64 {
57        self.handle().ptr_local(self.ptr.cast()).unwrap() as u64
58    }
59
60    pub fn global(&self) -> GlobalPtr<T> {
61        GlobalPtr::new(self.handle().id(), self.offset())
62    }
63
64    // Note: takes ownership to avoid aliasing
65    pub fn owned<'b>(self) -> RefMut<'b, T> {
66        RefMut::from_handle(self.handle().clone(), self.ptr)
67    }
68
69    pub fn as_ref(&self) -> Ref<'obj, T> {
70        Ref::new(self.ptr, self.lazy_handle.clone())
71    }
72
73    pub fn into_ref(self) -> Ref<'obj, T> {
74        Ref::new(self.ptr, self.lazy_handle)
75    }
76}
77
78impl<'a, T> RefMut<'a, MaybeUninit<T>> {
79    pub fn write(self, val: T) -> RefMut<'a, T> {
80        unsafe {
81            let ptr = self.ptr.as_mut().unwrap_unchecked();
82            ptr.write(val);
83            self.cast()
84        }
85    }
86}
87
88impl<'obj, T: core::fmt::Debug> core::fmt::Debug for RefMut<'obj, T> {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        write!(f, "{:?}", self.deref())
91    }
92}
93
94impl<'obj, T> Deref for RefMut<'obj, T> {
95    type Target = T;
96
97    #[inline]
98    fn deref(&self) -> &Self::Target {
99        unsafe { self.ptr.as_ref().unwrap_unchecked() }
100    }
101}
102
103impl<'obj, T> DerefMut for RefMut<'obj, T> {
104    fn deref_mut(&mut self) -> &mut Self::Target {
105        unsafe { self.ptr.as_mut().unwrap_unchecked() }
106    }
107}
108
109impl<'a, T> AsMut<T> for RefMut<'a, T> {
110    fn as_mut(&mut self) -> &mut T {
111        &mut *self
112    }
113}
114
115impl<'a, T> Borrow<T> for RefMut<'a, T> {
116    fn borrow(&self) -> &T {
117        &*self
118    }
119}
120
121impl<'a, T> BorrowMut<T> for RefMut<'a, T> {
122    fn borrow_mut(&mut self) -> &mut T {
123        &mut *self
124    }
125}
126
127impl<'a, T> From<RefMut<'a, T>> for GlobalPtr<T> {
128    fn from(value: RefMut<'a, T>) -> Self {
129        GlobalPtr::new(value.handle().id(), value.offset())
130    }
131}
132
133impl<'a, T> Into<ObjectHandle> for RefMut<'a, T> {
134    fn into(self) -> ObjectHandle {
135        self.handle().clone()
136    }
137}
138
139impl<'a, T> Into<ObjectHandle> for &RefMut<'a, T> {
140    fn into(self) -> ObjectHandle {
141        self.handle().clone()
142    }
143}
144
145impl<'a, T> AsRef<ObjectHandle> for RefMut<'a, T> {
146    fn as_ref(&self) -> &ObjectHandle {
147        self.handle()
148    }
149}