skip to content
==> 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}