Skip to content

Commit b106c77

Browse files
authored
fix(compiler): optimize two if-else wasm patterns (VirusTotal#565)
Following VirusTotal#563, two more patterns that can be optimized. Still very simple low hanging fruit stuff, I'm not sure if I manage to do something more impactful -- I begun looking into reducing catch undefs, but it got a bit out of hand and I don't know if it will lead to something good enough.
1 parent cbb3c3b commit b106c77

1 file changed

Lines changed: 16 additions & 30 deletions

File tree

lib/src/compiler/emit.rs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,26 +2248,20 @@ fn emit_for<I, B, C, A>(
22482248
None,
22492249
// count >= max_count
22502250
|then_| {
2251-
// Is max_count == 0?
2251+
// If max_count == 0, this should be
2252+
// treated as a `none` quantifier. At
2253+
// this point count >= 1, so break the
2254+
// loop with result false (0). If
2255+
// max_count != 0 and count >= max_count,
2256+
// break with result true (1).
2257+
//
2258+
// `i64.ne` with 0 directly produces the
2259+
// right i32: 0 when max_count == 0,
2260+
// 1 when max_count != 0.
22522261
load_var(ctx, then_, max_count);
2253-
then_.unop(UnaryOp::I64Eqz);
2254-
then_.if_else(
2255-
None,
2256-
// max_count == 0, this should treated be
2257-
// as a `none` quantifier. At this point
2258-
// count >= 1, so break the loop with
2259-
// result false.
2260-
|then_| {
2261-
then_.i32_const(0);
2262-
then_.br(loop_end);
2263-
},
2264-
// max_count != 0 and count >= max_count
2265-
// break the loop with result true.
2266-
|else_| {
2267-
else_.i32_const(1);
2268-
else_.br(loop_end);
2269-
},
2270-
);
2262+
then_.i64_const(0);
2263+
then_.binop(BinaryOp::I64Ne);
2264+
then_.br(loop_end);
22712265
},
22722266
|_| {},
22732267
);
@@ -2283,19 +2277,11 @@ fn emit_for<I, B, C, A>(
22832277
// return true. If `max_count` is non-zero it means that
22842278
// `counter` didn't reach `max_count` and the loop must
22852279
// return false.
2280+
//
2281+
// `i64.eqz` produces exactly the right i32 result:
2282+
// 1 (true) when max_count == 0, 0 (false) otherwise.
22862283
load_var(ctx, block, max_count);
22872284
block.unop(UnaryOp::I64Eqz);
2288-
block.if_else(
2289-
I32,
2290-
// max_count == 0
2291-
|then_| {
2292-
then_.i32_const(1);
2293-
},
2294-
// max_count != 0
2295-
|else_| {
2296-
else_.i32_const(0);
2297-
},
2298-
);
22992285
}
23002286
}
23012287
});

0 commit comments

Comments
 (0)