summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2024-04-24 01:59:23 +0900
committerGitHub <noreply@github.com>2024-04-24 01:59:23 +0900
commit94ddae02e591adeb994ae2f798878e814f976bc1 (patch)
tree02799d1f9a60beeb574d36e1848a2b40e301e2c6
parent3b9dc42525553653d7477874e854584e957887b2 (diff)
downloadbinaryen-94ddae02e591adeb994ae2f798878e814f976bc1.tar.gz
binaryen-94ddae02e591adeb994ae2f798878e814f976bc1.tar.bz2
binaryen-94ddae02e591adeb994ae2f798878e814f976bc1.zip
[EH] Fix assumption that all throw_refs are created from rethrows (#6524)
`shouldBeRef` incorrectly assumed that all `throw_ref`s within a `catch` body had been generated from `rethrow`s, which was not true, because `throw_ref`s are also created when translating `try`-`delegate`s: https://github.com/WebAssembly/binaryen/blob/219e668e87b012c0634043ed702534b8be31231f/src/passes/TranslateEH.cpp#L304 This fixes the assumption and changes `cast` to `dynCast`.
-rw-r--r--src/passes/TranslateEH.cpp12
-rw-r--r--test/lit/passes/translate-to-new-eh.wast75
2 files changed, 82 insertions, 5 deletions
diff --git a/src/passes/TranslateEH.cpp b/src/passes/TranslateEH.cpp
index f8e059624..42cea6199 100644
--- a/src/passes/TranslateEH.cpp
+++ b/src/passes/TranslateEH.cpp
@@ -359,11 +359,13 @@ struct TranslateToNewEH : public WalkerPass<PostWalker<TranslateToNewEH>> {
std::optional<Index> local = localAssigner->getExnrefLocal(curr->name);
if (local) {
for (auto* throwRef : FindAll<ThrowRef>(catchBody).list) {
- // All throw_refs generated in this pass has a local.get as its child.
- // See visitRethrow().
- auto* localGet = throwRef->exnref->cast<LocalGet>();
- if (localGet->index == *local) {
- return true;
+ // All rethrows within this catch body have already been converted to
+ // throw_refs, which contains a local.get as its child.(See
+ // visitRethrow() for details).
+ if (auto* localGet = throwRef->exnref->dynCast<LocalGet>()) {
+ if (localGet->index == *local) {
+ return true;
+ }
}
}
}
diff --git a/test/lit/passes/translate-to-new-eh.wast b/test/lit/passes/translate-to-new-eh.wast
index ba3997951..10de158d4 100644
--- a/test/lit/passes/translate-to-new-eh.wast
+++ b/test/lit/passes/translate-to-new-eh.wast
@@ -2211,4 +2211,79 @@
)
)
)
+
+ ;; CHECK: (func $try-catch-rethrow-with-inner-delegate (type $1)
+ ;; CHECK-NEXT: (local $0 exnref)
+ ;; CHECK-NEXT: (block $outer2
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (block $catch3 (result exnref)
+ ;; CHECK-NEXT: (try_table (catch_ref $e-empty $catch3)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (br $outer2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (block $outer1
+ ;; CHECK-NEXT: (try_table
+ ;; CHECK-NEXT: (throw_ref
+ ;; CHECK-NEXT: (block $l10 (result exnref)
+ ;; CHECK-NEXT: (try_table (catch_all_ref $l10)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (br $outer1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (throw_ref
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; STACKIR-OPT: (func $try-catch-rethrow-with-inner-delegate (type $1)
+ ;; STACKIR-OPT-NEXT: (local $0 exnref)
+ ;; STACKIR-OPT-NEXT: block $outer2
+ ;; STACKIR-OPT-NEXT: block $catch3 (result exnref)
+ ;; STACKIR-OPT-NEXT: try_table (catch_ref $e-empty $catch3)
+ ;; STACKIR-OPT-NEXT: call $foo
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: br $outer2
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: block $outer1
+ ;; STACKIR-OPT-NEXT: try_table
+ ;; STACKIR-OPT-NEXT: block $l10 (result exnref)
+ ;; STACKIR-OPT-NEXT: try_table (catch_all_ref $l10)
+ ;; STACKIR-OPT-NEXT: call $foo
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: br $outer1
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: throw_ref
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: unreachable
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: throw_ref
+ ;; STACKIR-OPT-NEXT: end
+ ;; STACKIR-OPT-NEXT: )
+ (func $try-catch-rethrow-with-inner-delegate
+ (try $l0
+ (do
+ (call $foo)
+ )
+ (catch $e-empty
+ (try $l1
+ (do
+ (try
+ (do
+ (call $foo)
+ )
+ (delegate $l1)
+ )
+ )
+ )
+ (rethrow $l0)
+ )
+ )
+ )
)