Skip to content

Commit a61b9df

Browse files
authored
Add new compound Rtt type (#3076)
Extends compound types introduced in #3012 with a representation of `Rtt`s as described in the GC proposal, by also introducing the concept of a `HeapType` shared between `TypeInfo` and `Rtt`. Again, this should be a non-functional change since `Rtt`s are not used anywhere yet. Subtyping rules and updating the `xref` aliases is left for future work.
1 parent 9371352 commit a61b9df

File tree

4 files changed

+475
-140
lines changed

4 files changed

+475
-140
lines changed

src/wasm-type.h

Lines changed: 96 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@
3131

3232
namespace wasm {
3333

34-
struct Tuple;
35-
struct Signature;
36-
struct Struct;
37-
struct Array;
38-
39-
typedef std::vector<class Type> TypeList;
40-
4134
class Type {
4235
// The `id` uniquely represents each type, so type equality is just a
4336
// comparison of the ids. For basic types the `id` is just the `BasicID`
@@ -73,16 +66,14 @@ class Type {
7366
Type(std::initializer_list<Type>);
7467

7568
// Construct from tuple description
76-
explicit Type(const Tuple&);
77-
78-
// Construct from signature description
79-
explicit Type(const Signature, bool nullable);
69+
explicit Type(const struct Tuple&);
8070

81-
// Construct from struct description
82-
explicit Type(const Struct&, bool nullable);
71+
// Construct from a heap type description. Also covers construction from
72+
// Signature, Struct or Array via implicit conversion to HeapType.
73+
explicit Type(const struct HeapType&, bool nullable);
8374

84-
// Construct from array description
85-
explicit Type(const Array&, bool nullable);
75+
// Construct from rtt description
76+
explicit Type(const struct Rtt&);
8677

8778
// Predicates
8879
// Compound Concrete
@@ -96,16 +87,18 @@ class Type {
9687
// │ f32 ║ x │ │ x │ x │ F │ │ F_loat
9788
// │ f64 ║ x │ │ x │ x │ F │ │ V_ector
9889
// │ v128 ║ x │ │ x │ x │ V │ ┘
99-
// ├─────────────╫───┼───┼───┼───┤───────┤
100-
// │ funcref ║ x │ │ x │ x │ f │ ┐ Ref
101-
// │ externref ║ x │ │ x │ x │ │ │ f_unc
102-
// │ nullref ║ x │ │ x │ x │ │ │
103-
// │ exnref ║ x │ │ x │ x │ │ │
104-
// ├─────────────╫───┼───┼───┼───┤───────┤ │
105-
// │ Signature ║ │ x │ x │ x │ f │ │
106-
// │ Struct ║ │ x │ x │ x │ │ │
107-
// │ Array ║ │ x │ x │ x │ │ ┘
90+
// ├─ Aliases ───╫───┼───┼───┼───┤───────┤
91+
// │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref
92+
// │ externref ║ x │ │ x │ x │ f? n │ │ f_unc, n_ullable
93+
// │ anyref ║ x │ │ x │ x │ f? n │ │ ┐
94+
// │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC)
95+
// │ i31ref ║ x │ │ x │ x │ │ │ ┘
96+
// │ nullref ║ x │ │ x │ x │ f? n │ │ ◄ TODO (removed)
97+
// │ exnref ║ x │ │ x │ x │ n │ │
98+
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
99+
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
108100
// │ Tuple ║ │ x │ │ x │ │
101+
// │ Rtt ║ │ x │ x │ x │ │
109102
// └─────────────╨───┴───┴───┴───┴───────┘
110103
constexpr bool isBasic() const { return id <= _last_basic_id; }
111104
constexpr bool isCompound() const { return id > _last_basic_id; }
@@ -118,6 +111,7 @@ class Type {
118111
bool isSingle() const { return isConcrete() && !isTuple(); }
119112
bool isRef() const;
120113
bool isNullable() const;
114+
bool isRtt() const;
121115

122116
private:
123117
template<bool (Type::*pred)() const> bool hasPredicate() {
@@ -227,6 +221,8 @@ struct ResultType {
227221
std::string toString() const;
228222
};
229223

224+
typedef std::vector<Type> TypeList;
225+
230226
struct Tuple {
231227
TypeList types;
232228
Tuple() : types() {}
@@ -303,6 +299,72 @@ struct Array {
303299
std::string toString() const;
304300
};
305301

302+
struct HeapType {
303+
enum Kind {
304+
FuncKind,
305+
ExternKind,
306+
AnyKind,
307+
EqKind,
308+
I31Kind,
309+
ExnKind,
310+
_last_basic_kind = ExnKind,
311+
SignatureKind,
312+
StructKind,
313+
ArrayKind,
314+
} kind;
315+
union {
316+
Signature signature;
317+
Struct struct_;
318+
Array array;
319+
};
320+
HeapType(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); }
321+
HeapType(const Signature& signature)
322+
: kind(SignatureKind), signature(signature) {}
323+
HeapType(Signature&& signature)
324+
: kind(SignatureKind), signature(std::move(signature)) {}
325+
HeapType(const Struct& struct_) : kind(StructKind), struct_(struct_) {}
326+
HeapType(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {}
327+
HeapType(const Array& array) : kind(ArrayKind), array(array) {}
328+
HeapType(Array&& array) : kind(ArrayKind), array(std::move(array)) {}
329+
HeapType(const HeapType& other);
330+
~HeapType();
331+
332+
bool isSignature() const { return kind == SignatureKind; }
333+
Signature getSignature() const {
334+
assert(isSignature() && "Not a signature");
335+
return signature;
336+
}
337+
bool isStruct() const { return kind == StructKind; }
338+
Struct getStruct() const {
339+
assert(isStruct() && "Not a struct");
340+
return struct_;
341+
}
342+
bool isArray() const { return kind == ArrayKind; }
343+
Array getArray() const {
344+
assert(isArray() && "Not an array");
345+
return array;
346+
}
347+
348+
bool operator==(const HeapType& other) const;
349+
bool operator!=(const HeapType& other) const { return !(*this == other); }
350+
HeapType& operator=(const HeapType& other);
351+
std::string toString() const;
352+
};
353+
354+
struct Rtt {
355+
uint32_t depth;
356+
HeapType heapType;
357+
Rtt(uint32_t depth, const HeapType& heapType)
358+
: depth(depth), heapType(heapType) {}
359+
Rtt(uint32_t depth, HeapType&& heapType)
360+
: depth(depth), heapType(std::move(heapType)) {}
361+
bool operator==(const Rtt& other) const {
362+
return depth == other.depth && heapType == other.heapType;
363+
}
364+
bool operator!=(const Rtt& other) const { return !(*this == other); }
365+
std::string toString() const;
366+
};
367+
306368
std::ostream& operator<<(std::ostream&, Type);
307369
std::ostream& operator<<(std::ostream&, ParamType);
308370
std::ostream& operator<<(std::ostream&, ResultType);
@@ -311,6 +373,8 @@ std::ostream& operator<<(std::ostream&, Signature);
311373
std::ostream& operator<<(std::ostream&, Field);
312374
std::ostream& operator<<(std::ostream&, Struct);
313375
std::ostream& operator<<(std::ostream&, Array);
376+
std::ostream& operator<<(std::ostream&, HeapType);
377+
std::ostream& operator<<(std::ostream&, Rtt);
314378

315379
} // namespace wasm
316380

@@ -340,6 +404,14 @@ template<> class hash<wasm::Array> {
340404
public:
341405
size_t operator()(const wasm::Array&) const;
342406
};
407+
template<> class hash<wasm::HeapType> {
408+
public:
409+
size_t operator()(const wasm::HeapType&) const;
410+
};
411+
template<> class hash<wasm::Rtt> {
412+
public:
413+
size_t operator()(const wasm::Rtt&) const;
414+
};
343415

344416
} // namespace std
345417

0 commit comments

Comments
 (0)