twizzler/ptr/
global.rs

1use core::fmt::Debug;
2use std::marker::PhantomData;
3
4use twizzler_abi::object::ObjID;
5use twizzler_rt_abi::object::{MapFlags, ObjectHandle};
6
7use super::{Ref, RefMut};
8use crate::object::RawObject;
9
10#[derive(Default, PartialEq, PartialOrd, Ord, Eq, Hash)]
11/// A global pointer, containing a fully qualified object ID and offset.
12pub struct GlobalPtr<T> {
13    id: ObjID,
14    offset: u64,
15    _pd: PhantomData<*const T>,
16}
17
18impl<T> Debug for GlobalPtr<T> {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        f.debug_struct("GlobalPtr")
21            .field("id", &self.id())
22            .field("offset", &self.offset())
23            .finish()
24    }
25}
26
27impl<T> GlobalPtr<T> {
28    /// Creates a new global pointer.
29    pub fn new(id: ObjID, offset: u64) -> Self {
30        Self {
31            id,
32            offset,
33            _pd: PhantomData,
34        }
35    }
36
37    /// Casts the global pointer to a different type.
38    pub fn cast<U>(self) -> GlobalPtr<U> {
39        GlobalPtr::new(self.id, self.offset)
40    }
41
42    /// Checks if the global pointer is local from the perspective of a given object.
43    pub fn is_local(&self, place: impl AsRef<ObjectHandle>) -> bool {
44        place.as_ref().id() == self.id()
45    }
46
47    /// Resolve a global pointer into a reference.
48    ///
49    /// # Safety
50    /// The underlying object must not mutate while the reference exists, unless
51    /// the underlying type is Sync + Send. The memory referenced by the pointer
52    /// must have an valid representation of the type.
53    pub unsafe fn resolve_stable(&self) -> Ref<'_, T> {
54        let handle = twizzler_rt_abi::object::twz_rt_map_object(
55            self.id(),
56            MapFlags::READ | MapFlags::INDIRECT,
57        )
58        .expect("failed to map global pointer object");
59        let ptr = handle
60            .lea(self.offset() as usize, size_of::<T>())
61            .expect("failed to resolve global pointer");
62        Ref::from_handle(handle, ptr.cast())
63    }
64
65    /// Resolve a global pointer into a reference.
66    ///
67    /// # Safety
68    /// The underlying object must not mutate while the reference exists, unless
69    /// the underlying type is Sync + Send. The memory referenced by the pointer
70    /// must have an valid representation of the type.
71    pub unsafe fn resolve(&self) -> Ref<'_, T> {
72        let handle = twizzler_rt_abi::object::twz_rt_map_object(self.id(), MapFlags::READ)
73            .expect("failed to map global pointer object");
74        let ptr = handle
75            .lea(self.offset() as usize, size_of::<T>())
76            .expect("failed to resolve global pointer");
77        Ref::from_handle(handle, ptr.cast())
78    }
79
80    /// Resolve a global pointer into a reference.
81    ///
82    /// # Safety
83    /// The underlying object must not mutate while the reference exists, unless
84    /// the underlying type is Sync + Send. The memory referenced by the pointer
85    /// must have an valid representation of the type. No other references may be
86    /// alive referring to the underlying data.
87    pub unsafe fn resolve_mut(&self) -> RefMut<'_, T> {
88        let handle = twizzler_rt_abi::object::twz_rt_map_object(
89            self.id(),
90            MapFlags::READ | MapFlags::WRITE | MapFlags::PERSIST,
91        )
92        .expect("failed to map global pointer object");
93        let ptr = handle
94            .lea_mut(self.offset() as usize, size_of::<T>())
95            .expect("failed to resolve global pointer");
96        RefMut::from_handle(handle, ptr.cast())
97    }
98
99    /// Returns true if the global pointer is null.
100    pub fn is_null(&self) -> bool {
101        self.id.raw() == 0
102    }
103
104    /// Returns the object ID of the global pointer.
105    pub fn id(&self) -> ObjID {
106        self.id
107    }
108
109    /// Returns the offset of the global pointer.
110    pub fn offset(&self) -> u64 {
111        self.offset
112    }
113}
114
115impl<T> Clone for GlobalPtr<T> {
116    fn clone(&self) -> Self {
117        Self {
118            id: self.id,
119            offset: self.offset,
120            _pd: PhantomData,
121        }
122    }
123}
124
125impl<T> Copy for GlobalPtr<T> {}