twizzler/ptr/resolved/
resolved.rs

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