@@ -26,13 +26,13 @@ namespace swift {
2626// / A relative reference to an object stored in memory. The reference may be
2727// / direct or indirect, and uses the low bit of the (assumed at least
2828// / 2-byte-aligned) pointer to differentiate.
29- template <typename ValueTy, bool Nullable = false >
29+ template <typename ValueTy, bool Nullable = false , typename Offset = int32_t >
3030class RelativeIndirectablePointer {
3131private:
3232 // / The relative offset of the pointer's memory from the `this` pointer.
3333 // / If the low bit is clear, this is a direct reference; otherwise, it is
3434 // / an indirect reference.
35- int32_t RelativeOffset;
35+ Offset RelativeOffset;
3636
3737 // / RelativePointers should appear in statically-generated metadata. They
3838 // / shouldn't be constructed or copied.
@@ -44,6 +44,10 @@ class RelativeIndirectablePointer {
4444 RelativeIndirectablePointer &operator =(const RelativeIndirectablePointer &)
4545 = delete ;
4646
47+ static_assert (std::is_integral<Offset>::value &&
48+ std::is_signed<Offset>::value,
49+ " offset type should be signed integer" );
50+
4751public:
4852 const ValueTy *get () const & {
4953 // Check for null.
@@ -79,11 +83,11 @@ class RelativeIndirectablePointer {
7983// / A relative reference to a function, intended to reference private metadata
8084// / functions for the current executable or dynamic library image from
8185// / position-independent constant data.
82- template <typename T, bool Nullable>
86+ template <typename T, bool Nullable, typename Offset >
8387class RelativeDirectPointerImpl {
8488private:
8589 // / The relative offset of the function's entry point from *this.
86- int32_t RelativeOffset;
90+ Offset RelativeOffset;
8791
8892 // / RelativePointers should appear in statically-generated metadata. They
8993 // / shouldn't be constructed or copied.
@@ -117,11 +121,11 @@ class RelativeDirectPointerImpl {
117121};
118122
119123// / 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 >
121125class RelativeDirectPointer :
122- private RelativeDirectPointerImpl<T, Nullable>
126+ private RelativeDirectPointerImpl<T, Nullable, Offset >
123127{
124- using super = RelativeDirectPointerImpl<T, Nullable>;
128+ using super = RelativeDirectPointerImpl<T, Nullable, Offset >;
125129public:
126130 using super::get;
127131
@@ -142,11 +146,11 @@ class RelativeDirectPointer :
142146
143147// / A specialization of RelativeDirectPointer for function pointers,
144148// / 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 >
148152{
149- using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable>;
153+ using super = RelativeDirectPointerImpl<RetTy (ArgTy...), Nullable, Offset >;
150154public:
151155 using super::get;
152156
@@ -163,9 +167,9 @@ class RelativeDirectPointer<RetTy (ArgTy...), Nullable> :
163167
164168// / A direct relative reference to an aligned object, with an additional
165169// / tiny integer value crammed into its low bits.
166- template <typename PointeeTy, typename IntTy>
170+ template <typename PointeeTy, typename IntTy, typename Offset = int32_t >
167171class RelativeDirectPointerIntPair {
168- int32_t RelativeOffsetPlusInt;
172+ Offset RelativeOffsetPlusInt;
169173
170174 // / RelativePointers should appear in statically-generated metadata. They
171175 // / shouldn't be constructed or copied.
@@ -177,18 +181,20 @@ class RelativeDirectPointerIntPair {
177181 RelativeDirectPointerIntPair &operator =(const RelativeDirectPointerIntPair&)
178182 = delete ;
179183
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 " );
183187
184- return alignof (int32_t ) - 1 ;
188+ return alignof (Offset ) - 1 ;
185189 }
186190
187191public:
188192 using ValueTy = PointeeTy;
189193 using PointerTy = PointeeTy*;
190194
191195 PointerTy getPointer () const & {
196+
197+
192198 // The value is addressed relative to `this`.
193199 auto base = reinterpret_cast <intptr_t >(this );
194200 intptr_t absolute = base + (RelativeOffsetPlusInt & ~getMask ());
0 commit comments