diff options
-rw-r--r-- | src/ir/ReFinalize.cpp | 3 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 41 | ||||
-rw-r--r-- | test/passes/precompute_all-features.txt | 10 | ||||
-rw-r--r-- | test/passes/precompute_all-features.wast | 15 |
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) + ) + ) + ) + ) + ) ) |