macroassembler/wtf/
code_ptr.rs1use 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}