summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-validator.cpp99
-rw-r--r--test/exception-handling.wast5
-rw-r--r--test/exception-handling.wast.from-wast5
-rw-r--r--test/exception-handling.wast.fromBinary5
-rw-r--r--test/exception-handling.wast.fromBinary.noDebugInfo5
5 files changed, 71 insertions, 48 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 7bf51c5f7..b19ed096f 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -197,11 +197,11 @@ struct ValidationInfo {
}
// Type 'left' should be a subtype of 'right', or unreachable.
- bool shouldBeSubTypeOrUnreachable(Type left,
- Type right,
- Expression* curr,
- const char* text,
- Function* func = nullptr) {
+ bool shouldBeSubTypeOrFirstIsUnreachable(Type left,
+ Type right,
+ Expression* curr,
+ const char* text,
+ Function* func = nullptr) {
if (left == Type::unreachable) {
return true;
}
@@ -360,11 +360,11 @@ private:
return info.shouldBeSubType(left, right, curr, text, getFunction());
}
- bool shouldBeSubTypeOrUnreachable(Type left,
- Type right,
- Expression* curr,
- const char* text) {
- return info.shouldBeSubTypeOrUnreachable(
+ bool shouldBeSubTypeOrFirstIsUnreachable(Type left,
+ Type right,
+ Expression* curr,
+ const char* text) {
+ return info.shouldBeSubTypeOrFirstIsUnreachable(
left, right, curr, text, getFunction());
}
@@ -503,10 +503,11 @@ void FunctionValidator::visitLoop(Loop* curr) {
"if loop is not returning a value, final element should "
"not flow out a value");
} else {
- shouldBeSubTypeOrUnreachable(curr->body->type,
- curr->type,
- curr,
- "loop with value and body must match types");
+ shouldBeSubTypeOrFirstIsUnreachable(
+ curr->body->type,
+ curr->type,
+ curr,
+ "loop with value and body must match types");
}
}
}
@@ -528,12 +529,12 @@ void FunctionValidator::visitIf(If* curr) {
}
} else {
if (curr->type != unreachable) {
- shouldBeSubTypeOrUnreachable(
+ shouldBeSubTypeOrFirstIsUnreachable(
curr->ifTrue->type,
curr->type,
curr,
"returning if-else's true must have right type");
- shouldBeSubTypeOrUnreachable(
+ shouldBeSubTypeOrFirstIsUnreachable(
curr->ifFalse->type,
curr->type,
curr,
@@ -637,10 +638,10 @@ void FunctionValidator::visitCall(Call* curr) {
return;
}
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeSubTypeOrUnreachable(curr->operands[i]->type,
- params[i],
- curr,
- "call param types must match") &&
+ if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
+ params[i],
+ curr,
+ "call param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
@@ -690,10 +691,10 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
return;
}
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeSubTypeOrUnreachable(curr->operands[i]->type,
- params[i],
- curr,
- "call param types must match") &&
+ if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
+ params[i],
+ curr,
+ "call param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
@@ -787,10 +788,11 @@ void FunctionValidator::visitGlobalSet(GlobalSet* curr) {
"global.set name must be valid (and not an import; imports "
"can't be modified)")) {
shouldBeTrue(global->mutable_, curr, "global.set global must be mutable");
- shouldBeSubTypeOrUnreachable(curr->value->type,
- global->type,
- curr,
- "global.set value must have right type");
+ shouldBeSubTypeOrFirstIsUnreachable(
+ curr->value->type,
+ global->type,
+ curr,
+ "global.set value must have right type");
}
}
@@ -1715,14 +1717,16 @@ void FunctionValidator::visitRefFunc(RefFunc* curr) {
void FunctionValidator::visitTry(Try* curr) {
if (curr->type != unreachable) {
- shouldBeSubTypeOrUnreachable(curr->body->type,
- curr->type,
- curr->body,
- "try's type does not match try body's type");
- shouldBeSubTypeOrUnreachable(curr->catchBody->type,
- curr->type,
- curr->catchBody,
- "try's type does not match catch's body type");
+ shouldBeSubTypeOrFirstIsUnreachable(
+ curr->body->type,
+ curr->type,
+ curr->body,
+ "try's type does not match try body's type");
+ shouldBeSubTypeOrFirstIsUnreachable(
+ curr->catchBody->type,
+ curr->type,
+ curr->catchBody,
+ "try's type does not match catch's body type");
} else {
shouldBeEqual(curr->body->type,
unreachable,
@@ -1752,10 +1756,10 @@ void FunctionValidator::visitThrow(Throw* curr) {
}
const std::vector<Type>& paramTypes = event->sig.params.expand();
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type,
- paramTypes[i],
- curr->operands[i],
- "event param types must match") &&
+ if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
+ paramTypes[i],
+ curr->operands[i],
+ "event param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
@@ -1765,10 +1769,11 @@ void FunctionValidator::visitThrow(Throw* curr) {
void FunctionValidator::visitRethrow(Rethrow* curr) {
shouldBeEqual(
curr->type, unreachable, curr, "rethrow's type must be unreachable");
- shouldBeSubType(curr->exnref->type,
- Type::exnref,
- curr->exnref,
- "rethrow's argument must be exnref type or its subtype");
+ shouldBeSubTypeOrFirstIsUnreachable(
+ curr->exnref->type,
+ Type::exnref,
+ curr->exnref,
+ "rethrow's argument must be exnref type or its subtype");
}
void FunctionValidator::visitBrOnExn(BrOnExn* curr) {
@@ -1778,7 +1783,7 @@ void FunctionValidator::visitBrOnExn(BrOnExn* curr) {
curr,
"br_on_exn's event params and event's params are different");
noteBreak(curr->name, curr->sent, curr);
- shouldBeSubTypeOrUnreachable(
+ shouldBeSubTypeOrFirstIsUnreachable(
curr->exnref->type,
Type::exnref,
curr,
@@ -1818,13 +1823,13 @@ void FunctionValidator::visitFunction(Function* curr) {
"all used types should be allowed");
// if function has no result, it is ignored
// if body is unreachable, it might be e.g. a return
- shouldBeSubTypeOrUnreachable(
+ shouldBeSubTypeOrFirstIsUnreachable(
curr->body->type,
curr->sig.results,
curr->body,
"function body type must match, if function returns");
for (Type returnType : returnTypes) {
- shouldBeSubTypeOrUnreachable(
+ shouldBeSubTypeOrFirstIsUnreachable(
returnType,
curr->sig.results,
curr->body,
diff --git a/test/exception-handling.wast b/test/exception-handling.wast
index 0929daeec..101136df2 100644
--- a/test/exception-handling.wast
+++ b/test/exception-handling.wast
@@ -1,5 +1,6 @@
(module
(event $e0 (attr 0) (param i32))
+ (event $e1 (attr 0) (param anyref))
(func $exnref_test (param $0 exnref) (result exnref)
(local.get $0)
@@ -54,7 +55,7 @@
)
)
- ;; Test subtype relationship for br_on_exn and rethrow
+ ;; Test subtype relationship
(func $subtype_test
(try
(catch
@@ -68,5 +69,7 @@
)
)
)
+
+ (throw $e1 (ref.null))
)
)
diff --git a/test/exception-handling.wast.from-wast b/test/exception-handling.wast.from-wast
index 93945c39c..f1826ccb6 100644
--- a/test/exception-handling.wast.from-wast
+++ b/test/exception-handling.wast.from-wast
@@ -1,8 +1,10 @@
(module
(type $none_=>_none (func))
(type $i32_=>_none (func (param i32)))
+ (type $anyref_=>_none (func (param anyref)))
(type $exnref_=>_exnref (func (param exnref) (result exnref)))
(event $e0 (attr 0) (param i32))
+ (event $e1 (attr 0) (param anyref))
(func $exnref_test (; 0 ;) (param $0 exnref) (result exnref)
(local.get $0)
)
@@ -81,5 +83,8 @@
)
)
)
+ (throw $e1
+ (ref.null)
+ )
)
)
diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary
index 369b17dd9..b5aba7e15 100644
--- a/test/exception-handling.wast.fromBinary
+++ b/test/exception-handling.wast.fromBinary
@@ -1,8 +1,10 @@
(module
(type $none_=>_none (func))
(type $i32_=>_none (func (param i32)))
+ (type $anyref_=>_none (func (param anyref)))
(type $exnref_=>_exnref (func (param exnref) (result exnref)))
(event $event$0 (attr 0) (param i32))
+ (event $event$1 (attr 0) (param anyref))
(func $exnref_test (; 0 ;) (param $0 exnref) (result exnref)
(local.get $0)
)
@@ -84,6 +86,9 @@
)
)
)
+ (throw $event$1
+ (ref.null)
+ )
)
)
diff --git a/test/exception-handling.wast.fromBinary.noDebugInfo b/test/exception-handling.wast.fromBinary.noDebugInfo
index 87ab1c772..632055441 100644
--- a/test/exception-handling.wast.fromBinary.noDebugInfo
+++ b/test/exception-handling.wast.fromBinary.noDebugInfo
@@ -1,8 +1,10 @@
(module
(type $none_=>_none (func))
(type $i32_=>_none (func (param i32)))
+ (type $anyref_=>_none (func (param anyref)))
(type $exnref_=>_exnref (func (param exnref) (result exnref)))
(event $event$0 (attr 0) (param i32))
+ (event $event$1 (attr 0) (param anyref))
(func $0 (; 0 ;) (param $0 exnref) (result exnref)
(local.get $0)
)
@@ -84,6 +86,9 @@
)
)
)
+ (throw $event$1
+ (ref.null)
+ )
)
)