summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parsing.h45
-rw-r--r--src/wasm/wasm-validator.cpp3
-rw-r--r--test/passes/inlining_all-features.txt26
-rw-r--r--test/passes/inlining_all-features.wast21
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)
+ )
+ )
+ )
+)