macroassembler/wtf/
code_ptr.rs

1use std::marker::PhantomData;
2
3pub struct CodePtr<PtrTag> {
4    value: *mut u8,
5    marker: PhantomData<PtrTag>,
6}
7
8impl<PtrTag> CodePtr<PtrTag> {
9    pub fn new(value: *mut u8) -> Self {
10        CodePtr {
11            value,
12            marker: PhantomData,
13        }
14    }
15
16    pub fn get(&self) -> *mut u8 {
17        self.value
18    }
19
20    pub fn set(&mut self, value: *mut u8) {
21        self.value = value;
22    }
23
24    pub fn as_usize(&self) -> usize {
25        self.value as usize
26    }
27
28    pub fn from_usize(value: usize) -> Self {
29        CodePtr {
30            value: value as *mut u8,
31            marker: PhantomData,
32        }
33    }
34
35    pub fn as_ptr(&self) -> *const u8 {
36        self.value
37    }
38
39    pub fn as_mut_ptr(&mut self) -> *mut u8 {
40        self.value
41    }
42
43    pub fn as_ptr_tag(&self) -> *const PtrTag {
44        self.value as *const PtrTag
45    }
46
47    pub fn as_mut_ptr_tag(&mut self) -> *mut PtrTag {
48        self.value as *mut PtrTag
49    }
50
51    pub fn is_null(&self) -> bool {
52        self.value.is_null()
53    }
54
55    pub fn is_not_null(&self) -> bool {
56        !self.value.is_null()
57    }
58
59    pub fn data_location(&self) -> *mut u8 {
60        self.value
61    }
62}
63
64impl<PtrTag> Clone for CodePtr<PtrTag> {
65    fn clone(&self) -> Self {
66        CodePtr {
67            value: self.value,
68            marker: PhantomData,
69        }
70    }
71}
72
73impl<PtrTag> Copy for CodePtr<PtrTag> {}
74
75impl<PtrTag> PartialEq for CodePtr<PtrTag> {
76    fn eq(&self, other: &Self) -> bool {
77        self.value == other.value
78    }
79}
80
81impl<PtrTag> Eq for CodePtr<PtrTag> {}
82
83impl<PtrTag> std::fmt::Debug for CodePtr<PtrTag> {
84    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
85        write!(f, "CodePtr({:p})", self.value)
86    }
87}
88
89impl<PtrTag> std::fmt::Pointer for CodePtr<PtrTag> {
90    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
91        write!(f, "{:p}", self.value)
92    }
93}
94
95impl<PtrTag> std::hash::Hash for CodePtr<PtrTag> {
96    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
97        self.value.hash(state);
98    }
99}
100
101impl<PtrTag> std::ops::Add<usize> for CodePtr<PtrTag> {
102    type Output = Self;
103
104    fn add(self, rhs: usize) -> Self::Output {
105        CodePtr {
106            value: unsafe { self.value.offset(rhs as isize) },
107            marker: PhantomData,
108        }
109    }
110}
111
112impl<PtrTag> std::ops::AddAssign<usize> for CodePtr<PtrTag> {
113    fn add_assign(&mut self, rhs: usize) {
114        self.value = unsafe { self.value.offset(rhs as isize) };
115    }
116}
117
118impl<PtrTag> std::ops::Sub<usize> for CodePtr<PtrTag> {
119    type Output = Self;
120
121    fn sub(self, rhs: usize) -> Self::Output {
122        CodePtr {
123            value: unsafe { self.value.offset(-(rhs as isize)) },
124            marker: PhantomData,
125        }
126    }
127}
128
129impl<PtrTag> std::ops::SubAssign<usize> for CodePtr<PtrTag> {
130    fn sub_assign(&mut self, rhs: usize) {
131        self.value = unsafe { self.value.offset(-(rhs as isize)) };
132    }
133}
134
135impl<PtrTag> std::ops::Sub<CodePtr<PtrTag>> for CodePtr<PtrTag> {
136    type Output = usize;
137
138    fn sub(self, rhs: CodePtr<PtrTag>) -> Self::Output {
139        (self.value as usize).wrapping_sub(rhs.value as usize)
140    }
141}
142
143impl<PtrTag> std::ops::Add<CodePtr<PtrTag>> for CodePtr<PtrTag> {
144    type Output = CodePtr<PtrTag>;
145
146    fn add(self, rhs: CodePtr<PtrTag>) -> Self::Output {
147        CodePtr {
148            value: unsafe { self.value.offset(rhs.value as isize) },
149            marker: PhantomData,
150        }
151    }
152}
153
154impl<PtrTag> std::ops::AddAssign<CodePtr<PtrTag>> for CodePtr<PtrTag> {
155    fn add_assign(&mut self, rhs: CodePtr<PtrTag>) {
156        self.value = unsafe { self.value.offset(rhs.value as isize) };
157    }
158}
159
160impl<PtrTag> std::ops::SubAssign<CodePtr<PtrTag>> for CodePtr<PtrTag> {
161    fn sub_assign(&mut self, rhs: CodePtr<PtrTag>) {
162        self.value = unsafe { self.value.offset(-(rhs.value as isize)) };
163    }
164}
165
166impl<PtrTag> std::ops::Add<&CodePtr<PtrTag>> for CodePtr<PtrTag> {
167    type Output = CodePtr<PtrTag>;
168
169    fn add(self, rhs: &CodePtr<PtrTag>) -> Self::Output {
170        CodePtr {
171            value: unsafe { self.value.offset(rhs.value as isize) },
172            marker: PhantomData,
173        }
174    }
175}
176
177impl<PtrTag> std::ops::AddAssign<&CodePtr<PtrTag>> for CodePtr<PtrTag> {
178    fn add_assign(&mut self, rhs: &CodePtr<PtrTag>) {
179        self.value = unsafe { self.value.offset(rhs.value as isize) };
180    }
181}