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)]
11pub 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 pub fn new(id: ObjID, offset: u64) -> Self {
30 Self {
31 id,
32 offset,
33 _pd: PhantomData,
34 }
35 }
36
37 pub fn cast<U>(self) -> GlobalPtr<U> {
39 GlobalPtr::new(self.id, self.offset)
40 }
41
42 pub fn is_local(&self, place: impl AsRef<ObjectHandle>) -> bool {
44 place.as_ref().id() == self.id()
45 }
46
47 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 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 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 pub fn is_null(&self) -> bool {
101 self.id.raw() == 0
102 }
103
104 pub fn id(&self) -> ObjID {
106 self.id
107 }
108
109 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> {}