Skip to content

Commit 83c82e5

Browse files
authored
[NFC] Make room for exact references in type encoding (#7314)
Reserve an additional bit in the encoding of types to represent reference exactness, which is introduced in the custom RTTs proposal: https://github.com/WebAssembly/custom-rtts/blob/main/proposals/custom-rtts/Overview.md#exact-reference-types. Also switch to using constexpr variables for bit manipulations in the type representation rather than using hardcoded numbers.
1 parent 3ea7e6f commit 83c82e5

File tree

3 files changed

+51
-39
lines changed

3 files changed

+51
-39
lines changed

src/wasm-type.h

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
98102
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).
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+
279288
public:
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(); }

src/wasm/wasm-type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ bool HeapType::isOpen() const {
876876

877877
Shareability HeapType::getShared() const {
878878
if (isBasic()) {
879-
return (id & 4) != 0 ? Shared : Unshared;
879+
return (id & SharedMask) != 0 ? Shared : Unshared;
880880
} else {
881881
return getHeapTypeInfo(*this)->share;
882882
}

test/example/c-api-kitchen-sink.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ BinaryenTypeAuto: -1
2020
BinaryenPackedTypeNotPacked: 0
2121
BinaryenPackedTypeInt8: 1
2222
BinaryenPackedTypeInt16: 2
23-
BinaryenHeapTypeExt: 8
24-
BinaryenHeapTypeFunc: 16
25-
BinaryenHeapTypeAny: 32
26-
BinaryenHeapTypeEq: 40
27-
BinaryenHeapTypeI31: 48
28-
BinaryenHeapTypeStruct: 56
29-
BinaryenHeapTypeArray: 64
30-
BinaryenHeapTypeString: 80
31-
BinaryenHeapTypeNone: 88
32-
BinaryenHeapTypeNoext: 96
33-
BinaryenHeapTypeNofunc: 104
23+
BinaryenHeapTypeExt: 16
24+
BinaryenHeapTypeFunc: 32
25+
BinaryenHeapTypeAny: 64
26+
BinaryenHeapTypeEq: 80
27+
BinaryenHeapTypeI31: 96
28+
BinaryenHeapTypeStruct: 112
29+
BinaryenHeapTypeArray: 128
30+
BinaryenHeapTypeString: 160
31+
BinaryenHeapTypeNone: 176
32+
BinaryenHeapTypeNoext: 192
33+
BinaryenHeapTypeNofunc: 208
3434
BinaryenFeatureMVP: 0
3535
BinaryenFeatureAtomics: 1
3636
BinaryenFeatureBulkMemory: 16

0 commit comments

Comments
 (0)