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    pub unsafe fn add(self, offset: usize) -> Self {
78        Self::new(self.ptr.add(offset), self.lazy_handle)
79    }
80
81    pub unsafe fn byte_add(self, offset: usize) -> Self {
82        Self::new(self.ptr.byte_add(offset), self.lazy_handle)
83    }
84
85    pub unsafe fn sub(self, offset: usize) -> Self {
86        Self::new(self.ptr.sub(offset), self.lazy_handle)
87    }
88
89    pub unsafe fn byte_sub(self, offset: usize) -> Self {
90        Self::new(self.ptr.byte_sub(offset), self.lazy_handle)
91    }
92}
93
94impl<'a, T> RefMut<'a, MaybeUninit<T>> {
95    pub fn write(self, val: T) -> RefMut<'a, T> {
96        unsafe {
97            let ptr = self.ptr.as_mut().unwrap_unchecked();
98            ptr.write(val);
99            self.cast()
100        }
101    }
102}
103
104impl<'obj, T: core::fmt::Debug> core::fmt::Debug for RefMut<'obj, T> {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        write!(f, "{:?}", self.deref())
107    }
108}
109
110impl<'obj, T> Deref for RefMut<'obj, T> {
111    type Target = T;
112
113    #[inline]
114    fn deref(&self) -> &Self::Target {
115        unsafe { self.ptr.as_ref().unwrap_unchecked() }
116    }
117}
118
119impl<'obj, T> DerefMut for RefMut<'obj, T> {
120    fn deref_mut(&mut self) -> &mut Self::Target {
121        unsafe { self.ptr.as_mut().unwrap_unchecked() }
122    }
123}
124
125impl<'a, T> AsMut<T> for RefMut<'a, T> {
126    fn as_mut(&mut self) -> &mut T {
127        &mut *self
128    }
129}
130
131impl<'a, T> Borrow<T> for RefMut<'a, T> {
132    fn borrow(&self) -> &T {
133        &*self
134    }
135}
136
137impl<'a, T> BorrowMut<T> for RefMut<'a, T> {
138    fn borrow_mut(&mut self) -> &mut T {
139        &mut *self
140    }
141}
142
143impl<'a, T> From<RefMut<'a, T>> for GlobalPtr<T> {
144    fn from(value: RefMut<'a, T>) -> Self {
145        GlobalPtr::new(value.handle().id(), value.offset())
146    }
147}
148
149impl<'a, T> Into<ObjectHandle> for RefMut<'a, T> {
150    fn into(self) -> ObjectHandle {
151        self.handle().clone()
152    }
153}
154
155impl<'a, T> Into<ObjectHandle> for &RefMut<'a, T> {
156    fn into(self) -> ObjectHandle {
157        self.handle().clone()
158    }
159}
160
161impl<'a, T> AsRef<ObjectHandle> for RefMut<'a, T> {
162    fn as_ref(&self) -> &ObjectHandle {
163        self.handle()
164    }
165}