diff options
-rw-r--r-- | src/wasm-type.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 9 |
3 files changed, 11 insertions, 6 deletions
diff --git a/src/wasm-type.h b/src/wasm-type.h index 0df3bfeed..958e14477 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -141,6 +141,7 @@ public: bool isRtt() const; bool isStruct() const; bool isArray() const; + bool isDefaultable() const; private: template<bool (Type::*pred)() const> bool hasPredicate() { diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 31290c745..ffc18b9fd 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -411,6 +411,13 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); } bool Type::isArray() const { return isRef() && getHeapType().isArray(); } +bool Type::isDefaultable() const { + // A variable can get a default value if its type is concrete (unreachable + // and none have no values, hence no default), and if it's a reference, it + // must be nullable. + return isConcrete() && (!isRef() || isNullable()); +} + bool Type::operator<(const Type& other) const { if (*this == other) { return false; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index bf6e121bf..b0fc4d9c8 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2294,8 +2294,7 @@ void FunctionValidator::visitStructNew(StructNew* curr) { "struct.new_with_default should have no operands"); // All the fields must be defaultable. for (const auto& field : fields) { - // TODO: add type.isDefaultable()? - shouldBeTrue(!field.type.isRef() || field.type.isNullable(), + shouldBeTrue(field.type.isDefaultable(), field, "struct.new_with_default value type must be defaultable"); } @@ -2368,8 +2367,7 @@ void FunctionValidator::visitArrayNew(ArrayNew* curr) { shouldBeTrue( !curr->init, curr, "array.new_with_default should have no init"); // The element must be defaultable. - // TODO: add type.isDefaultable()? - shouldBeTrue(!element.type.isRef() || element.type.isNullable(), + shouldBeTrue(element.type.isDefaultable(), element, "array.new_with_default value type must be defaultable"); } else { @@ -2439,8 +2437,7 @@ void FunctionValidator::visitFunction(Function* curr) { } for (const auto& var : curr->vars) { features |= var.getFeatures(); - shouldBeTrue(var.isConcrete(), curr, "vars must be concretely typed"); - // TODO: check for nullability + shouldBeTrue(var.isDefaultable(), curr, "vars must be defaultable"); } shouldBeTrue(features <= getModule()->features, curr->name, |