==> tests/lower.c <==1/* The shape of lowered code: branch targets and heights, the loop's interrupt check, dead code gone. */
2#include "mesh/check.h"
3#include "wasm/builder.h"
4#include "wasm/decode.h"
5#include "wasm/lower.h"
6#include "wasm/validate.h"
7
8#include <stdlib.h>
9
10static char err[256];
11
12int main(void) {
13 wasm_builder w = {0};
14 uint32_t t = wasm_builder_type(&w, "i>i");
15 /* block (result i32) i32.const 7 local.get 0 br_if 0 drop i32.const 9 end drop;
16 * block loop local.get 0 eqz br_if 0 br 1 (dead: i32.const 1 drop) end end i32.const 3 */
17 wasm_buf *b = wasm_builder_func_add(&w, t, "l", NULL);
18 static const uint8_t body[] = {0x02, 0x7f, 0x41, 7, 0x20, 0, 0x0d, 0, 0x1a, 0x41, 9, 0x0b, 0x1a, 0x02, 0x40,
19 0x03, 0x40, 0x20, 0, 0x45, 0x0d, 0, 0x0c, 1, 0x41, 1, 0x1a, 0x0b, 0x0b, 0x41, 3};
20 wb_bytes(b, body, sizeof body);
21 wasm_buf out;
22 wasm_builder_finish(&w, &out);
23 wasm_module m;
24 CHECK(wasm_decode(out.data, out.len, &m, err, sizeof err));
25 CHECK(wasm_validate(&m, WASM_F_ALL, NULL, err, sizeof err));
26 wasm_fn_code c;
27 CHECK(wasm_lower(&m, 0, &c, err, sizeof err));
28 CHECK_U(c.nlocals, 2);
29 /* i32.const 7, local.get 0, br_if (to the block's end: height 2 = 2 locals + 0, 1 value), drop,
30 * i32.const 9, drop, INTERRUPT, local.get, eqz, br_if (to the loop: its INTERRUPT), br (out:
31 * dead code after it is gone), i32.const 3, return. */
32 uint16_t want[] = {0x41, 0x20, WASM_INS_BR_IF, 0x1a, 0x41, 0x1a, WASM_INS_INTERRUPT, 0x20, 0x45, WASM_INS_BR_IF,
33 WASM_INS_BR, 0x41, WASM_INS_RETURN};
34 CHECK_U(c.ncode, sizeof want / sizeof want[0]);
35 for (uint32_t i = 0; i < c.ncode && i < sizeof want / sizeof want[0]; i++) CHECK_U(c.code[i].op, want[i]);
36 CHECK_U(c.code[2].a, 5); /* past the block's last instruction (i32.const 9 is 4) */
37 CHECK_U(c.code[2].b, (2ull << 32) | 1);
38 CHECK_U(c.code[9].a, 6); /* the loop's header */
39 CHECK_U(c.code[9].b, (2ull << 32) | 0);
40 CHECK_U(c.code[10].a, 11); /* out of the loop */
41 CHECK_U(c.code[12].a, 1);
42 CHECK(c.frame_slots >= 2 + 2);
43 wasm_fn_code_free(&c);
44 uint32_t *canon = wasm_canonical_types(&m);
45 CHECK_U(canon[0], 0);
46 free(canon);
47 wasm_module_free(&m);
48 wasm_buf_free(&out);
49 wasm_builder_free(&w);
50 return mesh_check_done();
51}