@@ -95,28 +95,32 @@ class HeapType {
9595 // should also be passed by value.
9696 uintptr_t id;
9797
98+ static constexpr int TypeBits = 3 ;
99+ static constexpr int UsedBits = TypeBits + 1 ;
100+ static constexpr int SharedMask = 1 << TypeBits;
101+
98102public:
99- // Bits 0 and 1 are used by the Type representation, so need to be left free.
100- // Bit 2 determines whether the basic heap type is shared (1) or unshared (0).
103+ // Bits 0-2 are used by the Type representation, so need to be left free.
104+ // Bit 3 determines whether the basic heap type is shared (1) or unshared (0).
101105 enum BasicHeapType : uint32_t {
102- ext = 1 << 3 ,
103- func = 2 << 3 ,
104- cont = 3 << 3 ,
105- any = 4 << 3 ,
106- eq = 5 << 3 ,
107- i31 = 6 << 3 ,
108- struct_ = 7 << 3 ,
109- array = 8 << 3 ,
110- exn = 9 << 3 ,
111- string = 10 << 3 ,
112- none = 11 << 3 ,
113- noext = 12 << 3 ,
114- nofunc = 13 << 3 ,
115- nocont = 14 << 3 ,
116- noexn = 15 << 3 ,
106+ ext = 1 << UsedBits ,
107+ func = 2 << UsedBits ,
108+ cont = 3 << UsedBits ,
109+ any = 4 << UsedBits ,
110+ eq = 5 << UsedBits ,
111+ i31 = 6 << UsedBits ,
112+ struct_ = 7 << UsedBits ,
113+ array = 8 << UsedBits ,
114+ exn = 9 << UsedBits ,
115+ string = 10 << UsedBits ,
116+ none = 11 << UsedBits ,
117+ noext = 12 << UsedBits ,
118+ nofunc = 13 << UsedBits ,
119+ nocont = 14 << UsedBits ,
120+ noexn = 15 << UsedBits ,
117121 };
118122 static constexpr BasicHeapType _last_basic_type =
119- BasicHeapType (noexn + ( 1 << 2 ) );
123+ BasicHeapType (noexn | SharedMask );
120124
121125 // BasicHeapType can be implicitly upgraded to HeapType
122126 constexpr HeapType (BasicHeapType id) : id(id) {}
@@ -214,7 +218,8 @@ class HeapType {
214218 // Get the shared or unshared version of this basic heap type.
215219 constexpr BasicHeapType getBasic (Shareability share) const {
216220 assert (isBasic ());
217- return BasicHeapType (share == Shared ? (id | 4 ) : (id & ~4 ));
221+ return BasicHeapType (share == Shared ? (id | SharedMask)
222+ : (id & ~SharedMask));
218223 }
219224
220225 // (In)equality must be defined for both HeapType and BasicHeapType because it
@@ -269,13 +274,17 @@ class Type {
269274 // bit 0 set. When that bit is masked off, they are pointers to the underlying
270275 // vectors of types. Otherwise, the type is a reference type, and is
271276 // represented as a heap type with bit 1 set iff the reference type is
272- // nullable.
277+ // nullable and bit 2 set iff the reference type is exact .
273278 //
274279 // Since `Type` is really just a single integer, it should be passed by value.
275280 // This is a uintptr_t rather than a TypeID (uint64_t) to save memory on
276281 // 32-bit platforms.
277282 uintptr_t id;
278283
284+ static constexpr int TupleMask = 1 << 0 ;
285+ static constexpr int NullMask = 1 << 1 ;
286+ static constexpr int ExactMask = 1 << 2 ;
287+
279288public:
280289 enum BasicType : uint32_t {
281290 none = 0 ,
@@ -306,7 +315,10 @@ class Type {
306315 // Construct from a heap type description. Also covers construction from
307316 // Signature, Struct or Array via implicit conversion to HeapType.
308317 Type (HeapType heapType, Nullability nullable)
309- : Type(heapType.getID() | (nullable == Nullable ? 2 : 0 )) {}
318+ : Type(heapType.getID() | (nullable == Nullable ? NullMask : 0 )) {
319+ assert (heapType.isBasic () ||
320+ !(heapType.getID () & (TupleMask | NullMask | ExactMask)));
321+ }
310322
311323 // Predicates
312324 // Compound Concrete
@@ -345,18 +357,18 @@ class Type {
345357 // basic case for the underlying implementation.
346358
347359 // TODO: Experiment with leaving bit 0 free in basic types.
348- bool isTuple () const { return !isBasic () && (id & 1 ); }
360+ bool isTuple () const { return !isBasic () && (id & TupleMask ); }
349361 const Tuple& getTuple () const {
350362 assert (isTuple ());
351- return *(Tuple*)(id & ~1 );
363+ return *(Tuple*)(id & ~TupleMask );
352364 }
353365
354- bool isRef () const { return !isBasic () && !(id & 1 ); }
355- bool isNullable () const { return isRef () && (id & 2 ); }
356- bool isNonNullable () const { return isRef () && !(id & 2 ); }
366+ bool isRef () const { return !isBasic () && !(id & TupleMask ); }
367+ bool isNullable () const { return isRef () && (id & NullMask ); }
368+ bool isNonNullable () const { return isRef () && !(id & NullMask ); }
357369 HeapType getHeapType () const {
358370 assert (isRef ());
359- return HeapType (id & ~2 );
371+ return HeapType (id & ~(NullMask | ExactMask) );
360372 }
361373
362374 bool isFunction () const { return isRef () && getHeapType ().isFunction (); }
0 commit comments