@@ -26,13 +26,13 @@ namespace swift {
26
26
// / A relative reference to an object stored in memory. The reference may be
27
27
// / direct or indirect, and uses the low bit of the (assumed at least
28
28
// / 2-byte-aligned) pointer to differentiate.
29
- template <typename ValueTy, bool Nullable = false >
29
+ template <typename ValueTy, bool Nullable = false , typename Offset = int32_t >
30
30
class RelativeIndirectablePointer {
31
31
private:
32
32
// / The relative offset of the pointer's memory from the `this` pointer.
33
33
// / If the low bit is clear, this is a direct reference; otherwise, it is
34
34
// / an indirect reference.
35
- int32_t RelativeOffset;
35
+ Offset RelativeOffset;
36
36
37
37
// / RelativePointers should appear in statically-generated metadata. They
38
38
// / shouldn't be constructed or copied.
@@ -44,6 +44,10 @@ class RelativeIndirectablePointer {
44
44
RelativeIndirectablePointer &operator =(const RelativeIndirectablePointer &)
45
45
= delete ;
46
46
47
+ static_assert (std::is_integral<Offset>::value &&
48
+ std::is_signed<Offset>::value,
49
+ " offset type should be signed integer" );
50
+
47
51
public:
48
52
const ValueTy *get () const & {
49
53
// Check for null.
@@ -79,11 +83,11 @@ class RelativeIndirectablePointer {
79
83
// / A relative reference to a function, intended to reference private metadata
80
84
// / functions for the current executable or dynamic library image from
81
85
// / position-independent constant data.
82
- template <typename T, bool Nullable>
86
+ template <typename T, bool Nullable, typename Offset >
83
87
class RelativeDirectPointerImpl {
84
88
private:
85
89
// / The relative offset of the function's entry point from *this.
86
- int32_t RelativeOffset;
90
+ Offset RelativeOffset;
87
91
88
92
// / RelativePointers should appear in statically-generated metadata. They
89
93
// / shouldn't be constructed or copied.
@@ -117,11 +121,11 @@ class RelativeDirectPointerImpl {
117
121
};
118
122
119
123
// / A direct relative reference to an object.
120
- template <typename T, bool Nullable = true >
124
+ template <typename T, bool Nullable = true , typename Offset = int32_t >
121
125
class RelativeDirectPointer :
122
- private RelativeDirectPointerImpl<T, Nullable>
126
+ private RelativeDirectPointerImpl<T, Nullable, Offset >
123
127
{
124
- using super = RelativeDirectPointerImpl<T, Nullable>;
128
+ using super = RelativeDirectPointerImpl<T, Nullable, Offset >;
125
129
public:
126
130
using super::get;
127
131
@@ -142,11 +146,11 @@ class RelativeDirectPointer :
142
146
143
147
// / A specialization of RelativeDirectPointer for function pointers,
144
148
// / allowing for calls.
145
- template <typename RetTy, typename ...ArgTy, bool Nullable>
146
- class RelativeDirectPointer <RetTy (ArgTy...), Nullable> :
147
- private RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable>
149
+ template <typename RetTy, typename ...ArgTy, bool Nullable, typename Offset >
150
+ class RelativeDirectPointer <RetTy (ArgTy...), Nullable, Offset > :
151
+ private RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable, Offset >
148
152
{
149
- using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable>;
153
+ using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable, Offset >;
150
154
public:
151
155
using super::get;
152
156
@@ -163,9 +167,9 @@ class RelativeDirectPointer<RetTy (ArgTy...), Nullable> :
163
167
164
168
// / A direct relative reference to an aligned object, with an additional
165
169
// / tiny integer value crammed into its low bits.
166
- template <typename PointeeTy, typename IntTy>
170
+ template <typename PointeeTy, typename IntTy, typename Offset = int32_t >
167
171
class RelativeDirectPointerIntPair {
168
- int32_t RelativeOffsetPlusInt;
172
+ Offset RelativeOffsetPlusInt;
169
173
170
174
// / RelativePointers should appear in statically-generated metadata. They
171
175
// / shouldn't be constructed or copied.
@@ -177,18 +181,20 @@ class RelativeDirectPointerIntPair {
177
181
RelativeDirectPointerIntPair &operator =(const RelativeDirectPointerIntPair&)
178
182
= delete ;
179
183
180
- static int32_t getMask () {
181
- static_assert (alignof (PointeeTy) >= alignof (int32_t ),
182
- " pointee alignment must be at least 32 bit " );
184
+ static Offset getMask () {
185
+ static_assert (alignof (PointeeTy) >= alignof (Offset ),
186
+ " pointee alignment must be at least as strict as offset type " );
183
187
184
- return alignof (int32_t ) - 1 ;
188
+ return alignof (Offset ) - 1 ;
185
189
}
186
190
187
191
public:
188
192
using ValueTy = PointeeTy;
189
193
using PointerTy = PointeeTy*;
190
194
191
195
PointerTy getPointer () const & {
196
+
197
+
192
198
// The value is addressed relative to `this`.
193
199
auto base = reinterpret_cast <intptr_t >(this );
194
200
intptr_t absolute = base + (RelativeOffsetPlusInt & ~getMask ());
0 commit comments