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::{marker::Invariant, object::RawObject};
9
10#[derive(Default, PartialEq, PartialOrd, Ord, Eq, Hash)]
11pub struct GlobalPtr<T> {
13 id: ObjID,
14 offset: u64,
15 _pd: PhantomData<*const T>,
16}
17
18unsafe impl<T: Invariant> Invariant for GlobalPtr<T> {}
19
20impl<T> Debug for GlobalPtr<T> {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 f.debug_struct("GlobalPtr")
23 .field("id", &self.id())
24 .field("offset", &self.offset())
25 .finish()
26 }
27}
28
29impl<T> GlobalPtr<T> {
30 pub fn new(id: ObjID, offset: u64) -> Self {
32 Self {
33 id,
34 offset,
35 _pd: PhantomData,
36 }
37 }
38
39 pub fn cast<U>(self) -> GlobalPtr<U> {
41 GlobalPtr::new(self.id, self.offset)
42 }
43
44 pub fn is_local(&self, place: impl AsRef<ObjectHandle>) -> bool {
46 place.as_ref().id() == self.id()
47 }
48
49 pub unsafe fn resolve_stable(&self) -> Ref<'_, T> {
56 let handle = twizzler_rt_abi::object::twz_rt_map_object(
57 self.id(),
58 MapFlags::READ | MapFlags::INDIRECT,
59 )
60 .expect("failed to map global pointer object");
61 let ptr = handle
62 .lea(self.offset() as usize, size_of::<T>())
63 .expect("failed to resolve global pointer");
64 Ref::from_handle(handle, ptr.cast())
65 }
66
67 pub unsafe fn resolve(&self) -> Ref<'_, T> {
74 let handle = twizzler_rt_abi::object::twz_rt_map_object(self.id(), MapFlags::READ)
75 .expect("failed to map global pointer object");
76 let ptr = handle
77 .lea(self.offset() as usize, size_of::<T>())
78 .expect("failed to resolve global pointer");
79 Ref::from_handle(handle, ptr.cast())
80 }
81
82 pub unsafe fn resolve_mut(&self) -> RefMut<'_, T> {
90 let handle = twizzler_rt_abi::object::twz_rt_map_object(
91 self.id(),
92 MapFlags::READ | MapFlags::WRITE | MapFlags::PERSIST,
93 )
94 .expect("failed to map global pointer object");
95 let ptr = handle
96 .lea_mut(self.offset() as usize, size_of::<T>())
97 .expect("failed to resolve global pointer");
98 RefMut::from_handle(handle, ptr.cast())
99 }
100
101 pub fn is_null(&self) -> bool {
103 self.id.raw() == 0
104 }
105
106 pub fn id(&self) -> ObjID {
108 self.id
109 }
110
111 pub fn offset(&self) -> u64 {
113 self.offset
114 }
115}
116
117impl<T> Clone for GlobalPtr<T> {
118 fn clone(&self) -> Self {
119 Self {
120 id: self.id,
121 offset: self.offset,
122 _pd: PhantomData,
123 }
124 }
125}
126
127impl<T> Copy for GlobalPtr<T> {}