==> tests/smoke.c <==1/* A few functions end to end: arithmetic, a loop, a call, memory, a trap. */
2#include "mesh/check.h"
3#include "wasm/builder.h"
4#include "wasm/interp.h"
5
6#include <stdio.h>
7
8static char err[256];
9
10int main(void) {
11 wasm_builder w = {0};
12 uint32_t t_ii_i = wasm_builder_type(&w, "ii>i");
13 uint32_t t_i_i = wasm_builder_type(&w, "i>i");
14 uint32_t add, fact, sum;
15 wasm_buf *b = wasm_builder_func_add(&w, t_ii_i, "", &add);
16 wb_op_u32(b, 0x20, 0);
17 wb_op_u32(b, 0x20, 1);
18 wb_op(b, 0x6a);
19 /* fact(n): n <= 1 ? 1 : n * fact(n - 1) */
20 b = wasm_builder_func_add(&w, t_i_i, "", &fact);
21 wb_op_u32(b, 0x20, 0);
22 wb_i32_const(b, 1);
23 wb_op(b, 0x4c); /* le_s */
24 wb_op(b, 0x04);
25 wb_byte(b, 0x7f);
26 wb_i32_const(b, 1);
27 wb_op(b, 0x05);
28 wb_op_u32(b, 0x20, 0);
29 wb_op_u32(b, 0x20, 0);
30 wb_i32_const(b, 1);
31 wb_op(b, 0x6b);
32 wb_op_u32(b, 0x10, 1);
33 wb_op(b, 0x6c);
34 wb_op(b, 0x0b);
35 /* sum(n): s = 0; i = 0; loop { s += i; i++; br_if i < n } ; store s at 8; load */
36 b = wasm_builder_func_add(&w, t_i_i, "ii", &sum);
37 wb_op(b, 0x03);
38 wb_byte(b, 0x40);
39 wb_op_u32(b, 0x20, 1);
40 wb_op_u32(b, 0x20, 2);
41 wb_op(b, 0x6a);
42 wb_op_u32(b, 0x21, 1);
43 wb_op_u32(b, 0x20, 2);
44 wb_i32_const(b, 1);
45 wb_op(b, 0x6a);
46 wb_op_u32(b, 0x22, 2);
47 wb_op_u32(b, 0x20, 0);
48 wb_op(b, 0x48);
49 wb_op_u32(b, 0x0d, 0);
50 wb_op(b, 0x0b);
51 wb_i32_const(b, 8);
52 wb_op_u32(b, 0x20, 1);
53 wb_memarg(b, 0x36, 2, 0);
54 wb_i32_const(b, 8);
55 wb_memarg(b, 0x28, 2, 0);
56 wasm_builder_memory(&w, 1, 0, false);
57 wasm_builder_add_export(&w, "add", WASM_EXTERN_FUNC, add);
58 wasm_builder_add_export(&w, "fact", WASM_EXTERN_FUNC, fact);
59 wasm_builder_add_export(&w, "sum", WASM_EXTERN_FUNC, sum);
60 wasm_buf out;
61 wasm_builder_finish(&w, &out);
62 wasm_compiled *c = wasm_compile(out.data, out.len, WASM_F_INTERP, err, sizeof err);
63 if (!c) fprintf(stderr, "compile: %s\n", err);
64 CHECK(c != NULL);
65 wasm_instance *I = c ? wasm_instantiate(c, NULL, 0, NULL, NULL, err, sizeof err) : NULL;
66 if (c && !I) fprintf(stderr, "instantiate: %s\n", err);
67 CHECK(I != NULL);
68 if (I) {
69 uint64_t io[2] = {40, 2};
70 CHECK_I(wasm_call(I, (uint32_t)wasm_instance_func(I, "add", "ii>i", err, sizeof err), io), WASM_NUM_OK);
71 CHECK_U(io[0], 42);
72 io[0] = 10;
73 CHECK_I(wasm_call(I, (uint32_t)wasm_instance_func(I, "fact", "i>i", err, sizeof err), io), WASM_NUM_OK);
74 CHECK_U(io[0], 3628800);
75 io[0] = 100;
76 CHECK_I(wasm_call(I, (uint32_t)wasm_instance_func(I, "sum", "i>i", err, sizeof err), io), WASM_NUM_OK);
77 CHECK_U(io[0], 4950);
78 io[0] = 100000;
79 CHECK_I(wasm_call(I, (uint32_t)wasm_instance_func(I, "fact", "i>i", err, sizeof err), io), WASM_TRAP_STACK_OVERFLOW);
80 CHECK_I(wasm_instance_func(I, "nope", "i>i", err, sizeof err), -1);
81 CHECK_S(err, "failed to find function export `nope`");
82 wasm_instance_free(I);
83 }
84 wasm_compiled_free(c);
85 wasm_buf_free(&out);
86 wasm_builder_free(&w);
87 return mesh_check_done();
88}