diff options
-rw-r--r-- | src/passes/TranslateEH.cpp | 12 | ||||
-rw-r--r-- | test/lit/passes/translate-to-new-eh.wast | 75 |
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) + ) + ) + ) ) |