summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-type.h1
-rw-r--r--src/wasm/wasm-type.cpp7
-rw-r--r--src/wasm/wasm-validator.cpp9
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,