diff options
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 736d669fb..6bcdb0e7c 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -236,7 +236,8 @@ struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> { }; std::unordered_map<Name, BreakInfo> breakInfos; - std::unordered_set<Name> exceptionTargetNames; + std::unordered_set<Name> delegateTargetNames; + std::unordered_set<Name> rethrowTargetNames; std::set<Type> returnTypes; // types used in returns @@ -280,7 +281,7 @@ public: static void visitPreTry(FunctionValidator* self, Expression** currp) { auto* curr = (*currp)->cast<Try>(); if (curr->name.is()) { - self->exceptionTargetNames.insert(curr->name); + self->delegateTargetNames.insert(curr->name); } } @@ -300,7 +301,8 @@ public: static void visitPreCatch(FunctionValidator* self, Expression** currp) { auto* curr = (*currp)->cast<Try>(); if (curr->name.is()) { - self->exceptionTargetNames.erase(curr->name); + self->delegateTargetNames.erase(curr->name); + self->rethrowTargetNames.insert(curr->name); } } @@ -376,7 +378,8 @@ public: void visitRefIs(RefIs* curr); void visitRefFunc(RefFunc* curr); void visitRefEq(RefEq* curr); - void noteException(Name name, Expression* curr); + void noteDelegate(Name name, Expression* curr); + void noteRethrow(Name name, Expression* curr); void visitTry(Try* curr); void visitThrow(Throw* curr); void visitRethrow(Rethrow* curr); @@ -2073,14 +2076,20 @@ void FunctionValidator::visitRefEq(RefEq* curr) { "ref.eq's right argument should be a subtype of eqref"); } -void FunctionValidator::noteException(Name name, Expression* curr) { +void FunctionValidator::noteDelegate(Name name, Expression* curr) { if (name != DELEGATE_CALLER_TARGET) { - shouldBeTrue(exceptionTargetNames.find(name) != exceptionTargetNames.end(), + shouldBeTrue(delegateTargetNames.count(name) != 0, curr, "all delegate targets must be valid"); } } +void FunctionValidator::noteRethrow(Name name, Expression* curr) { + shouldBeTrue(rethrowTargetNames.count(name) != 0, + curr, + "all rethrow targets must be valid"); +} + void FunctionValidator::visitTry(Try* curr) { shouldBeTrue(getModule()->features.hasExceptionHandling(), curr, @@ -2122,8 +2131,10 @@ void FunctionValidator::visitTry(Try* curr) { "try should have either catches or a delegate"); if (curr->isDelegate()) { - noteException(curr->delegateTarget, curr); + noteDelegate(curr->delegateTarget, curr); } + + rethrowTargetNames.erase(curr->name); } void FunctionValidator::visitThrow(Throw* curr) { @@ -2167,8 +2178,7 @@ void FunctionValidator::visitRethrow(Rethrow* curr) { Type(Type::unreachable), curr, "rethrow's type must be unreachable"); - // TODO Validate the depth field. The current LLVM toolchain only generates - // depth 0 for C++ support. + noteRethrow(curr->target, curr); } void FunctionValidator::visitTupleMake(TupleMake* curr) { @@ -2531,11 +2541,9 @@ void FunctionValidator::visitFunction(Function* curr) { "function result must match, if function has returns"); } - shouldBeTrue( - breakInfos.empty(), curr->body, "all named break targets must exist"); - shouldBeTrue(exceptionTargetNames.empty(), - curr->body, - "all named delegate targets must exist"); + assert(breakInfos.empty()); + assert(delegateTargetNames.empty()); + assert(rethrowTargetNames.empty()); returnTypes.clear(); labelNames.clear(); // validate optional local names |