From 99198d43412a0ebbc0e5628776c004e4712e7fa6 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 25 Aug 2020 00:25:11 +0200 Subject: [PATCH 1/9] Add new compound Rtt type --- src/wasm-type.h | 124 +++++++++++++++++++++++++++++++++++++++-- src/wasm/wasm-type.cpp | 91 ++++++++++++++++++++++++++++-- 2 files changed, 206 insertions(+), 9 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index cee8dae0355..57ac18f5857 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -97,15 +97,19 @@ class Type { // │ f64 ║ x │ │ x │ x │ F │ │ V_ector // │ v128 ║ x │ │ x │ x │ V │ ┘ // ├─────────────╫───┼───┼───┼───┤───────┤ - // │ funcref ║ x │ │ x │ x │ f │ ┐ Ref - // │ externref ║ x │ │ x │ x │ │ │ f_unc - // │ nullref ║ x │ │ x │ x │ │ │ - // │ exnref ║ x │ │ x │ x │ │ │ + // │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref + // │ externref ║ x │ │ x │ x │ n │ │ f_unc + // │ anyref ║ x │ │ x │ x │ n │ │ ┐ + // │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC) + // │ i31ref ║ x │ │ x │ x │ n │ │ ┘ + // │ nullref ║ x │ │ x │ x │ n │ │ ◄ TODO (removed) + // │ exnref ║ x │ │ x │ x │ n │ │ // ├─────────────╫───┼───┼───┼───┤───────┤ │ // │ Signature ║ │ x │ x │ x │ f │ │ // │ Struct ║ │ x │ x │ x │ │ │ // │ Array ║ │ x │ x │ x │ │ ┘ // │ Tuple ║ │ x │ │ x │ │ + // │ Rtt ║ │ x │ x │ x │ │ // └─────────────╨───┴───┴───┴───┴───────┘ constexpr bool isBasic() const { return id <= _last_basic_id; } constexpr bool isCompound() const { return id > _last_basic_id; } @@ -118,6 +122,7 @@ class Type { bool isSingle() const { return isConcrete() && !isTuple(); } bool isRef() const; bool isNullable() const; + bool isRtt() const; private: template bool hasPredicate() { @@ -303,6 +308,112 @@ struct Array { std::string toString() const; }; +struct Rtt { + enum Kind { + // Basic heap types + FuncKind, + ExternKind, + AnyKind, + EqKind, + I31Kind, + _last_basic_kind = I31Kind, + // Compound heap types + SignatureKind, + StructKind, + ArrayKind, + } kind; + uint32_t depth; + union { + Signature signature; + Struct struct_; + Array array; + }; + Rtt(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); } + Rtt(const Signature& signature) : kind(SignatureKind), signature(signature) {} + Rtt(Signature&& signature) + : kind(SignatureKind), signature(std::move(signature)) {} + Rtt(const Struct& struct_) : kind(StructKind), struct_(struct_) {} + Rtt(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {} + Rtt(const Array& array) : kind(ArrayKind), array(array) {} + Rtt(Array&& array) : kind(ArrayKind), array(std::move(array)) {} + Rtt(const Rtt& other) { + kind = other.kind; + depth = other.depth; + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + return; + case SignatureKind: + new (&signature) auto(other.signature); + return; + case StructKind: + new (&struct_) auto(other.struct_); + return; + case ArrayKind: + new (&array) auto(other.array); + return; + } + WASM_UNREACHABLE("unexpected kind"); + } + ~Rtt() { + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + return; + case SignatureKind: + signature.~Signature(); + return; + case StructKind: + struct_.~Struct(); + return; + case ArrayKind: + array.~Array(); + return; + } + WASM_UNREACHABLE("unexpected kind"); + } + bool operator==(const Rtt& other) const { + if (kind != other.kind || depth != other.depth) { + return false; + } + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + return true; + case SignatureKind: + return signature == other.signature; + case StructKind: + return struct_ == other.struct_; + case ArrayKind: + return array == other.array; + } + WASM_UNREACHABLE("unexpected kind"); + } + bool operator!=(const Rtt& other) const { return !(*this == other); } + Rtt& operator=(const Rtt& other) { + if (&other != this) { + this->~Rtt(); + new (this) auto(other); + } + return *this; + } + bool isBasic() const { return kind <= _last_basic_kind; } + bool isCompound() const { return kind > _last_basic_kind; } + bool isSignature() const { return kind == SignatureKind; } + bool isStruct() const { return kind == StructKind; } + bool isArray() const { return kind == ArrayKind; } + std::string toString() const; +}; + std::ostream& operator<<(std::ostream&, Type); std::ostream& operator<<(std::ostream&, ParamType); std::ostream& operator<<(std::ostream&, ResultType); @@ -311,6 +422,7 @@ std::ostream& operator<<(std::ostream&, Signature); std::ostream& operator<<(std::ostream&, Field); std::ostream& operator<<(std::ostream&, Struct); std::ostream& operator<<(std::ostream&, Array); +std::ostream& operator<<(std::ostream&, Rtt); } // namespace wasm @@ -340,6 +452,10 @@ template<> class hash { public: size_t operator()(const wasm::Array&) const; }; +template<> class hash { +public: + size_t operator()(const wasm::Rtt&) const; +}; } // namespace std diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 5247ebb6f36..852bf3964fa 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -28,7 +28,13 @@ namespace wasm { struct TypeInfo { - enum Kind { TupleKind, SignatureRefKind, StructRefKind, ArrayRefKind } kind; + enum Kind { + TupleKind, + SignatureRefKind, + StructRefKind, + ArrayRefKind, + RttKind, + } kind; struct SignatureRef { Signature signature; bool nullable; @@ -46,6 +52,7 @@ struct TypeInfo { SignatureRef signatureRef; StructRef structRef; ArrayRef arrayRef; + Rtt rtt; }; TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {} @@ -56,6 +63,7 @@ struct TypeInfo { : kind(StructRefKind), structRef{struct_, nullable} {} TypeInfo(const Array& array, bool nullable) : kind(ArrayRefKind), arrayRef{array, nullable} {} + TypeInfo(const Rtt& rtt) : kind(RttKind), rtt(rtt) {} TypeInfo(const TypeInfo& other) { kind = other.kind; switch (kind) { @@ -71,6 +79,9 @@ struct TypeInfo { case ArrayRefKind: new (&arrayRef) auto(other.arrayRef); return; + case RttKind: + new (&rtt) auto(other.rtt); + return; } WASM_UNREACHABLE("unexpected kind"); } @@ -92,6 +103,10 @@ struct TypeInfo { arrayRef.~ArrayRef(); return; } + case RttKind: { + rtt.~Rtt(); + return; + } } WASM_UNREACHABLE("unexpected kind"); } @@ -100,10 +115,12 @@ struct TypeInfo { constexpr bool isSignatureRef() const { return kind == SignatureRefKind; } constexpr bool isStructRef() const { return kind == StructRefKind; } constexpr bool isArrayRef() const { return kind == ArrayRefKind; } + constexpr bool isRtt() const { return kind == RttKind; } bool isNullable() const { switch (kind) { case TupleKind: + case RttKind: return false; case SignatureRefKind: return signatureRef.nullable; @@ -131,6 +148,8 @@ struct TypeInfo { case ArrayRefKind: return arrayRef.nullable == other.arrayRef.nullable && arrayRef.array == other.arrayRef.array; + case RttKind: + return rtt == other.rtt; } WASM_UNREACHABLE("unexpected kind"); } @@ -180,7 +199,7 @@ template<> class hash { auto digest = wasm::hash(info.kind); switch (info.kind) { case wasm::TypeInfo::TupleKind: { - wasm::rehash(digest, info.tuple.types); + wasm::rehash(digest, info.tuple); return digest; } case wasm::TypeInfo::SignatureRefKind: { @@ -198,6 +217,10 @@ template<> class hash { wasm::rehash(digest, info.arrayRef.nullable); return digest; } + case wasm::TypeInfo::RttKind: { + wasm::rehash(digest, info.rtt); + return digest; + } } WASM_UNREACHABLE("unexpected kind"); } @@ -225,15 +248,36 @@ size_t hash::operator()(const wasm::Field& field) const { } size_t hash::operator()(const wasm::Struct& struct_) const { - auto digest = wasm::hash(0); - wasm::rehash(digest, struct_.fields); - return digest; + return wasm::hash(struct_.fields); } size_t hash::operator()(const wasm::Array& array) const { return wasm::hash(array.element); } +size_t hash::operator()(const wasm::Rtt& rtt) const { + auto digest = wasm::hash(rtt.kind); + wasm::rehash(digest, rtt.depth); + switch (rtt.kind) { + case wasm::Rtt::FuncKind: + case wasm::Rtt::ExternKind: + case wasm::Rtt::AnyKind: + case wasm::Rtt::EqKind: + case wasm::Rtt::I31Kind: + return digest; + case wasm::Rtt::SignatureKind: + wasm::rehash(digest, rtt.signature); + return digest; + case wasm::Rtt::StructKind: + wasm::rehash(digest, rtt.struct_); + return digest; + case wasm::Rtt::ArrayKind: + wasm::rehash(digest, rtt.array); + return digest; + } + WASM_UNREACHABLE("unexpected kind"); +} + } // namespace std namespace wasm { @@ -338,6 +382,7 @@ bool Type::isRef() const { } else { switch (getTypeInfo(*this)->kind) { case TypeInfo::TupleKind: + case TypeInfo::RttKind: return false; case TypeInfo::SignatureRefKind: case TypeInfo::StructRefKind: @@ -356,6 +401,14 @@ bool Type::isNullable() const { } } +bool Type::isRtt() const { + if (isBasic()) { + return false; + } else { + return getTypeInfo(*this)->isRtt(); + } +} + bool Type::operator<(const Type& other) const { return std::lexicographical_compare(begin(), end(), @@ -581,6 +634,8 @@ std::string Struct::toString() const { return genericToString(*this); } std::string Array::toString() const { return genericToString(*this); } +std::string Rtt::toString() const { return genericToString(*this); } + std::string TypeInfo::toString() const { return genericToString(*this); } bool Signature::operator<(const Signature& other) const { @@ -708,6 +763,29 @@ std::ostream& operator<<(std::ostream& os, Array array) { return os << "(array " << array.element << ")"; } +std::ostream& operator<<(std::ostream& os, Rtt rtt) { + os << "(rtt " << rtt.depth << " "; + switch (rtt.kind) { + case wasm::Rtt::FuncKind: + return os << "func)"; + case wasm::Rtt::ExternKind: + return os << "extern)"; + case wasm::Rtt::AnyKind: + return os << "any)"; + case wasm::Rtt::EqKind: + return os << "eq)"; + case wasm::Rtt::I31Kind: + return os << "i31)"; + case wasm::Rtt::SignatureKind: + return os << rtt.signature << ")"; + case wasm::Rtt::StructKind: + return os << rtt.struct_ << ")"; + case wasm::Rtt::ArrayKind: + return os << rtt.array << ")"; + } + WASM_UNREACHABLE("unexpected kind"); +} + std::ostream& operator<<(std::ostream& os, TypeInfo info) { switch (info.kind) { case TypeInfo::TupleKind: { @@ -734,6 +812,9 @@ std::ostream& operator<<(std::ostream& os, TypeInfo info) { } return os << info.arrayRef.array << ")"; } + case TypeInfo::RttKind: { + return os << info.rtt; + } } WASM_UNREACHABLE("unexpected kind"); } From 2b41dadce06bbaa1f60e31db3473a230cf287f5f Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 25 Aug 2020 00:45:49 +0200 Subject: [PATCH 2/9] document nullability --- src/wasm-type.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index 57ac18f5857..5c53fa54044 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -97,17 +97,17 @@ class Type { // │ f64 ║ x │ │ x │ x │ F │ │ V_ector // │ v128 ║ x │ │ x │ x │ V │ ┘ // ├─────────────╫───┼───┼───┼───┤───────┤ - // │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref - // │ externref ║ x │ │ x │ x │ n │ │ f_unc - // │ anyref ║ x │ │ x │ x │ n │ │ ┐ - // │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC) - // │ i31ref ║ x │ │ x │ x │ n │ │ ┘ - // │ nullref ║ x │ │ x │ x │ n │ │ ◄ TODO (removed) - // │ exnref ║ x │ │ x │ x │ n │ │ + // │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref + // │ externref ║ x │ │ x │ x │ f? n │ │ f_unc, n_ullable + // │ anyref ║ x │ │ x │ x │ f? n │ │ ┐ + // │ eqref ║ x │ │ x │ x │ n │ │ │ TODO (GC) + // │ i31ref ║ x │ │ x │ x │ │ │ ┘ + // │ nullref ║ x │ │ x │ x │ f? n │ │ ◄ TODO (removed) + // │ exnref ║ x │ │ x │ x │ n │ │ // ├─────────────╫───┼───┼───┼───┤───────┤ │ - // │ Signature ║ │ x │ x │ x │ f │ │ - // │ Struct ║ │ x │ x │ x │ │ │ - // │ Array ║ │ x │ x │ x │ │ ┘ + // │ Signature ║ │ x │ x │ x │ f n? │ │ + // │ Struct ║ │ x │ x │ x │ n? │ │ + // │ Array ║ │ x │ x │ x │ n? │ ┘ // │ Tuple ║ │ x │ │ x │ │ // │ Rtt ║ │ x │ x │ x │ │ // └─────────────╨───┴───┴───┴───┴───────┘ From 813a4589c2a5025e1cb6c60a9391ffdd236f2f5e Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 25 Aug 2020 00:55:57 +0200 Subject: [PATCH 3/9] construct with depth (whoops) --- src/wasm-type.h | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index 5c53fa54044..7ac5af7970e 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -328,14 +328,21 @@ struct Rtt { Struct struct_; Array array; }; - Rtt(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); } - Rtt(const Signature& signature) : kind(SignatureKind), signature(signature) {} - Rtt(Signature&& signature) - : kind(SignatureKind), signature(std::move(signature)) {} - Rtt(const Struct& struct_) : kind(StructKind), struct_(struct_) {} - Rtt(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {} - Rtt(const Array& array) : kind(ArrayKind), array(array) {} - Rtt(Array&& array) : kind(ArrayKind), array(std::move(array)) {} + Rtt(uint32_t depth, Kind kind) : kind(kind), depth(depth) { + assert(kind <= _last_basic_kind); + } + Rtt(uint32_t depth, const Signature& signature) + : kind(SignatureKind), depth(depth), signature(signature) {} + Rtt(uint32_t depth, Signature&& signature) + : kind(SignatureKind), depth(depth), signature(std::move(signature)) {} + Rtt(uint32_t depth, const Struct& struct_) + : kind(StructKind), depth(depth), struct_(struct_) {} + Rtt(uint32_t depth, Struct&& struct_) + : kind(StructKind), depth(depth), struct_(std::move(struct_)) {} + Rtt(uint32_t depth, const Array& array) + : kind(ArrayKind), depth(depth), array(array) {} + Rtt(uint32_t depth, Array&& array) + : kind(ArrayKind), depth(depth), array(std::move(array)) {} Rtt(const Rtt& other) { kind = other.kind; depth = other.depth; From 35bd8a1cf72ffb995400baeea4c259d19b7091a1 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 25 Aug 2020 22:07:32 +0200 Subject: [PATCH 4/9] refactor to use HeapType in both TypeInfo and Rtt --- src/wasm-type.h | 106 +++++++++-------- src/wasm/wasm-type.cpp | 253 ++++++++++++++++------------------------- 2 files changed, 160 insertions(+), 199 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index 7ac5af7970e..9970db06061 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -31,13 +31,6 @@ namespace wasm { -struct Tuple; -struct Signature; -struct Struct; -struct Array; - -typedef std::vector TypeList; - class Type { // The `id` uniquely represents each type, so type equality is just a // comparison of the ids. For basic types the `id` is just the `BasicID` @@ -73,16 +66,14 @@ class Type { Type(std::initializer_list); // Construct from tuple description - explicit Type(const Tuple&); - - // Construct from signature description - explicit Type(const Signature, bool nullable); + explicit Type(const struct Tuple&); - // Construct from struct description - explicit Type(const Struct&, bool nullable); + // Construct from a heap type description. Also covers construction from + // Signature, Struct or Array via implicit conversion to HeapType. + explicit Type(const struct HeapType&, bool nullable); - // Construct from array description - explicit Type(const Array&, bool nullable); + // Construct from rtt description + explicit Type(const struct Rtt&); // Predicates // Compound Concrete @@ -232,6 +223,8 @@ struct ResultType { std::string toString() const; }; +typedef std::vector TypeList; + struct Tuple { TypeList types; Tuple() : types() {} @@ -308,50 +301,42 @@ struct Array { std::string toString() const; }; -struct Rtt { +struct HeapType { enum Kind { - // Basic heap types FuncKind, ExternKind, AnyKind, EqKind, I31Kind, - _last_basic_kind = I31Kind, - // Compound heap types + ExnKind, + _last_basic_kind = ExnKind, SignatureKind, StructKind, ArrayKind, } kind; - uint32_t depth; union { Signature signature; Struct struct_; Array array; }; - Rtt(uint32_t depth, Kind kind) : kind(kind), depth(depth) { - assert(kind <= _last_basic_kind); - } - Rtt(uint32_t depth, const Signature& signature) - : kind(SignatureKind), depth(depth), signature(signature) {} - Rtt(uint32_t depth, Signature&& signature) - : kind(SignatureKind), depth(depth), signature(std::move(signature)) {} - Rtt(uint32_t depth, const Struct& struct_) - : kind(StructKind), depth(depth), struct_(struct_) {} - Rtt(uint32_t depth, Struct&& struct_) - : kind(StructKind), depth(depth), struct_(std::move(struct_)) {} - Rtt(uint32_t depth, const Array& array) - : kind(ArrayKind), depth(depth), array(array) {} - Rtt(uint32_t depth, Array&& array) - : kind(ArrayKind), depth(depth), array(std::move(array)) {} - Rtt(const Rtt& other) { + HeapType(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); } + HeapType(const Signature& signature) + : kind(SignatureKind), signature(signature) {} + HeapType(Signature&& signature) + : kind(SignatureKind), signature(std::move(signature)) {} + HeapType(const Struct& struct_) : kind(StructKind), struct_(struct_) {} + HeapType(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {} + HeapType(const Array& array) : kind(ArrayKind), array(array) {} + HeapType(Array&& array) : kind(ArrayKind), array(std::move(array)) {} + HeapType(const HeapType& other) { kind = other.kind; - depth = other.depth; switch (kind) { case FuncKind: case ExternKind: case AnyKind: case EqKind: case I31Kind: + case ExnKind: return; case SignatureKind: new (&signature) auto(other.signature); @@ -365,13 +350,14 @@ struct Rtt { } WASM_UNREACHABLE("unexpected kind"); } - ~Rtt() { + ~HeapType() { switch (kind) { case FuncKind: case ExternKind: case AnyKind: case EqKind: case I31Kind: + case ExnKind: return; case SignatureKind: signature.~Signature(); @@ -385,8 +371,8 @@ struct Rtt { } WASM_UNREACHABLE("unexpected kind"); } - bool operator==(const Rtt& other) const { - if (kind != other.kind || depth != other.depth) { + bool operator==(const HeapType& other) const { + if (kind != other.kind) { return false; } switch (kind) { @@ -395,6 +381,7 @@ struct Rtt { case AnyKind: case EqKind: case I31Kind: + case ExnKind: return true; case SignatureKind: return signature == other.signature; @@ -405,19 +392,43 @@ struct Rtt { } WASM_UNREACHABLE("unexpected kind"); } - bool operator!=(const Rtt& other) const { return !(*this == other); } - Rtt& operator=(const Rtt& other) { + bool operator!=(const HeapType& other) const { return !(*this == other); } + HeapType& operator=(const HeapType& other) { if (&other != this) { - this->~Rtt(); + this->~HeapType(); new (this) auto(other); } return *this; } - bool isBasic() const { return kind <= _last_basic_kind; } - bool isCompound() const { return kind > _last_basic_kind; } bool isSignature() const { return kind == SignatureKind; } + Signature getSignature() const { + assert(isSignature() && "Not a signature"); + return signature; + } bool isStruct() const { return kind == StructKind; } + Struct getStruct() const { + assert(isStruct() && "Not a struct"); + return struct_; + } bool isArray() const { return kind == ArrayKind; } + Array getArray() const { + assert(isArray() && "Not an array"); + return array; + } + std::string toString() const; +}; + +struct Rtt { + uint32_t depth; + HeapType heapType; + Rtt(uint32_t depth, const HeapType& heapType) + : depth(depth), heapType(heapType) {} + Rtt(uint32_t depth, HeapType&& heapType) + : depth(depth), heapType(std::move(heapType)) {} + bool operator==(const Rtt& other) const { + return depth == other.depth && heapType == other.heapType; + } + bool operator!=(const Rtt& other) const { return !(*this == other); } std::string toString() const; }; @@ -429,6 +440,7 @@ std::ostream& operator<<(std::ostream&, Signature); std::ostream& operator<<(std::ostream&, Field); std::ostream& operator<<(std::ostream&, Struct); std::ostream& operator<<(std::ostream&, Array); +std::ostream& operator<<(std::ostream&, HeapType); std::ostream& operator<<(std::ostream&, Rtt); } // namespace wasm @@ -459,6 +471,10 @@ template<> class hash { public: size_t operator()(const wasm::Array&) const; }; +template<> class hash { +public: + size_t operator()(const wasm::HeapType&) const; +}; template<> class hash { public: size_t operator()(const wasm::Rtt&) const; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 852bf3964fa..97235801033 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -30,54 +30,35 @@ namespace wasm { struct TypeInfo { enum Kind { TupleKind, - SignatureRefKind, - StructRefKind, - ArrayRefKind, + RefKind, RttKind, } kind; - struct SignatureRef { - Signature signature; - bool nullable; - }; - struct StructRef { - Struct struct_; - bool nullable; - }; - struct ArrayRef { - Array array; + struct Ref { + HeapType heapType; bool nullable; }; union { Tuple tuple; - SignatureRef signatureRef; - StructRef structRef; - ArrayRef arrayRef; + Ref ref; Rtt rtt; }; TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {} TypeInfo(Tuple&& tuple) : kind(TupleKind), tuple(std::move(tuple)) {} - TypeInfo(const Signature& signature, bool nullable) - : kind(SignatureRefKind), signatureRef{signature, nullable} {} - TypeInfo(const Struct& struct_, bool nullable) - : kind(StructRefKind), structRef{struct_, nullable} {} - TypeInfo(const Array& array, bool nullable) - : kind(ArrayRefKind), arrayRef{array, nullable} {} + TypeInfo(const HeapType& heapType, bool nullable) + : kind(RefKind), ref{heapType, nullable} {} + TypeInfo(HeapType&& heapType, bool nullable) + : kind(RefKind), ref{std::move(heapType), nullable} {} TypeInfo(const Rtt& rtt) : kind(RttKind), rtt(rtt) {} + TypeInfo(Rtt&& rtt) : kind(RttKind), rtt(std::move(rtt)) {} TypeInfo(const TypeInfo& other) { kind = other.kind; switch (kind) { case TupleKind: new (&tuple) auto(other.tuple); return; - case SignatureRefKind: - new (&signatureRef) auto(other.signatureRef); - return; - case StructRefKind: - new (&structRef) auto(other.structRef); - return; - case ArrayRefKind: - new (&arrayRef) auto(other.arrayRef); + case RefKind: + new (&ref) auto(other.ref); return; case RttKind: new (&rtt) auto(other.rtt); @@ -91,16 +72,8 @@ struct TypeInfo { tuple.~Tuple(); return; } - case SignatureRefKind: { - signatureRef.~SignatureRef(); - return; - } - case StructRefKind: { - structRef.~StructRef(); - return; - } - case ArrayRefKind: { - arrayRef.~ArrayRef(); + case RefKind: { + ref.~Ref(); return; } case RttKind: { @@ -112,25 +85,10 @@ struct TypeInfo { } constexpr bool isTuple() const { return kind == TupleKind; } - constexpr bool isSignatureRef() const { return kind == SignatureRefKind; } - constexpr bool isStructRef() const { return kind == StructRefKind; } - constexpr bool isArrayRef() const { return kind == ArrayRefKind; } + constexpr bool isRef() const { return kind == RefKind; } constexpr bool isRtt() const { return kind == RttKind; } - bool isNullable() const { - switch (kind) { - case TupleKind: - case RttKind: - return false; - case SignatureRefKind: - return signatureRef.nullable; - case StructRefKind: - return structRef.nullable; - case ArrayRefKind: - return arrayRef.nullable; - } - WASM_UNREACHABLE("unexpected kind"); - } + bool isNullable() const { return kind == RefKind && ref.nullable; } bool operator==(const TypeInfo& other) const { if (kind != other.kind) { @@ -139,15 +97,9 @@ struct TypeInfo { switch (kind) { case TupleKind: return tuple == other.tuple; - case SignatureRefKind: - return signatureRef.nullable == other.signatureRef.nullable && - signatureRef.signature == other.signatureRef.signature; - case StructRefKind: - return structRef.nullable == other.structRef.nullable && - structRef.struct_ == other.structRef.struct_; - case ArrayRefKind: - return arrayRef.nullable == other.arrayRef.nullable && - arrayRef.array == other.arrayRef.array; + case RefKind: + return ref.heapType == other.ref.heapType && + ref.nullable == other.ref.nullable; case RttKind: return rtt == other.rtt; } @@ -202,19 +154,9 @@ template<> class hash { wasm::rehash(digest, info.tuple); return digest; } - case wasm::TypeInfo::SignatureRefKind: { - wasm::rehash(digest, info.signatureRef.signature); - wasm::rehash(digest, info.signatureRef.nullable); - return digest; - } - case wasm::TypeInfo::StructRefKind: { - wasm::rehash(digest, info.structRef.struct_); - wasm::rehash(digest, info.structRef.nullable); - return digest; - } - case wasm::TypeInfo::ArrayRefKind: { - wasm::rehash(digest, info.arrayRef.array); - wasm::rehash(digest, info.arrayRef.nullable); + case wasm::TypeInfo::RefKind: { + wasm::rehash(digest, info.ref.heapType); + wasm::rehash(digest, info.ref.nullable); return digest; } case wasm::TypeInfo::RttKind: { @@ -255,29 +197,35 @@ size_t hash::operator()(const wasm::Array& array) const { return wasm::hash(array.element); } -size_t hash::operator()(const wasm::Rtt& rtt) const { - auto digest = wasm::hash(rtt.kind); - wasm::rehash(digest, rtt.depth); - switch (rtt.kind) { - case wasm::Rtt::FuncKind: - case wasm::Rtt::ExternKind: - case wasm::Rtt::AnyKind: - case wasm::Rtt::EqKind: - case wasm::Rtt::I31Kind: +size_t hash::operator()(const wasm::HeapType& heapType) const { + auto digest = wasm::hash(heapType.kind); + switch (heapType.kind) { + case wasm::HeapType::FuncKind: + case wasm::HeapType::ExternKind: + case wasm::HeapType::AnyKind: + case wasm::HeapType::EqKind: + case wasm::HeapType::I31Kind: + case wasm::HeapType::ExnKind: return digest; - case wasm::Rtt::SignatureKind: - wasm::rehash(digest, rtt.signature); + case wasm::HeapType::SignatureKind: + wasm::rehash(digest, heapType.signature); return digest; - case wasm::Rtt::StructKind: - wasm::rehash(digest, rtt.struct_); + case wasm::HeapType::StructKind: + wasm::rehash(digest, heapType.struct_); return digest; - case wasm::Rtt::ArrayKind: - wasm::rehash(digest, rtt.array); + case wasm::HeapType::ArrayKind: + wasm::rehash(digest, heapType.array); return digest; } WASM_UNREACHABLE("unexpected kind"); } +size_t hash::operator()(const wasm::Rtt& rtt) const { + auto digest = wasm::hash(rtt.depth); + wasm::rehash(digest, rtt.heapType); + return digest; +} + } // namespace std namespace wasm { @@ -305,9 +253,16 @@ std::unordered_map indices = { {TypeInfo({Type::f64}), Type::f64}, {TypeInfo({Type::v128}), Type::v128}, {TypeInfo({Type::funcref}), Type::funcref}, + {TypeInfo(HeapType(HeapType::FuncKind), true), Type::funcref}, {TypeInfo({Type::externref}), Type::externref}, - {TypeInfo({Type::nullref}), Type::nullref}, + {TypeInfo(HeapType(HeapType::ExternKind), true), Type::externref}, + // TODO (GC): Add canonical ids + // * `(ref null any) == anyref` + // * `(ref null eq) == eqref` + // * `(ref i31) == i31ref` + {TypeInfo({Type::nullref}), Type::nullref}, // TODO (removed) {TypeInfo({Type::exnref}), Type::exnref}, + {TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref}, }; } // anonymous namespace @@ -350,22 +305,28 @@ Type::Type(const Tuple& tuple) { id = canonicalize(TypeInfo(tuple)); } -Type::Type(const Signature signature, bool nullable) { - id = canonicalize(TypeInfo(signature, nullable)); -} - -Type::Type(const Struct& struct_, bool nullable) { +Type::Type(const HeapType& heapType, bool nullable) { #ifndef NDEBUG - for (Field f : struct_.fields) { - assert(f.type.isSingle()); + switch (heapType.kind) { + case HeapType::FuncKind: + case HeapType::ExternKind: + case HeapType::AnyKind: + case HeapType::EqKind: + case HeapType::I31Kind: + case HeapType::ExnKind: + case HeapType::SignatureKind: + break; + case HeapType::StructKind: + for (Field f : heapType.struct_.fields) { + assert(f.type.isSingle()); + } + break; + case HeapType::ArrayKind: + assert(heapType.array.element.type.isSingle()); + break; } #endif - id = canonicalize(TypeInfo(struct_, nullable)); -} - -Type::Type(const Array& array, bool nullable) { - assert(array.element.type.isSingle()); - id = canonicalize(TypeInfo(array, nullable)); + id = canonicalize(TypeInfo(heapType, nullable)); } bool Type::isTuple() const { @@ -380,16 +341,7 @@ bool Type::isRef() const { if (isBasic()) { return id >= funcref && id <= exnref; } else { - switch (getTypeInfo(*this)->kind) { - case TypeInfo::TupleKind: - case TypeInfo::RttKind: - return false; - case TypeInfo::SignatureRefKind: - case TypeInfo::StructRefKind: - case TypeInfo::ArrayRefKind: - return true; - } - WASM_UNREACHABLE("unexpected kind"); + return getTypeInfo(*this)->isRef(); } } @@ -634,6 +586,8 @@ std::string Struct::toString() const { return genericToString(*this); } std::string Array::toString() const { return genericToString(*this); } +std::string HeapType::toString() const { return genericToString(*this); } + std::string Rtt::toString() const { return genericToString(*this); } std::string TypeInfo::toString() const { return genericToString(*this); } @@ -763,54 +717,45 @@ std::ostream& operator<<(std::ostream& os, Array array) { return os << "(array " << array.element << ")"; } -std::ostream& operator<<(std::ostream& os, Rtt rtt) { - os << "(rtt " << rtt.depth << " "; - switch (rtt.kind) { - case wasm::Rtt::FuncKind: - return os << "func)"; - case wasm::Rtt::ExternKind: - return os << "extern)"; - case wasm::Rtt::AnyKind: - return os << "any)"; - case wasm::Rtt::EqKind: - return os << "eq)"; - case wasm::Rtt::I31Kind: - return os << "i31)"; - case wasm::Rtt::SignatureKind: - return os << rtt.signature << ")"; - case wasm::Rtt::StructKind: - return os << rtt.struct_ << ")"; - case wasm::Rtt::ArrayKind: - return os << rtt.array << ")"; +std::ostream& operator<<(std::ostream& os, HeapType heapType) { + switch (heapType.kind) { + case wasm::HeapType::FuncKind: + return os << "func"; + case wasm::HeapType::ExternKind: + return os << "extern"; + case wasm::HeapType::AnyKind: + return os << "any"; + case wasm::HeapType::EqKind: + return os << "eq"; + case wasm::HeapType::I31Kind: + return os << "i31"; + case wasm::HeapType::ExnKind: + return os << "exn"; + case wasm::HeapType::SignatureKind: + return os << heapType.signature; + case wasm::HeapType::StructKind: + return os << heapType.struct_; + case wasm::HeapType::ArrayKind: + return os << heapType.array; } WASM_UNREACHABLE("unexpected kind"); } +std::ostream& operator<<(std::ostream& os, Rtt rtt) { + return os << "(rtt " << rtt.depth << " " << rtt.heapType << ")"; +} + std::ostream& operator<<(std::ostream& os, TypeInfo info) { switch (info.kind) { case TypeInfo::TupleKind: { return os << info.tuple; } - case TypeInfo::SignatureRefKind: { - os << "(ref "; - if (info.signatureRef.nullable) { - os << "null "; - } - return os << info.signatureRef.signature << ")"; - } - case TypeInfo::StructRefKind: { - os << "(ref "; - if (info.structRef.nullable) { - os << "null "; - } - return os << info.structRef.struct_ << ")"; - } - case TypeInfo::ArrayRefKind: { + case TypeInfo::RefKind: { os << "(ref "; - if (info.arrayRef.nullable) { + if (info.ref.nullable) { os << "null "; } - return os << info.arrayRef.array << ")"; + return os << info.ref.heapType << ")"; } case TypeInfo::RttKind: { return os << info.rtt; From afda2065c7e7aa210ca5d1c45f02e80dd62fa901 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 25 Aug 2020 23:24:32 +0200 Subject: [PATCH 5/9] basic tests --- test/example/typeinfo.cpp | 71 +++++++++++++++++++++++++++++++++++++-- test/example/typeinfo.txt | 25 +++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp index dc98667060f..4fe2496ba3c 100644 --- a/test/example/typeinfo.cpp +++ b/test/example/typeinfo.cpp @@ -6,6 +6,49 @@ using namespace wasm; void test_compound() { + { + HeapType func(HeapType::FuncKind); + assert(Type(func, true).getID() == Type::funcref); + assert(Type(func, false).getID() == Type(func, false).getID()); + assert(Type(func, false).getID() != Type(func, true).getID()); + HeapType sameFunc(HeapType::FuncKind); + assert(Type(func, false).getID() == Type(sameFunc, false).getID()); + + HeapType extern_(HeapType::ExternKind); + assert(Type(extern_, true).getID() == Type::externref); + assert(Type(extern_, false).getID() == Type(extern_, false).getID()); + assert(Type(extern_, false).getID() != Type(extern_, true).getID()); + HeapType sameExtern(HeapType::ExternKind); + assert(Type(extern_, false).getID() == Type(sameExtern, false).getID()); + + HeapType any(HeapType::AnyKind); + // assert(Type(any, true).getID() == Type::anyref); + assert(Type(any, false).getID() == Type(any, false).getID()); + assert(Type(any, false).getID() != Type(any, true).getID()); + HeapType sameAny(HeapType::AnyKind); + assert(Type(any, false).getID() == Type(sameAny, false).getID()); + + HeapType eq(HeapType::EqKind); + // assert(Type(eq, true).getID() == Type::eqref); + assert(Type(eq, false).getID() == Type(eq, false).getID()); + assert(Type(eq, false).getID() != Type(eq, true).getID()); + HeapType sameEq(HeapType::EqKind); + assert(Type(eq, false).getID() == Type(sameEq, false).getID()); + + HeapType i31(HeapType::I31Kind); + // assert(Type(i31, false).getID() == Type::i31ref); + assert(Type(i31, false).getID() == Type(i31, false).getID()); + assert(Type(i31, false).getID() != Type(i31, true).getID()); + HeapType sameI31(HeapType::I31Kind); + assert(Type(i31, false).getID() == Type(sameI31, false).getID()); + + HeapType exn(HeapType::ExnKind); + assert(Type(exn, true).getID() == Type::exnref); + assert(Type(exn, false).getID() == Type(exn, false).getID()); + assert(Type(exn, false).getID() != Type(exn, true).getID()); + HeapType sameExn(HeapType::ExnKind); + assert(Type(exn, false).getID() == Type(sameExn, false).getID()); + } { Signature signature(Type::i32, Type::none); assert(Type(signature, false).getID() == Type(signature, false).getID()); @@ -58,7 +101,31 @@ void test_compound() { void test_printing() { { - std::cout << ";; Signature\n"; + std::cout << ";; Heap types\n"; + std::cout << HeapType(HeapType::FuncKind) << "\n"; + std::cout << Type(HeapType::FuncKind, true) << "\n"; + std::cout << Type(HeapType::FuncKind, false) << "\n"; + std::cout << HeapType(HeapType::ExternKind) << "\n"; + std::cout << Type(HeapType::ExternKind, true) << "\n"; + std::cout << Type(HeapType::ExternKind, false) << "\n"; + std::cout << HeapType(HeapType::AnyKind) << "\n"; + std::cout << Type(HeapType::AnyKind, true) << "\n"; + std::cout << Type(HeapType::AnyKind, false) << "\n"; + std::cout << HeapType(HeapType::EqKind) << "\n"; + std::cout << Type(HeapType::EqKind, true) << "\n"; + std::cout << Type(HeapType::EqKind, false) << "\n"; + std::cout << HeapType(HeapType::I31Kind) << "\n"; + std::cout << Type(HeapType::I31Kind, true) << "\n"; + std::cout << Type(HeapType::I31Kind, false) << "\n"; + std::cout << HeapType(HeapType::ExnKind) << "\n"; + std::cout << Type(HeapType::ExnKind, true) << "\n"; + std::cout << Type(HeapType::ExnKind, false) << "\n"; + std::cout << HeapType(Signature(Type::none, Type::none)) << "\n"; + std::cout << HeapType(Struct({})) << "\n"; + std::cout << HeapType(Array({Type::i32, false})) << "\n"; + } + { + std::cout << "\n;; Signature\n"; Signature emptySignature(Type::none, Type::none); std::cout << emptySignature << "\n"; std::cout << Type(emptySignature, false) << "\n"; @@ -197,7 +264,7 @@ void test_printing() { } // TODO: Think about recursive types. Currently impossible to construct. { - std::cout << "\n;; Recursive\n"; + std::cout << "\n;; Recursive (not really)\n"; Signature signatureSignature(Type::none, Type::none); signatureSignature.params = Type(signatureSignature, false); // ^ copies diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt index 71e9a3e9c78..89755dbf253 100644 --- a/test/example/typeinfo.txt +++ b/test/example/typeinfo.txt @@ -1,3 +1,26 @@ +;; Heap types +func +funcref +(ref func) +extern +externref +(ref extern) +any +(ref null any) +(ref any) +eq +(ref null eq) +(ref eq) +i31 +(ref null i31) +(ref i31) +exn +exnref +(ref exn) +(func) +(struct) +(array i32) + ;; Signature (func) (ref (func)) @@ -63,7 +86,7 @@ none ((ref (func)) (ref null (func)) (ref (struct)) (ref null (struct)) (ref (array i32)) (ref null (array i32))) ((ref (func)) (ref null (func)) (ref (struct)) (ref null (struct)) (ref (array i32)) (ref null (array i32))) -;; Recursive +;; Recursive (not really) (func (param (ref (func)))) (ref (func (param (ref (func))))) (func (param (ref (array (ref (func)))))) From 74bb40daf07254cd4cb036600ae75a3ab8de8fca Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 26 Aug 2020 12:47:04 +0200 Subject: [PATCH 6/9] actually test Rtt (heh) --- src/wasm/wasm-type.cpp | 2 ++ test/example/typeinfo.cpp | 36 ++++++++++++++++++++++++++++++++++++ test/example/typeinfo.txt | 6 ++++++ 3 files changed, 44 insertions(+) diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 97235801033..a8e0140e51d 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -329,6 +329,8 @@ Type::Type(const HeapType& heapType, bool nullable) { id = canonicalize(TypeInfo(heapType, nullable)); } +Type::Type(const Rtt& rtt) { id = canonicalize(TypeInfo(rtt)); } + bool Type::isTuple() const { if (isBasic()) { return false; diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp index 4fe2496ba3c..deeec5b5e85 100644 --- a/test/example/typeinfo.cpp +++ b/test/example/typeinfo.cpp @@ -97,6 +97,33 @@ void test_compound() { Tuple otherTuple({Type::f64, Type::externref}); assert(Type(tuple).getID() != Type(otherTuple).getID()); } + { + Rtt rtt(0, HeapType::FuncKind); + assert(Type(rtt).getID() == Type(rtt).getID()); + + Rtt sameRtt(0, HeapType::FuncKind); + assert(rtt == sameRtt); + assert(Type(rtt).getID() == Type(sameRtt).getID()); + + Rtt otherDepthRtt(1, HeapType::FuncKind); + assert(rtt != otherDepthRtt); + assert(Type(rtt).getID() != Type(otherDepthRtt).getID()); + + Rtt otherHeapTypeRtt(0, HeapType::AnyKind); + assert(rtt != otherHeapTypeRtt); + assert(Type(rtt).getID() != Type(otherHeapTypeRtt).getID()); + + Rtt structRtt(0, Struct({})); + assert(Type(structRtt).getID() == Type(structRtt).getID()); + + Rtt sameStructRtt(0, Struct({})); + assert(structRtt == sameStructRtt); + assert(Type(structRtt).getID() == Type(sameStructRtt).getID()); + + Rtt otherStructRtt(0, Struct({{Type::i32, false}})); + assert(structRtt != otherStructRtt); + assert(Type(structRtt).getID() != Type(otherStructRtt).getID()); + } } void test_printing() { @@ -176,6 +203,15 @@ void test_printing() { std::cout << tuple << "\n"; std::cout << Type(tuple) << "\n"; } + { + std::cout << "\n;; Rtt\n"; + Rtt rtt(0, HeapType::FuncKind); + std::cout << rtt << "\n"; + std::cout << Type(rtt) << "\n"; + Rtt rttCompound(1, Struct({})); + std::cout << rttCompound << "\n"; + std::cout << Type(rttCompound) << "\n"; + } { std::cout << "\n;; Signature of references (param/result)\n"; Signature signature(Type(Struct({}), true), diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt index 89755dbf253..1f9fa9ef968 100644 --- a/test/example/typeinfo.txt +++ b/test/example/typeinfo.txt @@ -51,6 +51,12 @@ none (i32 f64 externref) (i32 f64 externref) +;; Rtt +(rtt 0 func) +(rtt 0 func) +(rtt 1 (struct)) +(rtt 1 (struct)) + ;; Signature of references (param/result) (func (param (ref null (struct))) (result (ref (array (mut i32))))) From 6eba0fd8d8535270cf17fe01dd7612fbeb7ce76d Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 26 Aug 2020 12:54:04 +0200 Subject: [PATCH 7/9] more --- test/example/typeinfo.cpp | 27 +++++++++++++++++++++------ test/example/typeinfo.txt | 18 ++++++++++++++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp index deeec5b5e85..ac01c6a1b8c 100644 --- a/test/example/typeinfo.cpp +++ b/test/example/typeinfo.cpp @@ -205,12 +205,27 @@ void test_printing() { } { std::cout << "\n;; Rtt\n"; - Rtt rtt(0, HeapType::FuncKind); - std::cout << rtt << "\n"; - std::cout << Type(rtt) << "\n"; - Rtt rttCompound(1, Struct({})); - std::cout << rttCompound << "\n"; - std::cout << Type(rttCompound) << "\n"; + std::cout << Rtt(0, HeapType::FuncKind) << "\n"; + std::cout << Type(Rtt(0, HeapType::FuncKind)) << "\n"; + std::cout << Rtt(1, HeapType::ExternKind) << "\n"; + std::cout << Type(Rtt(1, HeapType::ExternKind)) << "\n"; + std::cout << Rtt(2, HeapType::AnyKind) << "\n"; + std::cout << Type(Rtt(2, HeapType::AnyKind)) << "\n"; + std::cout << Rtt(3, HeapType::EqKind) << "\n"; + std::cout << Type(Rtt(3, HeapType::EqKind)) << "\n"; + std::cout << Rtt(4, HeapType::I31Kind) << "\n"; + std::cout << Type(Rtt(4, HeapType::I31Kind)) << "\n"; + std::cout << Rtt(5, HeapType::ExnKind) << "\n"; + std::cout << Type(Rtt(5, HeapType::ExnKind)) << "\n"; + Rtt signatureRtt(6, Signature(Type::none, Type::none)); + std::cout << signatureRtt << "\n"; + std::cout << Type(signatureRtt) << "\n"; + Rtt structRtt(7, Struct({})); + std::cout << structRtt << "\n"; + std::cout << Type(structRtt) << "\n"; + Rtt arrayRtt(8, Array({Type::i32, false})); + std::cout << arrayRtt << "\n"; + std::cout << Type(arrayRtt) << "\n"; } { std::cout << "\n;; Signature of references (param/result)\n"; diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt index 1f9fa9ef968..95706d5e28b 100644 --- a/test/example/typeinfo.txt +++ b/test/example/typeinfo.txt @@ -54,8 +54,22 @@ none ;; Rtt (rtt 0 func) (rtt 0 func) -(rtt 1 (struct)) -(rtt 1 (struct)) +(rtt 1 extern) +(rtt 1 extern) +(rtt 2 any) +(rtt 2 any) +(rtt 3 eq) +(rtt 3 eq) +(rtt 4 i31) +(rtt 4 i31) +(rtt 5 exn) +(rtt 5 exn) +(rtt 6 (func)) +(rtt 6 (func)) +(rtt 7 (struct)) +(rtt 7 (struct)) +(rtt 8 (array i32)) +(rtt 8 (array i32)) ;; Signature of references (param/result) (func (param (ref null (struct))) (result (ref (array (mut i32))))) From 1cb2737852d59e2ce6d03773134746362d174939 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 26 Aug 2020 13:36:15 +0200 Subject: [PATCH 8/9] update diagram --- src/wasm-type.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index 9970db06061..b13c3df6c43 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -87,7 +87,7 @@ class Type { // │ f32 ║ x │ │ x │ x │ F │ │ F_loat // │ f64 ║ x │ │ x │ x │ F │ │ V_ector // │ v128 ║ x │ │ x │ x │ V │ ┘ - // ├─────────────╫───┼───┼───┼───┤───────┤ + // ├─ Aliases ───╫───┼───┼───┼───┤───────┤ // │ funcref ║ x │ │ x │ x │ f n │ ┐ Ref // │ externref ║ x │ │ x │ x │ f? n │ │ f_unc, n_ullable // │ anyref ║ x │ │ x │ x │ f? n │ │ ┐ @@ -95,10 +95,8 @@ class Type { // │ i31ref ║ x │ │ x │ x │ │ │ ┘ // │ nullref ║ x │ │ x │ x │ f? n │ │ ◄ TODO (removed) // │ exnref ║ x │ │ x │ x │ n │ │ - // ├─────────────╫───┼───┼───┼───┤───────┤ │ - // │ Signature ║ │ x │ x │ x │ f n? │ │ - // │ Struct ║ │ x │ x │ x │ n? │ │ - // │ Array ║ │ x │ x │ x │ n? │ ┘ + // ├─ Compound ──╫───┼───┼───┼───┤───────┤ │ + // │ Ref ║ │ x │ x │ x │ f? n? │◄┘ // │ Tuple ║ │ x │ │ x │ │ // │ Rtt ║ │ x │ x │ x │ │ // └─────────────╨───┴───┴───┴───┴───────┘ From 28745e9d858b892950d3ffb0000ac475c4cefbc9 Mon Sep 17 00:00:00 2001 From: dcode Date: Wed, 26 Aug 2020 22:23:56 +0200 Subject: [PATCH 9/9] move less trivial methods into the .cpp file --- src/wasm-type.h | 79 ++++-------------------------------------- src/wasm/wasm-type.cpp | 74 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 72 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index b13c3df6c43..8a9e58ec975 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -326,78 +326,9 @@ struct HeapType { HeapType(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {} HeapType(const Array& array) : kind(ArrayKind), array(array) {} HeapType(Array&& array) : kind(ArrayKind), array(std::move(array)) {} - HeapType(const HeapType& other) { - kind = other.kind; - switch (kind) { - case FuncKind: - case ExternKind: - case AnyKind: - case EqKind: - case I31Kind: - case ExnKind: - return; - case SignatureKind: - new (&signature) auto(other.signature); - return; - case StructKind: - new (&struct_) auto(other.struct_); - return; - case ArrayKind: - new (&array) auto(other.array); - return; - } - WASM_UNREACHABLE("unexpected kind"); - } - ~HeapType() { - switch (kind) { - case FuncKind: - case ExternKind: - case AnyKind: - case EqKind: - case I31Kind: - case ExnKind: - return; - case SignatureKind: - signature.~Signature(); - return; - case StructKind: - struct_.~Struct(); - return; - case ArrayKind: - array.~Array(); - return; - } - WASM_UNREACHABLE("unexpected kind"); - } - bool operator==(const HeapType& other) const { - if (kind != other.kind) { - return false; - } - switch (kind) { - case FuncKind: - case ExternKind: - case AnyKind: - case EqKind: - case I31Kind: - case ExnKind: - return true; - case SignatureKind: - return signature == other.signature; - case StructKind: - return struct_ == other.struct_; - case ArrayKind: - return array == other.array; - } - WASM_UNREACHABLE("unexpected kind"); - } - bool operator!=(const HeapType& other) const { return !(*this == other); } - HeapType& operator=(const HeapType& other) { - if (&other != this) { - this->~HeapType(); - new (this) auto(other); - } - return *this; - } + HeapType(const HeapType& other); + ~HeapType(); + bool isSignature() const { return kind == SignatureKind; } Signature getSignature() const { assert(isSignature() && "Not a signature"); @@ -413,6 +344,10 @@ struct HeapType { assert(isArray() && "Not an array"); return array; } + + bool operator==(const HeapType& other) const; + bool operator!=(const HeapType& other) const { return !(*this == other); } + HeapType& operator=(const HeapType& other); std::string toString() const; }; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index a8e0140e51d..e46cb58866c 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -554,6 +554,80 @@ const Type& Type::operator[](size_t index) const { } } +HeapType::HeapType(const HeapType& other) { + kind = other.kind; + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + case ExnKind: + return; + case SignatureKind: + new (&signature) auto(other.signature); + return; + case StructKind: + new (&struct_) auto(other.struct_); + return; + case ArrayKind: + new (&array) auto(other.array); + return; + } + WASM_UNREACHABLE("unexpected kind"); +} + +HeapType::~HeapType() { + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + case ExnKind: + return; + case SignatureKind: + signature.~Signature(); + return; + case StructKind: + struct_.~Struct(); + return; + case ArrayKind: + array.~Array(); + return; + } +} + +bool HeapType::operator==(const HeapType& other) const { + if (kind != other.kind) { + return false; + } + switch (kind) { + case FuncKind: + case ExternKind: + case AnyKind: + case EqKind: + case I31Kind: + case ExnKind: + return true; + case SignatureKind: + return signature == other.signature; + case StructKind: + return struct_ == other.struct_; + case ArrayKind: + return array == other.array; + } + WASM_UNREACHABLE("unexpected kind"); +} + +HeapType& HeapType::operator=(const HeapType& other) { + if (&other != this) { + this->~HeapType(); + new (this) auto(other); + } + return *this; +} + namespace { std::ostream&