1use core::fmt::Debug;
2use std::marker::PhantomData;
3
4use twizzler_rt_abi::object::{MapFlags, ObjID, ObjectHandle};
5
6use super::{Ref, RefMut};
7use crate::{marker::Invariant, object::RawObject};
8
9#[derive(Default, PartialOrd, Ord, Hash)]
10pub struct GlobalPtr<T> {
12 id: ObjID,
13 offset: u64,
14 _pd: PhantomData<*const T>,
15}
16
17impl<T> Eq for GlobalPtr<T> {}
18
19impl<T> PartialEq for GlobalPtr<T> {
20 fn eq(&self, other: &Self) -> bool {
21 self.id == other.id && self.offset() == other.offset()
22 }
23}
24
25unsafe impl<T: Invariant> Invariant for GlobalPtr<T> {}
26
27impl<T> Debug for GlobalPtr<T> {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("GlobalPtr")
30 .field("id", &self.id())
31 .field("offset", &self.offset())
32 .finish()
33 }
34}
35
36impl<T> GlobalPtr<T> {
37 pub fn new(id: ObjID, offset: u64) -> Self {
39 Self {
40 id,
41 offset,
42 _pd: PhantomData,
43 }
44 }
45
46 pub fn cast<U>(self) -> GlobalPtr<U> {
48 GlobalPtr::new(self.id, self.offset)
49 }
50
51 pub fn is_local(&self, place: impl AsRef<ObjectHandle>) -> bool {
53 place.as_ref().id() == self.id()
54 }
55
56 pub unsafe fn resolve_stable(&self) -> Ref<'_, T> {
63 let handle = twizzler_rt_abi::object::twz_rt_map_object(
64 self.id(),
65 MapFlags::READ | MapFlags::INDIRECT,
66 )
67 .expect("failed to map global pointer object");
68 let ptr = handle
69 .lea(self.offset() as usize, size_of::<T>())
70 .expect("failed to resolve global pointer");
71 Ref::from_handle(handle, ptr.cast())
72 }
73
74 pub unsafe fn resolve(&self) -> Ref<'_, T> {
81 let handle = twizzler_rt_abi::object::twz_rt_map_object(self.id(), MapFlags::READ)
82 .expect("failed to map global pointer object");
83 let ptr = handle
84 .lea(self.offset() as usize, size_of::<T>())
85 .expect("failed to resolve global pointer");
86 Ref::from_handle(handle, ptr.cast())
87 }
88
89 pub unsafe fn resolve_mut(&self) -> RefMut<'_, T> {
97 let handle = twizzler_rt_abi::object::twz_rt_map_object(
98 self.id(),
99 MapFlags::READ | MapFlags::WRITE | MapFlags::PERSIST,
100 )
101 .expect("failed to map global pointer object");
102 let ptr = handle
103 .lea_mut(self.offset() as usize, size_of::<T>())
104 .expect("failed to resolve global pointer");
105 RefMut::from_handle(handle, ptr.cast())
106 }
107
108 pub fn is_null(&self) -> bool {
110 self.id.raw() == 0
111 }
112
113 pub fn id(&self) -> ObjID {
115 self.id
116 }
117
118 pub fn offset(&self) -> u64 {
120 self.offset
121 }
122}
123
124impl<T> Clone for GlobalPtr<T> {
125 fn clone(&self) -> Self {
126 Self {
127 id: self.id,
128 offset: self.offset,
129 _pd: PhantomData,
130 }
131 }
132}
133
134impl<T> Copy for GlobalPtr<T> {}