Skip to content

Commit 94ddae0

Browse files
authored
[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`.
1 parent 3b9dc42 commit 94ddae0

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

src/passes/TranslateEH.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,13 @@ struct TranslateToNewEH : public WalkerPass<PostWalker<TranslateToNewEH>> {
359359
std::optional<Index> local = localAssigner->getExnrefLocal(curr->name);
360360
if (local) {
361361
for (auto* throwRef : FindAll<ThrowRef>(catchBody).list) {
362-
// All throw_refs generated in this pass has a local.get as its child.
363-
// See visitRethrow().
364-
auto* localGet = throwRef->exnref->cast<LocalGet>();
365-
if (localGet->index == *local) {
366-
return true;
362+
// All rethrows within this catch body have already been converted to
363+
// throw_refs, which contains a local.get as its child.(See
364+
// visitRethrow() for details).
365+
if (auto* localGet = throwRef->exnref->dynCast<LocalGet>()) {
366+
if (localGet->index == *local) {
367+
return true;
368+
}
367369
}
368370
}
369371
}

test/lit/passes/translate-to-new-eh.wast

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,4 +2211,79 @@
22112211
)
22122212
)
22132213
)
2214+
2215+
;; CHECK: (func $try-catch-rethrow-with-inner-delegate (type $1)
2216+
;; CHECK-NEXT: (local $0 exnref)
2217+
;; CHECK-NEXT: (block $outer2
2218+
;; CHECK-NEXT: (local.set $0
2219+
;; CHECK-NEXT: (block $catch3 (result exnref)
2220+
;; CHECK-NEXT: (try_table (catch_ref $e-empty $catch3)
2221+
;; CHECK-NEXT: (call $foo)
2222+
;; CHECK-NEXT: )
2223+
;; CHECK-NEXT: (br $outer2)
2224+
;; CHECK-NEXT: )
2225+
;; CHECK-NEXT: )
2226+
;; CHECK-NEXT: (block
2227+
;; CHECK-NEXT: (block $outer1
2228+
;; CHECK-NEXT: (try_table
2229+
;; CHECK-NEXT: (throw_ref
2230+
;; CHECK-NEXT: (block $l10 (result exnref)
2231+
;; CHECK-NEXT: (try_table (catch_all_ref $l10)
2232+
;; CHECK-NEXT: (call $foo)
2233+
;; CHECK-NEXT: )
2234+
;; CHECK-NEXT: (br $outer1)
2235+
;; CHECK-NEXT: )
2236+
;; CHECK-NEXT: )
2237+
;; CHECK-NEXT: )
2238+
;; CHECK-NEXT: )
2239+
;; CHECK-NEXT: (throw_ref
2240+
;; CHECK-NEXT: (local.get $0)
2241+
;; CHECK-NEXT: )
2242+
;; CHECK-NEXT: )
2243+
;; CHECK-NEXT: )
2244+
;; CHECK-NEXT: )
2245+
;; STACKIR-OPT: (func $try-catch-rethrow-with-inner-delegate (type $1)
2246+
;; STACKIR-OPT-NEXT: (local $0 exnref)
2247+
;; STACKIR-OPT-NEXT: block $outer2
2248+
;; STACKIR-OPT-NEXT: block $catch3 (result exnref)
2249+
;; STACKIR-OPT-NEXT: try_table (catch_ref $e-empty $catch3)
2250+
;; STACKIR-OPT-NEXT: call $foo
2251+
;; STACKIR-OPT-NEXT: end
2252+
;; STACKIR-OPT-NEXT: br $outer2
2253+
;; STACKIR-OPT-NEXT: end
2254+
;; STACKIR-OPT-NEXT: block $outer1
2255+
;; STACKIR-OPT-NEXT: try_table
2256+
;; STACKIR-OPT-NEXT: block $l10 (result exnref)
2257+
;; STACKIR-OPT-NEXT: try_table (catch_all_ref $l10)
2258+
;; STACKIR-OPT-NEXT: call $foo
2259+
;; STACKIR-OPT-NEXT: end
2260+
;; STACKIR-OPT-NEXT: br $outer1
2261+
;; STACKIR-OPT-NEXT: end
2262+
;; STACKIR-OPT-NEXT: throw_ref
2263+
;; STACKIR-OPT-NEXT: end
2264+
;; STACKIR-OPT-NEXT: unreachable
2265+
;; STACKIR-OPT-NEXT: end
2266+
;; STACKIR-OPT-NEXT: throw_ref
2267+
;; STACKIR-OPT-NEXT: end
2268+
;; STACKIR-OPT-NEXT: )
2269+
(func $try-catch-rethrow-with-inner-delegate
2270+
(try $l0
2271+
(do
2272+
(call $foo)
2273+
)
2274+
(catch $e-empty
2275+
(try $l1
2276+
(do
2277+
(try
2278+
(do
2279+
(call $foo)
2280+
)
2281+
(delegate $l1)
2282+
)
2283+
)
2284+
)
2285+
(rethrow $l0)
2286+
)
2287+
)
2288+
)
22142289
)

0 commit comments

Comments
 (0)