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