diff options
-rw-r--r-- | src/prebuilt/wasm2c.include.c | 1 | ||||
-rw-r--r-- | src/prebuilt/wasm2c.include.h | 1 | ||||
-rw-r--r-- | src/wasm2c.c.tmpl | 1 | ||||
-rw-r--r-- | src/wasm2c.h.tmpl | 1 | ||||
-rwxr-xr-x | src/wasm2c_tmpl.py | 2 | ||||
-rw-r--r-- | wasm2c/.gitignore | 10 | ||||
-rw-r--r-- | wasm2c/examples/fac/Makefile | 9 | ||||
-rw-r--r-- | wasm2c/examples/fac/fac.c | 3 | ||||
-rw-r--r-- | wasm2c/examples/fac/fac.h | 54 | ||||
-rw-r--r-- | wasm2c/examples/rot13/Makefile | 9 | ||||
-rw-r--r-- | wasm2c/examples/rot13/main.c | 93 | ||||
-rw-r--r-- | wasm2c/examples/rot13/rot13.wat | 56 |
12 files changed, 185 insertions, 55 deletions
diff --git a/src/prebuilt/wasm2c.include.c b/src/prebuilt/wasm2c.include.c index b14cc435..d7b1df23 100644 --- a/src/prebuilt/wasm2c.include.c +++ b/src/prebuilt/wasm2c.include.c @@ -1,5 +1,6 @@ /* Generated from 'wasm2c.c.tmpl' by wasm2c_tmpl.py, do not edit! */ const char SECTION_NAME(includes)[] = +"/* Automically generated by wasm2c */\n" "#include <math.h>\n" "#include <string.h>\n" ; diff --git a/src/prebuilt/wasm2c.include.h b/src/prebuilt/wasm2c.include.h index 23319cde..4ba24751 100644 --- a/src/prebuilt/wasm2c.include.h +++ b/src/prebuilt/wasm2c.include.h @@ -1,5 +1,6 @@ /* Generated from 'wasm2c.h.tmpl' by wasm2c_tmpl.py, do not edit! */ const char SECTION_NAME(top)[] = +"/* Automically generated by wasm2c */\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" diff --git a/src/wasm2c.c.tmpl b/src/wasm2c.c.tmpl index 2d188c77..4465cf9a 100644 --- a/src/wasm2c.c.tmpl +++ b/src/wasm2c.c.tmpl @@ -1,4 +1,5 @@ %%includes +/* Automically generated by wasm2c */ #include <math.h> #include <string.h> %%declarations diff --git a/src/wasm2c.h.tmpl b/src/wasm2c.h.tmpl index ac51cde9..8478d81b 100644 --- a/src/wasm2c.h.tmpl +++ b/src/wasm2c.h.tmpl @@ -1,4 +1,5 @@ %%top +/* Automically generated by wasm2c */ #ifdef __cplusplus extern "C" { #endif diff --git a/src/wasm2c_tmpl.py b/src/wasm2c_tmpl.py index af3b953e..0da117a8 100755 --- a/src/wasm2c_tmpl.py +++ b/src/wasm2c_tmpl.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # # Copyright 2018 WebAssembly Community Group participants # diff --git a/wasm2c/.gitignore b/wasm2c/.gitignore new file mode 100644 index 00000000..47ea610d --- /dev/null +++ b/wasm2c/.gitignore @@ -0,0 +1,10 @@ +wasm-rt-impl.o +examples/fac/main.o +examples/fac/fac +examples/fac/fac.o +examples/rot13/main.o +examples/rot13/rot13 +examples/rot13/rot13.c +examples/rot13/rot13.h +examples/rot13/rot13.o +examples/rot13/rot13.wasm diff --git a/wasm2c/examples/fac/Makefile b/wasm2c/examples/fac/Makefile new file mode 100644 index 00000000..f5b2a338 --- /dev/null +++ b/wasm2c/examples/fac/Makefile @@ -0,0 +1,9 @@ +# Use implicit rules for compiling C files. +CFLAGS=-I../.. +fac: main.o fac.o ../../wasm-rt-impl.o + +fac.wasm: fac.wat + ../../../bin/wat2wasm $< -o $@ + +fac.c: fac.wasm + ../../../bin/wasm2c $< -o $@ diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index a954c363..acd8ed91 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -1,6 +1,5 @@ -#include <assert.h> +/* Automically generated by wasm2c */ #include <math.h> -#include <stdlib.h> #include <string.h> #include "fac.h" diff --git a/wasm2c/examples/fac/fac.h b/wasm2c/examples/fac/fac.h index 0a58ef42..5e78f33b 100644 --- a/wasm2c/examples/fac/fac.h +++ b/wasm2c/examples/fac/fac.h @@ -1,17 +1,13 @@ #ifndef FAC_H_GENERATED_ #define FAC_H_GENERATED_ +/* Automically generated by wasm2c */ #ifdef __cplusplus extern "C" { #endif -#ifndef WASM_RT_INCLUDED_ -#define WASM_RT_INCLUDED_ - #include <stdint.h> -#ifndef WASM_RT_MAX_CALL_STACK_DEPTH -#define WASM_RT_MAX_CALL_STACK_DEPTH 500 -#endif +#include "wasm-rt.h" #ifndef WASM_RT_MODULE_PREFIX #define WASM_RT_MODULE_PREFIX @@ -33,52 +29,6 @@ typedef int64_t s64; typedef float f32; typedef double f64; -typedef enum { - WASM_RT_TRAP_NONE, - WASM_RT_TRAP_OOB, - WASM_RT_TRAP_INT_OVERFLOW, - WASM_RT_TRAP_DIV_BY_ZERO, - WASM_RT_TRAP_INVALID_CONVERSION, - WASM_RT_TRAP_UNREACHABLE, - WASM_RT_TRAP_CALL_INDIRECT, - WASM_RT_TRAP_EXHAUSTION, -} wasm_rt_trap_t; - -typedef enum { - WASM_RT_I32, - WASM_RT_I64, - WASM_RT_F32, - WASM_RT_F64, -} wasm_rt_type_t; - -typedef void (*wasm_rt_anyfunc_t)(void); - -typedef struct { - uint32_t func_type; - wasm_rt_anyfunc_t func; -} wasm_rt_elem_t; - -typedef struct { - uint8_t* data; - uint32_t pages, max_pages; - uint32_t size; -} wasm_rt_memory_t; - -typedef struct { - wasm_rt_elem_t* data; - uint32_t max_size; - uint32_t size; -} wasm_rt_table_t; - -extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn)); -extern uint32_t wasm_rt_register_func_type(uint32_t params, uint32_t results, ...); -extern void wasm_rt_allocate_memory(wasm_rt_memory_t*, uint32_t initial_pages, uint32_t max_pages); -extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages); -extern void wasm_rt_allocate_table(wasm_rt_table_t*, uint32_t elements, uint32_t max_elements); -extern uint32_t wasm_rt_call_stack_depth; - -#endif /* WASM_RT_INCLUDED_ */ - extern void WASM_RT_ADD_PREFIX(init)(void); /* export: 'fac' */ diff --git a/wasm2c/examples/rot13/Makefile b/wasm2c/examples/rot13/Makefile new file mode 100644 index 00000000..35483310 --- /dev/null +++ b/wasm2c/examples/rot13/Makefile @@ -0,0 +1,9 @@ +# Use implicit rules for compiling C files. +CFLAGS=-I../.. +rot13: main.o rot13.o ../../wasm-rt-impl.o + +rot13.wasm: rot13.wat + ../../../bin/wat2wasm $< -o $@ + +rot13.c: rot13.wasm + ../../../bin/wasm2c $< -o $@ 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]); +} diff --git a/wasm2c/examples/rot13/rot13.wat b/wasm2c/examples/rot13/rot13.wat new file mode 100644 index 00000000..0a33d80e --- /dev/null +++ b/wasm2c/examples/rot13/rot13.wat @@ -0,0 +1,56 @@ +(import "host" "mem" (memory $mem 1)) +(import "host" "fill_buf" (func $fill_buf (param i32 i32) (result i32))) +(import "host" "buf_done" (func $buf_done (param i32 i32))) + +(func $rot13c (param $c i32) (result i32) + (local $uc i32) + + ;; No change if < 'A'. + (if (i32.lt_u (get_local $c) (i32.const 65)) + (return (get_local $c))) + + ;; Clear 5th bit of c, to force uppercase. 0xdf = 0b11011111 + (set_local $uc (i32.and (get_local $c) (i32.const 0xdf))) + + ;; In range ['A', 'M'] return |c| + 13. + (if (i32.le_u (get_local $uc) (i32.const 77)) + (return (i32.add (get_local $c) (i32.const 13)))) + + ;; In range ['N', 'Z'] return |c| - 13. + (if (i32.le_u (get_local $uc) (i32.const 90)) + (return (i32.sub (get_local $c) (i32.const 13)))) + + ;; No change for everything else. + (return (get_local $c)) +) + +(func (export "rot13") + (local $size i32) + (local $i i32) + + ;; Ask host to fill memory [0, 1024) with data. + (call $fill_buf (i32.const 0) (i32.const 1024)) + + ;; The host returns the size filled. + (set_local $size) + + ;; Loop over all bytes and rot13 them. + (block $exit + (loop $top + ;; if (i >= size) break + (if (i32.ge_u (get_local $i) (get_local $size)) (br $exit)) + + ;; mem[i] = rot13c(mem[i]) + (i32.store8 + (get_local $i) + (call $rot13c + (i32.load8_u (get_local $i)))) + + ;; i++ + (set_local $i (i32.add (get_local $i) (i32.const 1))) + (br $top) + ) + ) + + (call $buf_done (i32.const 0) (get_local $size)) +) |