Skip to content

Commit 6ec03c5

Browse files
authored
Prevent calls from sinking into 'try' (#2899)
Expressions that may throw cannot be sinked into 'try'. At the start of 'try', we drop all sinkables that may throw.
1 parent 7fdec37 commit 6ec03c5

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

src/passes/SimplifyLocals.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,20 @@ struct SimplifyLocals
302302
Expression** currp) {
303303
Expression* curr = *currp;
304304

305+
// Expressions that may throw cannot be sinked into 'try'. At the start of
306+
// 'try', we drop all sinkables that may throw.
307+
if (curr->is<Try>()) {
308+
std::vector<Index> invalidated;
309+
for (auto& sinkable : self->sinkables) {
310+
if (sinkable.second.effects.throws) {
311+
invalidated.push_back(sinkable.first);
312+
}
313+
}
314+
for (auto index : invalidated) {
315+
self->sinkables.erase(index);
316+
}
317+
}
318+
305319
EffectAnalyzer effects(self->getPassOptions(), self->getModule()->features);
306320
if (effects.checkPre(curr)) {
307321
self->checkInvalidations(effects);

test/passes/simplify-locals_all-features.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,7 @@
18961896
(type $none_=>_none (func))
18971897
(type $i32_exnref_=>_none (func (param i32 exnref)))
18981898
(type $exnref_=>_none (func (param exnref)))
1899+
(type $none_=>_i32 (func (result i32)))
18991900
(type $none_=>_exnref (func (result exnref)))
19001901
(event $event$0 (attr 0) (param))
19011902
(event $event$1 (attr 0) (param exnref))
@@ -1980,4 +1981,41 @@
19801981
)
19811982
)
19821983
)
1984+
(func $bar (result i32)
1985+
(i32.const 3)
1986+
)
1987+
(func $call-cannot-be-sinked-into-try
1988+
(local $0 i32)
1989+
(local.set $0
1990+
(call $bar)
1991+
)
1992+
(try
1993+
(do
1994+
(drop
1995+
(local.get $0)
1996+
)
1997+
)
1998+
(catch
1999+
(drop
2000+
(exnref.pop)
2001+
)
2002+
)
2003+
)
2004+
)
2005+
(func $non-call-can-be-sinked-into-try
2006+
(local $0 i32)
2007+
(nop)
2008+
(try
2009+
(do
2010+
(drop
2011+
(i32.const 3)
2012+
)
2013+
)
2014+
(catch
2015+
(drop
2016+
(exnref.pop)
2017+
)
2018+
)
2019+
)
2020+
)
19832021
)

test/passes/simplify-locals_all-features.wast

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,4 +1749,36 @@
17491749
)
17501750
)
17511751
)
1752+
1753+
(func $bar (result i32) (i32.const 3))
1754+
(func $call-cannot-be-sinked-into-try (local $0 i32)
1755+
(drop
1756+
;; This local.tee should NOT be sinked into 'try' below, because it may
1757+
;; throw
1758+
(local.tee $0 (call $bar))
1759+
)
1760+
(try
1761+
(do
1762+
(drop (local.get $0))
1763+
)
1764+
(catch
1765+
(drop (exnref.pop))
1766+
)
1767+
)
1768+
)
1769+
1770+
(func $non-call-can-be-sinked-into-try (local $0 i32)
1771+
(drop
1772+
;; This local.tee can be sinked into 'try' below, because it cannot throw
1773+
(local.tee $0 (i32.const 3))
1774+
)
1775+
(try
1776+
(do
1777+
(drop (local.get $0))
1778+
)
1779+
(catch
1780+
(drop (exnref.pop))
1781+
)
1782+
)
1783+
)
17521784
)

0 commit comments

Comments
 (0)