@@ -95,28 +95,32 @@ class HeapType {
95
95
// should also be passed by value.
96
96
uintptr_t id;
97
97
98
+ static constexpr int TypeBits = 3 ;
99
+ static constexpr int UsedBits = TypeBits + 1 ;
100
+ static constexpr int SharedMask = 1 << TypeBits;
101
+
98
102
public:
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).
101
105
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 ,
117
121
};
118
122
static constexpr BasicHeapType _last_basic_type =
119
- BasicHeapType (noexn + ( 1 << 2 ) );
123
+ BasicHeapType (noexn | SharedMask );
120
124
121
125
// BasicHeapType can be implicitly upgraded to HeapType
122
126
constexpr HeapType (BasicHeapType id) : id(id) {}
@@ -214,7 +218,8 @@ class HeapType {
214
218
// Get the shared or unshared version of this basic heap type.
215
219
constexpr BasicHeapType getBasic (Shareability share) const {
216
220
assert (isBasic ());
217
- return BasicHeapType (share == Shared ? (id | 4 ) : (id & ~4 ));
221
+ return BasicHeapType (share == Shared ? (id | SharedMask)
222
+ : (id & ~SharedMask));
218
223
}
219
224
220
225
// (In)equality must be defined for both HeapType and BasicHeapType because it
@@ -269,13 +274,17 @@ class Type {
269
274
// bit 0 set. When that bit is masked off, they are pointers to the underlying
270
275
// vectors of types. Otherwise, the type is a reference type, and is
271
276
// 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 .
273
278
//
274
279
// Since `Type` is really just a single integer, it should be passed by value.
275
280
// This is a uintptr_t rather than a TypeID (uint64_t) to save memory on
276
281
// 32-bit platforms.
277
282
uintptr_t id;
278
283
284
+ static constexpr int TupleMask = 1 << 0 ;
285
+ static constexpr int NullMask = 1 << 1 ;
286
+ static constexpr int ExactMask = 1 << 2 ;
287
+
279
288
public:
280
289
enum BasicType : uint32_t {
281
290
none = 0 ,
@@ -306,7 +315,10 @@ class Type {
306
315
// Construct from a heap type description. Also covers construction from
307
316
// Signature, Struct or Array via implicit conversion to HeapType.
308
317
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
+ }
310
322
311
323
// Predicates
312
324
// Compound Concrete
@@ -345,18 +357,18 @@ class Type {
345
357
// basic case for the underlying implementation.
346
358
347
359
// 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 ); }
349
361
const Tuple& getTuple () const {
350
362
assert (isTuple ());
351
- return *(Tuple*)(id & ~1 );
363
+ return *(Tuple*)(id & ~TupleMask );
352
364
}
353
365
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 ); }
357
369
HeapType getHeapType () const {
358
370
assert (isRef ());
359
- return HeapType (id & ~2 );
371
+ return HeapType (id & ~(NullMask | ExactMask) );
360
372
}
361
373
362
374
bool isFunction () const { return isRef () && getHeapType ().isFunction (); }
0 commit comments