diff options
-rw-r--r-- | src/wasm/wasm-validator.cpp | 99 | ||||
-rw-r--r-- | test/exception-handling.wast | 5 | ||||
-rw-r--r-- | test/exception-handling.wast.from-wast | 5 | ||||
-rw-r--r-- | test/exception-handling.wast.fromBinary | 5 | ||||
-rw-r--r-- | test/exception-handling.wast.fromBinary.noDebugInfo | 5 |
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) + ) ) ) |