diff options
-rw-r--r-- | src/parsing.h | 45 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 3 | ||||
-rw-r--r-- | test/passes/inlining_all-features.txt | 26 | ||||
-rw-r--r-- | test/passes/inlining_all-features.wast | 21 |
4 files changed, 68 insertions, 27 deletions
diff --git a/src/parsing.h b/src/parsing.h index 68647901a..9c3e0cd19 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -22,6 +22,7 @@ #include <sstream> #include <string> +#include "ir/branch-utils.h" #include "mixed_arena.h" #include "shared-constants.h" #include "support/colors.h" @@ -344,42 +345,32 @@ struct UniqueNameMapper { // Given an expression, ensures all names are unique static void uniquify(Expression* curr) { - struct Walker : public ControlFlowWalker<Walker, Visitor<Walker>> { + struct Walker + : public ControlFlowWalker<Walker, UnifiedExpressionVisitor<Walker>> { UniqueNameMapper mapper; static void doPreVisitControlFlow(Walker* self, Expression** currp) { - auto* curr = *currp; - if (auto* block = curr->dynCast<Block>()) { - if (block->name.is()) { - block->name = self->mapper.pushLabelName(block->name); + BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) { + if (name.is()) { + name = self->mapper.pushLabelName(name); } - } else if (auto* loop = curr->dynCast<Loop>()) { - if (loop->name.is()) { - loop->name = self->mapper.pushLabelName(loop->name); - } - } + }); } + static void doPostVisitControlFlow(Walker* self, Expression** currp) { - auto* curr = *currp; - if (auto* block = curr->dynCast<Block>()) { - if (block->name.is()) { - self->mapper.popLabelName(block->name); - } - } else if (auto* loop = curr->dynCast<Loop>()) { - if (loop->name.is()) { - self->mapper.popLabelName(loop->name); + BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) { + if (name.is()) { + self->mapper.popLabelName(name); } - } + }); } - void visitBreak(Break* curr) { - curr->name = mapper.sourceToUnique(curr->name); - } - void visitSwitch(Switch* curr) { - for (auto& target : curr->targets) { - target = mapper.sourceToUnique(target); - } - curr->default_ = mapper.sourceToUnique(curr->default_); + void visitExpression(Expression* curr) { + BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) { + if (name.is()) { + name = mapper.sourceToUnique(name); + } + }); } }; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 97146a7c4..e95950bb5 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2098,6 +2098,9 @@ void FunctionValidator::visitTry(Try* curr) { shouldBeTrue(getModule()->features.hasExceptionHandling(), curr, "try requires exception-handling to be enabled"); + if (curr->name.is()) { + noteLabelName(curr->name); + } if (curr->type != Type::unreachable) { shouldBeSubTypeOrFirstIsUnreachable( curr->body->type, diff --git a/test/passes/inlining_all-features.txt b/test/passes/inlining_all-features.txt index e23736fac..e0ecf57b5 100644 --- a/test/passes/inlining_all-features.txt +++ b/test/passes/inlining_all-features.txt @@ -53,3 +53,29 @@ ) ) ) +(module + (type $i32_=>_none (func (param i32))) + (type $none_=>_i32 (func (result i32))) + (import "a" "b" (func $foo (result i32))) + (event $event$0 (attr 0) (param i32)) + (export "exported" (func $1)) + (func $1 (param $x i32) + (loop $label + (block + (block $__inlined_func$0 + (try $label0 + (do + (nop) + ) + (catch $event$0 + (nop) + ) + ) + ) + ) + (br_if $label + (call $foo) + ) + ) + ) +) diff --git a/test/passes/inlining_all-features.wast b/test/passes/inlining_all-features.wast index 863daad9b..3890d63a1 100644 --- a/test/passes/inlining_all-features.wast +++ b/test/passes/inlining_all-features.wast @@ -43,3 +43,24 @@ (call $0) ) ) +;; properly ensure unique try labels after an inlining +(module + (import "a" "b" (func $foo (result i32))) + (event $event$0 (attr 0) (param i32)) + (func $0 + (try $label + (do) + (catch $event$0 + (nop) + ) + ) + ) + (func "exported" (param $x i32) + (loop $label ;; the same label as the try that will be inlined into here + (call $0) + (br_if $label + (call $foo) + ) + ) + ) +) |