summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-08-19 09:23:55 -0700
committerGitHub <noreply@github.com>2024-08-19 09:23:55 -0700
commit0b05a3ebc7feedfd28f54b6486cf3f2ec1864edb (patch)
tree530a4d6a6ccd4375f757a5b87f0ba16a4fbf6729
parente058bfbdf31c7b59df8ab62a9ebaedac45521c12 (diff)
downloadbinaryen-0b05a3ebc7feedfd28f54b6486cf3f2ec1864edb.tar.gz
binaryen-0b05a3ebc7feedfd28f54b6486cf3f2ec1864edb.tar.bz2
binaryen-0b05a3ebc7feedfd28f54b6486cf3f2ec1864edb.zip
[NFC] Use HeapType::getKind more broadly (#6846)
Replace code that checked `isStruct()`, `isArray()`, etc. in sequence with uses of `HeapType::getKind()` and switch statements. This will make it easier to find the code that needs updating if/when we add new heap type kinds in the future. It also makes it much easier to find code that already needs updating to handle continuation types by grepping for "TODO: cont".
-rw-r--r--src/ir/gc-type-utils.h13
-rw-r--r--src/ir/subtypes.h21
-rw-r--r--src/passes/TypeMerging.cpp51
-rw-r--r--src/passes/TypeSSA.cpp17
-rw-r--r--src/passes/Unsubtyping.cpp38
-rw-r--r--src/tools/fuzzing/fuzzing.cpp119
-rw-r--r--src/tools/fuzzing/heap-types.cpp132
-rw-r--r--src/tools/wasm-fuzz-types.cpp23
-rw-r--r--src/wasm/wasm-binary.cpp51
-rw-r--r--src/wasm/wasm-type.cpp161
10 files changed, 363 insertions, 263 deletions
diff --git a/src/ir/gc-type-utils.h b/src/ir/gc-type-utils.h
index 7c530e179..6ac6db3ba 100644
--- a/src/ir/gc-type-utils.h
+++ b/src/ir/gc-type-utils.h
@@ -149,10 +149,15 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) {
//
// TODO: use in more places
inline std::optional<Field> getField(HeapType type, Index index = 0) {
- if (type.isStruct()) {
- return type.getStruct().fields[index];
- } else if (type.isArray()) {
- return type.getArray().element;
+ switch (type.getKind()) {
+ case HeapTypeKind::Struct:
+ return type.getStruct().fields[index];
+ case HeapTypeKind::Array:
+ return type.getArray().element;
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ case HeapTypeKind::Basic:
+ break;
}
return {};
}
diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h
index 767c79fd7..203772055 100644
--- a/src/ir/subtypes.h
+++ b/src/ir/subtypes.h
@@ -125,13 +125,20 @@ struct SubTypes {
for (auto type : types) {
HeapType basic;
auto share = type.getShared();
- if (type.isStruct()) {
- basic = HeapTypes::struct_.getBasic(share);
- } else if (type.isArray()) {
- basic = HeapTypes::array.getBasic(share);
- } else {
- assert(type.isSignature());
- basic = HeapTypes::func.getBasic(share);
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ basic = HeapTypes::func.getBasic(share);
+ break;
+ case HeapTypeKind::Struct:
+ basic = HeapTypes::struct_.getBasic(share);
+ break;
+ case HeapTypeKind::Array:
+ basic = HeapTypes::array.getBasic(share);
+ break;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
auto& basicDepth = depths[basic];
basicDepth = std::max(basicDepth, depths[type] + 1);
diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp
index e5ac7888b..1cac7732f 100644
--- a/src/passes/TypeMerging.cpp
+++ b/src/passes/TypeMerging.cpp
@@ -544,14 +544,22 @@ bool shapeEq(HeapType a, HeapType b) {
if (a.isShared() != b.isShared()) {
return false;
}
- if (a.isStruct() && b.isStruct()) {
- return shapeEq(a.getStruct(), b.getStruct());
- }
- if (a.isArray() && b.isArray()) {
- return shapeEq(a.getArray(), b.getArray());
+ auto aKind = a.getKind();
+ auto bKind = b.getKind();
+ if (aKind != bKind) {
+ return false;
}
- if (a.isSignature() && b.isSignature()) {
- return shapeEq(a.getSignature(), b.getSignature());
+ switch (aKind) {
+ case HeapTypeKind::Func:
+ return shapeEq(a.getSignature(), b.getSignature());
+ case HeapTypeKind::Struct:
+ return shapeEq(a.getStruct(), b.getStruct());
+ case HeapTypeKind::Array:
+ return shapeEq(a.getArray(), b.getArray());
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
return false;
}
@@ -559,19 +567,24 @@ bool shapeEq(HeapType a, HeapType b) {
size_t shapeHash(HeapType a) {
size_t digest = hash(a.isOpen());
rehash(digest, a.isShared());
- if (a.isStruct()) {
- rehash(digest, 0);
- hash_combine(digest, shapeHash(a.getStruct()));
- } else if (a.isArray()) {
- rehash(digest, 1);
- hash_combine(digest, shapeHash(a.getArray()));
- } else if (a.isSignature()) {
- rehash(digest, 2);
- hash_combine(digest, shapeHash(a.getSignature()));
- } else {
- WASM_UNREACHABLE("unexpected kind");
+ auto kind = a.getKind();
+ rehash(digest, kind);
+ switch (kind) {
+ case HeapTypeKind::Func:
+ hash_combine(digest, shapeHash(a.getSignature()));
+ return digest;
+ case HeapTypeKind::Struct:
+ hash_combine(digest, shapeHash(a.getStruct()));
+ return digest;
+ case HeapTypeKind::Array:
+ hash_combine(digest, shapeHash(a.getArray()));
+ return digest;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
- return digest;
+ WASM_UNREACHABLE("unexpected kind");
}
bool shapeEq(const Struct& a, const Struct& b) {
diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp
index 1355b113e..8ba6c10c4 100644
--- a/src/passes/TypeSSA.cpp
+++ b/src/passes/TypeSSA.cpp
@@ -237,12 +237,17 @@ struct TypeSSA : public Pass {
for (Index i = 0; i < num; i++) {
auto* curr = newsToModify[i];
auto oldType = curr->type.getHeapType();
- if (oldType.isStruct()) {
- builder[i] = oldType.getStruct();
- } else if (oldType.isArray()) {
- builder[i] = oldType.getArray();
- } else {
- WASM_UNREACHABLE("unexpected type kind");
+ switch (oldType.getKind()) {
+ case HeapTypeKind::Struct:
+ builder[i] = oldType.getStruct();
+ break;
+ case HeapTypeKind::Array:
+ builder[i] = oldType.getArray();
+ break;
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
builder[i].subTypeOf(oldType);
builder[i].setShared(oldType.getShared());
diff --git a/src/passes/Unsubtyping.cpp b/src/passes/Unsubtyping.cpp
index ccad4ed3d..8d76f348a 100644
--- a/src/passes/Unsubtyping.cpp
+++ b/src/passes/Unsubtyping.cpp
@@ -264,21 +264,31 @@ struct Unsubtyping
if (super.isBasic()) {
continue;
}
- if (type.isStruct()) {
- const auto& fields = type.getStruct().fields;
- const auto& superFields = super.getStruct().fields;
- for (size_t i = 0, size = superFields.size(); i < size; ++i) {
- noteSubtype(fields[i].type, superFields[i].type);
+ switch (type.getKind()) {
+ case HeapTypeKind::Func: {
+ auto sig = type.getSignature();
+ auto superSig = super.getSignature();
+ noteSubtype(superSig.params, sig.params);
+ noteSubtype(sig.results, superSig.results);
+ break;
}
- } else if (type.isArray()) {
- auto elem = type.getArray().element;
- noteSubtype(elem.type, super.getArray().element.type);
- } else {
- assert(type.isSignature());
- auto sig = type.getSignature();
- auto superSig = super.getSignature();
- noteSubtype(superSig.params, sig.params);
- noteSubtype(sig.results, superSig.results);
+ case HeapTypeKind::Struct: {
+ const auto& fields = type.getStruct().fields;
+ const auto& superFields = super.getStruct().fields;
+ for (size_t i = 0, size = superFields.size(); i < size; ++i) {
+ noteSubtype(fields[i].type, superFields[i].type);
+ }
+ break;
+ }
+ case HeapTypeKind::Array: {
+ auto elem = type.getArray().element;
+ noteSubtype(elem.type, super.getArray().element.type);
+ break;
+ }
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 64780696b..bebf4f989 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -291,28 +291,35 @@ void TranslateToFuzzReader::setupHeapTypes() {
auto eq = HeapTypes::eq.getBasic(share);
auto any = HeapTypes::any.getBasic(share);
auto func = HeapTypes::func.getBasic(share);
- if (type.isStruct()) {
- interestingHeapSubTypes[struct_].push_back(type);
- interestingHeapSubTypes[eq].push_back(type);
- interestingHeapSubTypes[any].push_back(type);
-
- // Note the mutable fields.
- auto& fields = type.getStruct().fields;
- for (Index i = 0; i < fields.size(); i++) {
- if (fields[i].mutable_) {
- mutableStructFields.push_back(StructField{type, i});
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ interestingHeapSubTypes[func].push_back(type);
+ break;
+ case HeapTypeKind::Struct: {
+ interestingHeapSubTypes[struct_].push_back(type);
+ interestingHeapSubTypes[eq].push_back(type);
+ interestingHeapSubTypes[any].push_back(type);
+ // Note the mutable fields.
+ auto& fields = type.getStruct().fields;
+ for (Index i = 0; i < fields.size(); i++) {
+ if (fields[i].mutable_) {
+ mutableStructFields.push_back(StructField{type, i});
+ }
}
+ break;
}
- } else if (type.isArray()) {
- interestingHeapSubTypes[array].push_back(type);
- interestingHeapSubTypes[eq].push_back(type);
- interestingHeapSubTypes[any].push_back(type);
-
- if (type.getArray().element.mutable_) {
- mutableArrays.push_back(type);
- }
- } else if (type.isSignature()) {
- interestingHeapSubTypes[func].push_back(type);
+ case HeapTypeKind::Array:
+ interestingHeapSubTypes[array].push_back(type);
+ interestingHeapSubTypes[eq].push_back(type);
+ interestingHeapSubTypes[any].push_back(type);
+ if (type.getArray().element.mutable_) {
+ mutableArrays.push_back(type);
+ }
+ break;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
@@ -2757,43 +2764,49 @@ Expression* TranslateToFuzzReader::makeCompoundRef(Type type) {
return funcContext ? make(type) : makeTrivial(type);
};
- if (heapType.isSignature()) {
- return makeRefFuncConst(type);
- } else if (type.isStruct()) {
- auto& fields = heapType.getStruct().fields;
- std::vector<Expression*> values;
- // If there is a nondefaultable field, we must provide the value and not
- // depend on defaults. Also do that randomly half the time.
- if (std::any_of(
- fields.begin(),
- fields.end(),
- [&](const Field& field) { return !field.type.isDefaultable(); }) ||
- oneIn(2)) {
- for (auto& field : fields) {
- values.push_back(makeChild(field.type));
- }
- // Add more nesting manually, as we can easily get exponential blowup
- // here. This nesting makes it much less likely for a recursive data
- // structure to end up as a massive tree of struct.news, since the nesting
- // limitation code at the top of this function will kick in.
- if (!values.empty()) {
- // Subtract 1 since if there is a single value there cannot be
- // exponential blowup.
- nester.add(values.size() - 1);
+ switch (heapType.getKind()) {
+ case HeapTypeKind::Func:
+ return makeRefFuncConst(type);
+ case HeapTypeKind::Struct: {
+ auto& fields = heapType.getStruct().fields;
+ std::vector<Expression*> values;
+ // If there is a nondefaultable field, we must provide the value and not
+ // depend on defaults. Also do that randomly half the time.
+ if (std::any_of(
+ fields.begin(),
+ fields.end(),
+ [&](const Field& field) { return !field.type.isDefaultable(); }) ||
+ oneIn(2)) {
+ for (auto& field : fields) {
+ values.push_back(makeChild(field.type));
+ }
+ // Add more nesting manually, as we can easily get exponential blowup
+ // here. This nesting makes it much less likely for a recursive data
+ // structure to end up as a massive tree of struct.news, since the
+ // nesting limitation code at the top of this function will kick in.
+ if (!values.empty()) {
+ // Subtract 1 since if there is a single value there cannot be
+ // exponential blowup.
+ nester.add(values.size() - 1);
+ }
}
+ return builder.makeStructNew(heapType, values);
}
- return builder.makeStructNew(heapType, values);
- } else if (type.isArray()) {
- auto element = heapType.getArray().element;
- Expression* init = nullptr;
- if (!element.type.isDefaultable() || oneIn(2)) {
- init = makeChild(element.type);
+ case HeapTypeKind::Array: {
+ auto element = heapType.getArray().element;
+ Expression* init = nullptr;
+ if (!element.type.isDefaultable() || oneIn(2)) {
+ init = makeChild(element.type);
+ }
+ auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE)));
+ return builder.makeArrayNew(type.getHeapType(), count, init);
}
- auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE)));
- return builder.makeArrayNew(type.getHeapType(), count, init);
- } else {
- WASM_UNREACHABLE("bad user-defined ref type");
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
+ WASM_UNREACHABLE("unexpected kind");
}
Expression* TranslateToFuzzReader::makeStringNewArray() {
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index e4d54ae07..b4833475a 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -131,14 +131,20 @@ struct HeapTypeGeneratorImpl {
} else {
// We have a supertype, so create a subtype.
HeapType supertype = builder[*supertypeIndices[index]];
- if (supertype.isSignature()) {
- builder[index] = generateSubSignature(supertype.getSignature());
- } else if (supertype.isStruct()) {
- builder[index] = generateSubStruct(supertype.getStruct(), share);
- } else if (supertype.isArray()) {
- builder[index] = generateSubArray(supertype.getArray());
- } else {
- WASM_UNREACHABLE("unexpected kind");
+ switch (supertype.getKind()) {
+ case wasm::HeapTypeKind::Func:
+ builder[index] = generateSubSignature(supertype.getSignature());
+ break;
+ case wasm::HeapTypeKind::Struct:
+ builder[index] = generateSubStruct(supertype.getStruct(), share);
+ break;
+ case wasm::HeapTypeKind::Array:
+ builder[index] = generateSubArray(supertype.getArray());
+ break;
+ case wasm::HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case wasm::HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
}
@@ -879,38 +885,44 @@ std::vector<HeapType> Inhabitator::build() {
for (size_t i = 0; i < types.size(); ++i) {
auto type = types[i];
- if (type.isStruct()) {
- Struct copy = type.getStruct();
- for (size_t j = 0; j < copy.fields.size(); ++j) {
- updateType({type, j}, copy.fields[j].type);
+ switch (type.getKind()) {
+ case HeapTypeKind::Func: {
+ auto sig = type.getSignature();
+ size_t j = 0;
+ std::vector<Type> params;
+ for (auto param : sig.params) {
+ params.push_back(param);
+ updateType({type, j++}, params.back());
+ }
+ std::vector<Type> results;
+ for (auto result : sig.results) {
+ results.push_back(result);
+ updateType({type, j++}, results.back());
+ }
+ builder[i] = Signature(builder.getTempTupleType(params),
+ builder.getTempTupleType(results));
+ continue;
}
- builder[i] = copy;
- continue;
- }
- if (type.isArray()) {
- Array copy = type.getArray();
- updateType({type, 0}, copy.element.type);
- builder[i] = copy;
- continue;
- }
- if (type.isSignature()) {
- auto sig = type.getSignature();
- size_t j = 0;
- std::vector<Type> params;
- for (auto param : sig.params) {
- params.push_back(param);
- updateType({type, j++}, params.back());
+ case HeapTypeKind::Struct: {
+ Struct copy = type.getStruct();
+ for (size_t j = 0; j < copy.fields.size(); ++j) {
+ updateType({type, j}, copy.fields[j].type);
+ }
+ builder[i] = copy;
+ continue;
}
- std::vector<Type> results;
- for (auto result : sig.results) {
- results.push_back(result);
- updateType({type, j++}, results.back());
+ case HeapTypeKind::Array: {
+ Array copy = type.getArray();
+ updateType({type, 0}, copy.element.type);
+ builder[i] = copy;
+ continue;
}
- builder[i] = Signature(builder.getTempTupleType(params),
- builder.getTempTupleType(results));
- continue;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
- WASM_UNREACHABLE("unexpected type kind");
+ WASM_UNREACHABLE("unexpected kind");
}
// Establish rec groups.
@@ -994,35 +1006,43 @@ bool isUninhabitable(Type type,
bool isUninhabitable(HeapType type,
std::unordered_set<HeapType>& visited,
std::unordered_set<HeapType>& visiting) {
- if (type.isBasic()) {
- return false;
- }
- if (type.isSignature()) {
- // Function types are always inhabitable.
- return false;
+ switch (type.getKind()) {
+ case HeapTypeKind::Basic:
+ return false;
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ // Function types are always inhabitable.
+ return false;
+ case HeapTypeKind::Struct:
+ case HeapTypeKind::Array:
+ break;
}
if (visited.count(type)) {
return false;
}
-
- if (!visiting.insert(type).second) {
+ auto [it, inserted] = visiting.insert(type);
+ if (!inserted) {
return true;
}
-
- if (type.isStruct()) {
- for (auto& field : type.getStruct().fields) {
- if (isUninhabitable(field.type, visited, visiting)) {
+ switch (type.getKind()) {
+ case HeapTypeKind::Struct:
+ for (auto& field : type.getStruct().fields) {
+ if (isUninhabitable(field.type, visited, visiting)) {
+ return true;
+ }
+ }
+ break;
+ case HeapTypeKind::Array:
+ if (isUninhabitable(type.getArray().element.type, visited, visiting)) {
return true;
}
- }
- } else if (type.isArray()) {
- if (isUninhabitable(type.getArray().element.type, visited, visiting)) {
- return true;
- }
- } else {
- WASM_UNREACHABLE("unexpected type kind");
+ break;
+ case HeapTypeKind::Basic:
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("unexpected kind");
}
- visiting.erase(type);
+ visiting.erase(it);
visited.insert(type);
return false;
}
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp
index 074d235c9..7ba341e09 100644
--- a/src/tools/wasm-fuzz-types.cpp
+++ b/src/tools/wasm-fuzz-types.cpp
@@ -297,15 +297,22 @@ void Fuzzer::checkCanonicalization() {
// Copy the original types
for (; index < types.size(); ++index) {
auto type = types[index];
- if (type.isSignature()) {
- builder[index] = getSignature(type.getSignature());
- } else if (type.isStruct()) {
- builder[index] = getStruct(type.getStruct());
- } else if (type.isArray()) {
- builder[index] = getArray(type.getArray());
- } else {
- WASM_UNREACHABLE("unexpected type kind");
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ builder[index] = getSignature(type.getSignature());
+ continue;
+ case HeapTypeKind::Struct:
+ builder[index] = getStruct(type.getStruct());
+ continue;
+ case HeapTypeKind::Array:
+ builder[index] = getArray(type.getArray());
+ continue;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
+ WASM_UNREACHABLE("unexpected type kind");
}
}
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 2abb32837..8565ddaad 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -291,30 +291,37 @@ void WasmBinaryWriter::writeTypes() {
if (type.isShared()) {
o << S32LEB(BinaryConsts::EncodedType::Shared);
}
- if (type.isSignature()) {
- o << S32LEB(BinaryConsts::EncodedType::Func);
- auto sig = type.getSignature();
- for (auto& sigType : {sig.params, sig.results}) {
- o << U32LEB(sigType.size());
- for (const auto& type : sigType) {
- writeType(type);
+ switch (type.getKind()) {
+ case HeapTypeKind::Func: {
+ o << S32LEB(BinaryConsts::EncodedType::Func);
+ auto sig = type.getSignature();
+ for (auto& sigType : {sig.params, sig.results}) {
+ o << U32LEB(sigType.size());
+ for (const auto& type : sigType) {
+ writeType(type);
+ }
}
+ break;
}
- } else if (type.isContinuation()) {
- o << S32LEB(BinaryConsts::EncodedType::Cont);
- writeHeapType(type.getContinuation().type);
- } else if (type.isStruct()) {
- o << S32LEB(BinaryConsts::EncodedType::Struct);
- auto fields = type.getStruct().fields;
- o << U32LEB(fields.size());
- for (const auto& field : fields) {
- writeField(field);
- }
- } else if (type.isArray()) {
- o << S32LEB(BinaryConsts::EncodedType::Array);
- writeField(type.getArray().element);
- } else {
- WASM_UNREACHABLE("TODO GC type writing");
+ case HeapTypeKind::Struct: {
+ o << S32LEB(BinaryConsts::EncodedType::Struct);
+ auto fields = type.getStruct().fields;
+ o << U32LEB(fields.size());
+ for (const auto& field : fields) {
+ writeField(field);
+ }
+ break;
+ }
+ case HeapTypeKind::Array:
+ o << S32LEB(BinaryConsts::EncodedType::Array);
+ writeField(type.getArray().element);
+ break;
+ case HeapTypeKind::Cont:
+ o << S32LEB(BinaryConsts::EncodedType::Cont);
+ writeHeapType(type.getContinuation().type);
+ break;
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
finishSection(start);
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 34299a9a1..84ae51521 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -1233,42 +1233,46 @@ size_t HeapType::getDepth() const {
// In addition to the explicit supertypes we just traversed over, there is
// implicit supertyping wrt basic types. A signature type always has one more
// super, HeapType::func, etc.
- if (!isBasic()) {
- if (isFunction() || isContinuation()) {
- depth++;
- } else if (isStruct()) {
+ switch (getKind()) {
+ case HeapTypeKind::Basic:
+ // Some basic types have supers.
+ switch (getBasic(Unshared)) {
+ case HeapType::ext:
+ case HeapType::func:
+ case HeapType::cont:
+ case HeapType::any:
+ case HeapType::exn:
+ break;
+ case HeapType::eq:
+ depth++;
+ break;
+ case HeapType::i31:
+ case HeapType::struct_:
+ case HeapType::array:
+ case HeapType::string:
+ depth += 2;
+ break;
+ case HeapType::none:
+ case HeapType::nofunc:
+ case HeapType::nocont:
+ case HeapType::noext:
+ case HeapType::noexn:
+ // Bottom types are infinitely deep.
+ depth = size_t(-1l);
+ }
+ break;
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ ++depth;
+ break;
+ case HeapTypeKind::Struct:
// specific struct types <: struct <: eq <: any
depth += 3;
- } else if (isArray()) {
+ break;
+ case HeapTypeKind::Array:
// specific array types <: array <: eq <: any
depth += 3;
- }
- } else {
- // Some basic types have supers.
- switch (getBasic(Unshared)) {
- case HeapType::ext:
- case HeapType::func:
- case HeapType::cont:
- case HeapType::any:
- case HeapType::exn:
- break;
- case HeapType::eq:
- depth++;
- break;
- case HeapType::i31:
- case HeapType::struct_:
- case HeapType::array:
- case HeapType::string:
- depth += 2;
- break;
- case HeapType::none:
- case HeapType::nofunc:
- case HeapType::nocont:
- case HeapType::noext:
- case HeapType::noexn:
- // Bottom types are infinitely deep.
- depth = size_t(-1l);
- }
+ break;
}
return depth;
}
@@ -1353,31 +1357,30 @@ bool HeapType::isSubType(HeapType left, HeapType right) {
}
std::vector<Type> HeapType::getTypeChildren() const {
- if (isBasic()) {
- return {};
- }
- if (isStruct()) {
- std::vector<Type> children;
- for (auto& field : getStruct().fields) {
- children.push_back(field.type);
+ switch (getKind()) {
+ case HeapTypeKind::Basic:
+ return {};
+ case HeapTypeKind::Func: {
+ std::vector<Type> children;
+ auto sig = getSignature();
+ for (auto tuple : {sig.params, sig.results}) {
+ for (auto t : tuple) {
+ children.push_back(t);
+ }
+ }
+ return children;
}
- return children;
- }
- if (isArray()) {
- return {getArray().element.type};
- }
- if (isSignature()) {
- std::vector<Type> children;
- auto sig = getSignature();
- for (auto tuple : {sig.params, sig.results}) {
- for (auto t : tuple) {
- children.push_back(t);
+ case HeapTypeKind::Struct: {
+ std::vector<Type> children;
+ for (auto& field : getStruct().fields) {
+ children.push_back(field.type);
}
+ return children;
}
- return children;
- }
- if (isContinuation()) {
- return {};
+ case HeapTypeKind::Array:
+ return {getArray().element.type};
+ case HeapTypeKind::Cont:
+ return {};
}
WASM_UNREACHABLE("unexpected kind");
}
@@ -1586,16 +1589,21 @@ TypeNames DefaultTypeNameGenerator::getNames(HeapType type) {
if (inserted) {
// Generate a new name for this type we have not previously seen.
std::stringstream stream;
- if (type.isSignature()) {
- stream << "func." << funcCount++;
- } else if (type.isContinuation()) {
- stream << "cont." << contCount++;
- } else if (type.isStruct()) {
- stream << "struct." << structCount++;
- } else if (type.isArray()) {
- stream << "array." << arrayCount++;
- } else {
- WASM_UNREACHABLE("unexpected kind");
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ stream << "func." << funcCount++;
+ break;
+ case HeapTypeKind::Struct:
+ stream << "struct." << structCount++;
+ break;
+ case HeapTypeKind::Array:
+ stream << "array." << arrayCount++;
+ break;
+ case HeapTypeKind::Cont:
+ stream << "cont." << contCount++;
+ break;
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
it->second = {stream.str(), {}};
}
@@ -1972,16 +1980,21 @@ std::ostream& TypePrinter::print(HeapType type) {
if (type.isShared()) {
os << "(shared ";
}
- if (type.isSignature()) {
- print(type.getSignature());
- } else if (type.isContinuation()) {
- print(type.getContinuation());
- } else if (type.isStruct()) {
- print(type.getStruct(), names.fieldNames);
- } else if (type.isArray()) {
- print(type.getArray());
- } else {
- WASM_UNREACHABLE("unexpected type");
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ print(type.getSignature());
+ break;
+ case HeapTypeKind::Struct:
+ print(type.getStruct(), names.fieldNames);
+ break;
+ case HeapTypeKind::Array:
+ print(type.getArray());
+ break;
+ case HeapTypeKind::Cont:
+ print(type.getContinuation());
+ break;
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
if (type.isShared()) {
os << ')';