Skip to content

Commit f629369

Browse files
committed
Handle try in Flatten pass
This adds handling of try in the Flatten pass. This is in a way similar to 'if' handling.
1 parent 8f1474a commit f629369

File tree

3 files changed

+97
-9
lines changed

3 files changed

+97
-9
lines changed

src/passes/Flatten.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,36 @@ struct Flatten
166166
loop->finalize();
167167
replaceCurrent(rep);
168168

169+
} else if (auto* tryy = curr->dynCast<Try>()) {
170+
// remove a try value
171+
Expression* rep = tryy;
172+
auto* originalBody = tryy->body;
173+
auto* originalCatchBody = tryy->catchBody;
174+
auto type = tryy->type;
175+
Expression* prelude = nullptr;
176+
if (type.isConcrete()) {
177+
Index temp = builder.addVar(getFunction(), type);
178+
if (tryy->body->type.isConcrete()) {
179+
tryy->body = builder.makeLocalSet(temp, tryy->body);
180+
}
181+
if (tryy->catchBody->type.isConcrete()) {
182+
tryy->catchBody = builder.makeLocalSet(temp, tryy->catchBody);
183+
}
184+
// the whole try is now a prelude
185+
prelude = tryy;
186+
// and we leave just a get of the value
187+
rep = builder.makeLocalGet(temp, type);
188+
}
189+
tryy->body = getPreludesWithExpression(originalBody, tryy->body);
190+
tryy->catchBody =
191+
getPreludesWithExpression(originalCatchBody, tryy->catchBody);
192+
tryy->finalize();
193+
if (prelude) {
194+
ReFinalizeNode().visit(prelude);
195+
ourPreludes.push_back(prelude);
196+
}
197+
replaceCurrent(rep);
198+
169199
} else {
170200
WASM_UNREACHABLE("unexpected expr type");
171201
}
@@ -218,10 +248,9 @@ struct Flatten
218248
// )
219249
// )
220250
// In this case we need two locals to store (ref.null); one with
221-
// anyref type that's for the target block ($label0) and one more
222-
// with nullref type in case for flowing out. Here we create the
223-
// second 'flowing out' local in case two block's types are
224-
// different.
251+
// anyref type that's for the target block ($any) and one more with
252+
// nullref type in case for flowing out. Here we create the second
253+
// 'flowing out' local in case two block's types are different.
225254
if (type != blockType) {
226255
temp = builder.addVar(getFunction(), type);
227256
ourPreludes.push_back(builder.makeLocalSet(
@@ -273,7 +302,6 @@ struct Flatten
273302
}
274303
}
275304
}
276-
// TODO Handle br_on_exn
277305

278306
// continue for general handling of everything, control flow or otherwise
279307
curr = getCurrent(); // we may have replaced it

test/passes/flatten_all-features.txt

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
(type $i32_i32_=>_none (func (param i32 i32)))
55
(type $i32_=>_i32 (func (param i32) (result i32)))
66
(type $none_=>_f32 (func (result f32)))
7+
(type $i32_=>_none (func (param i32)))
78
(type $i64_i64_=>_i64 (func (param i64 i64) (result i64)))
89
(type $none_=>_anyref (func (result anyref)))
910
(memory $0 10)
1011
(table $0 1 1 funcref)
1112
(elem (i32.const 0) $call-me)
1213
(global $x (mut i32) (i32.const 0))
14+
(event $e0 (attr 0) (param i32))
1315
(func $a1 (; 0 ;)
1416
(local $0 i32)
1517
(local.set $0
@@ -2240,15 +2242,15 @@
22402242
(local $5 nullref)
22412243
(local $6 nullref)
22422244
(local $7 anyref)
2243-
(block $label0
2245+
(block $any
22442246
(block $block
22452247
(local.set $1
22462248
(ref.null)
22472249
)
22482250
(local.set $2
22492251
(ref.null)
22502252
)
2251-
(br_if $label0
2253+
(br_if $any
22522254
(i32.const 0)
22532255
)
22542256
(local.set $3
@@ -2278,4 +2280,38 @@
22782280
(local.get $7)
22792281
)
22802282
)
2283+
(func $try_catch (; 44 ;)
2284+
(local $exn exnref)
2285+
(local $1 exnref)
2286+
(try
2287+
(throw $e0
2288+
(i32.const 0)
2289+
)
2290+
(catch
2291+
(local.set $1
2292+
(exnref.pop)
2293+
)
2294+
(local.set $exn
2295+
(local.get $1)
2296+
)
2297+
)
2298+
)
2299+
)
2300+
(func $try_catch_br (; 45 ;)
2301+
(local $0 exnref)
2302+
(block $label$0
2303+
(try
2304+
(nop)
2305+
(catch
2306+
(local.set $0
2307+
(exnref.pop)
2308+
)
2309+
(drop
2310+
(local.get $0)
2311+
)
2312+
(br $label$0)
2313+
)
2314+
)
2315+
)
2316+
)
22812317
)

test/passes/flatten_all-features.wast

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,15 +1028,39 @@
10281028
;; value type, we need the value to be set into two locals: one with the outer
10291029
;; block's type, and one with its value type.
10301030
(func $subtype (result anyref) (local $0 nullref)
1031-
(block $label0 (result anyref)
1031+
(block $any (result anyref)
10321032
(block (result nullref)
10331033
(local.tee $0
1034-
(br_if $label0
1034+
(br_if $any
10351035
(ref.null)
10361036
(i32.const 0)
10371037
)
10381038
)
10391039
)
10401040
)
10411041
)
1042+
1043+
(event $e0 (attr 0) (param i32))
1044+
(func $try_catch (local $exn exnref)
1045+
(try
1046+
(throw $e0 (i32.const 0))
1047+
(catch
1048+
(local.set $exn (exnref.pop))
1049+
)
1050+
)
1051+
)
1052+
1053+
(func $try_catch_br
1054+
(block $label$0
1055+
(try
1056+
(nop)
1057+
(catch
1058+
(drop
1059+
(exnref.pop)
1060+
)
1061+
(br $label$0)
1062+
)
1063+
)
1064+
)
1065+
)
10421066
)

0 commit comments

Comments
 (0)