summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/ReFinalize.cpp3
-rw-r--r--src/wasm-interpreter.h41
-rw-r--r--test/passes/precompute_all-features.txt10
-rw-r--r--test/passes/precompute_all-features.wast15
4 files changed, 45 insertions, 24 deletions
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index a81182832..1de2e97a6 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -130,8 +130,9 @@ void ReFinalize::visitBrOnExn(BrOnExn* curr) {
curr->finalize();
if (curr->exnref->type == Type::unreachable) {
replaceUntaken(curr->exnref, nullptr);
+ } else {
+ updateBreakValueType(curr->name, curr->sent);
}
- updateBreakValueType(curr->name, curr->sent);
}
void ReFinalize::visitNop(Nop* curr) { curr->finalize(); }
void ReFinalize::visitUnreachable(Unreachable* curr) { curr->finalize(); }
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 257a0670f..b0118231e 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1270,7 +1270,24 @@ public:
throwException(flow.getSingleValue());
WASM_UNREACHABLE("rethrow");
}
- Flow visitBrOnExn(BrOnExn* curr) { WASM_UNREACHABLE("unimp"); }
+ Flow visitBrOnExn(BrOnExn* curr) {
+ NOTE_ENTER("BrOnExn");
+ Flow flow = this->visit(curr->exnref);
+ if (flow.breaking()) {
+ return flow;
+ }
+ if (flow.getType() == Type::nullref) {
+ trap("br_on_exn: argument is null");
+ }
+ const ExceptionPackage& ex = flow.getSingleValue().getExceptionPackage();
+ if (curr->event != ex.event) { // Not taken
+ return flow;
+ }
+ // Taken
+ flow.values = ex.values;
+ flow.breakTo = curr->name;
+ return flow;
+ }
virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); }
@@ -1514,10 +1531,6 @@ public:
NOTE_ENTER("Try");
return Flow(NONCONSTANT_FLOW);
}
- Flow visitBrOnExn(BrOnExn* curr) {
- NOTE_ENTER("BrOnExn");
- return Flow(NONCONSTANT_FLOW);
- }
void trap(const char* why) override { throw NonconstantException(); }
@@ -2410,24 +2423,6 @@ private:
return this->visit(curr->catchBody);
}
}
- Flow visitBrOnExn(BrOnExn* curr) {
- NOTE_ENTER("BrOnExn");
- Flow flow = this->visit(curr->exnref);
- if (flow.breaking()) {
- return flow;
- }
- if (flow.getType() == Type::nullref) {
- trap("br_on_exn: argument is null");
- }
- const ExceptionPackage& ex = flow.getSingleValue().getExceptionPackage();
- if (curr->event != ex.event) { // Not taken
- return flow;
- }
- // Taken
- flow.values = ex.values;
- flow.breakTo = curr->name;
- return flow;
- }
Flow visitPush(Push* curr) {
NOTE_ENTER("Push");
Flow value = this->visit(curr->value);
diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt
index 9c7f4eab1..4253d3c42 100644
--- a/test/passes/precompute_all-features.txt
+++ b/test/passes/precompute_all-features.txt
@@ -10,6 +10,7 @@
(data (i32.const 0) "passive")
(global $global i32 (i32.const 1))
(global $global-mut (mut i32) (i32.const 2))
+ (event $event$0 (attr 0) (param))
(func $x (param $x i32)
(call $x
(i32.const 2300)
@@ -314,4 +315,13 @@
)
)
)
+ (func $unreachable-br_on_exn
+ (block $label$1
+ (drop
+ (loop $label$2
+ (br $label$2)
+ )
+ )
+ )
+ )
)
diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast
index bbe984704..343b01ff1 100644
--- a/test/passes/precompute_all-features.wast
+++ b/test/passes/precompute_all-features.wast
@@ -461,4 +461,19 @@
)
)
)
+
+ ;; br_on_exn's argument becomes unreachable, so br_on_exn itself is replaced
+ ;; with its argument in ReFinalize process after precompute.
+ (event $event$0 (attr 0) (param))
+ (func $unreachable-br_on_exn
+ (block $label$1
+ (drop
+ (br_on_exn $label$1 $event$0
+ (loop $label$2 (result nullref)
+ (br $label$2)
+ )
+ )
+ )
+ )
+ )
)