diff options
author | Ben Smith <binji@chromium.org> | 2020-04-14 08:57:07 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-14 08:57:07 -0700 |
commit | 952c3b8006911a8659c1b922c3bb4adffc671d89 (patch) | |
tree | 00e85fa8d984fce95731ea690cc56a6646b6bc00 /wasm2c/examples/rot13/main.c | |
parent | 10a9b0563efea0ab00abf6846c0ebcb53f492404 (diff) | |
download | wabt-952c3b8006911a8659c1b922c3bb4adffc671d89.tar.gz wabt-952c3b8006911a8659c1b922c3bb4adffc671d89.tar.bz2 wabt-952c3b8006911a8659c1b922c3bb4adffc671d89.zip |
[wasm2c] Add rot13 example (#1384)
This example demonstrates how to use imported functions. The `rot13`
program takes each command line argument, and rot13-encodes it.
The exported `rot13` function has no arguments, and instead calls back
into the program (via `fill_buf`) with a buffer to fill in. When the
function finishes it calls `buf_done`.
(rot13.wat is the same as in src/test-interp.cc.)
Diffstat (limited to 'wasm2c/examples/rot13/main.c')
-rw-r--r-- | wasm2c/examples/rot13/main.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/wasm2c/examples/rot13/main.c b/wasm2c/examples/rot13/main.c new file mode 100644 index 00000000..f99ee014 --- /dev/null +++ b/wasm2c/examples/rot13/main.c @@ -0,0 +1,93 @@ +/* Entry point for the rot13 example. + * + * This example shows how you can fulfill wasm module imports in your C + * program, and access linear memory. + * + * The program reads arguments from the command line, and [rot13] encodes them, + * e.g.: + * + * ``` + * $ rot13 foo bar + * foo -> sbb + * bar -> one + * ``` + * + * [rot13]: https://en.wikipedia.org/wiki/ROT13 + */ +#include <stdio.h> +#include <stdlib.h> + +/* Uncomment this to define rot13_init rot13_Z_rot13Z_vv instead. */ +/* #define WASM_RT_MODULE_PREFIX rot13_ */ + +#include "rot13.h" + +/* Define the imports as declared in rot13.h. */ +wasm_rt_memory_t (*Z_hostZ_mem); +u32 (*Z_hostZ_fill_bufZ_iii)(u32, u32); +void (*Z_hostZ_buf_doneZ_vii)(u32, u32); + +/* Define the implementations of the imports. */ +static wasm_rt_memory_t s_memory; +static u32 fill_buf(u32 ptr, u32 size); +static void buf_done(u32 ptr, u32 size); + +/* The string that is currently being processed. This needs to be static + * because the buffer is filled in the callback. */ +static const char* s_input; + +int main(int argc, char** argv) { + /* Initialize the rot13 module. Since we didn't define WASM_RT_MODULE_PREFIX, + the initialization function is called `init`. */ + init(); + + /* Allocate 1 page of wasm memory (64KiB). */ + wasm_rt_allocate_memory(&s_memory, 1, 1); + + /* Provide the imports expected by the module: "host.mem", "host.fill_buf" + * and "host.buf_done". Their mangled names are `Z_hostZ_mem`, + * `Z_hostZ_fill_bufZ_iii` and `Z_hostZ_buf_doneZ_vii`. */ + Z_hostZ_mem = &s_memory; + Z_hostZ_fill_bufZ_iii = &fill_buf; + Z_hostZ_buf_doneZ_vii = &buf_done; + + /* Call `rot13` on each argument, using the mangled name. */ + while (argc > 1) { + /* Move to next arg. Do this first, so the program name is skipped. */ + argc--; argv++; + + s_input = argv[0]; + Z_rot13Z_vv(); + } + return 0; +} + +/* Fill the wasm buffer with the input to be rot13'd. + * + * params: + * ptr: The wasm memory address of the buffer to fill data. + * size: The size of the buffer in wasm memory. + * result: + * The number of bytes filled into the buffer. (Must be <= size). + */ +u32 fill_buf(u32 ptr, u32 size) { + for (size_t i = 0; i < size; ++i) { + if (s_input[i] == 0) { + return i; + } + s_memory.data[ptr + i] = s_input[i]; + } + return size; +} + +/* Called when the wasm buffer has been rot13'd. + * + * params: + * ptr: The wasm memory address of the buffer. + * size: The size of the buffer in wasm memory. + */ +void buf_done(u32 ptr, u32 size) { + /* The output buffer is not necessarily null-terminated, so use the %*.s + * printf format to limit the number of characters printed. */ + printf("%s -> %.*s\n", s_input, (int)size, &s_memory.data[ptr]); +} |