From cc284482ea222e5a077a0d40aa50128bcf65a606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sun, 22 May 2022 20:35:28 +0200 Subject: [PATCH] standalone: Initial version using wamr --- .gitignore | 1 + scripts/bin2h | 17 ++++++ src/standalone/.gitignore | 3 ++ src/standalone/Makefile | 21 ++++++++ src/standalone/main.c | 110 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100755 scripts/bin2h create mode 100644 src/standalone/.gitignore create mode 100644 src/standalone/Makefile create mode 100644 src/standalone/main.c diff --git a/.gitignore b/.gitignore index 458f4d5..1f6d6a5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ dist/ *.tmp *.bin *.assembled.wat +*.o diff --git a/scripts/bin2h b/scripts/bin2h new file mode 100755 index 0000000..4d8c27f --- /dev/null +++ b/scripts/bin2h @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +const process = require("process"); +const fs = require("fs"); +const path = require("path"); + +const infn = process.argv[2]; +const outfn = process.argv[3]; + +const name = path.basename(outfn).split(".").slice(0, -1).join("."); +const inf = fs.readFileSync(infn); +const bs = []; +for (const b of inf) { + bs.push(`0x${b.toString(16)}`); +} +const out = `unsigned char ${name}[] = { ${bs.join(", ")} };\n`; +fs.writeFileSync(outfn, out); diff --git a/src/standalone/.gitignore b/src/standalone/.gitignore new file mode 100644 index 0000000..497e8d4 --- /dev/null +++ b/src/standalone/.gitignore @@ -0,0 +1,3 @@ +/waforth +/waforth_core.h +/wasm-micro-runtime diff --git a/src/standalone/Makefile b/src/standalone/Makefile new file mode 100644 index 0000000..5a46e21 --- /dev/null +++ b/src/standalone/Makefile @@ -0,0 +1,21 @@ +WAMR_DIR=wasm-micro-runtime +CC=clang +CFLAGS=-I$(WAMR_DIR)/core/iwasm/include -DWASM_ENABLE_DEBUG_INTERP +LDFLAGS=-L$(WAMR_DIR)/product-mini/platforms/darwin/build -rpath $(WAMR_DIR)/product-mini/platforms/darwin/build +LIBS=-liwasm + +BIN2H=../../scripts/bin2h +WAT2WASM=wat2wasm + +OBJECTS=main.o + +all: $(OBJECTS) + $(CC) -o waforth $(OBJECTS) $(LDFLAGS) $(LIBS) + +main.o: waforth_core.h + +waforth_core.wasm: ../waforth.wat + $(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $< + +waforth_core.h: waforth_core.wasm + $(BIN2H) ../waforth.wasm waforth_core.h \ No newline at end of file diff --git a/src/standalone/main.c b/src/standalone/main.c new file mode 100644 index 0000000..5f7f901 --- /dev/null +++ b/src/standalone/main.c @@ -0,0 +1,110 @@ +#include "waforth_core.h" +#include "wasm_export.h" +#include + +void waf_emit(wasm_exec_env_t exec_env, int c) { + printf("%c", c); +} + +int waf_read(wasm_exec_env_t exec_env, char *addr, size_t len) { + int n = 0; + while (!(n = getline(&addr, &len, stdin))) { + } + return n; +} + +int waf_key(wasm_exec_env_t exec_env) { + printf("key \n"); + return 0x20; +} + +void waf_call(wasm_exec_env_t exec_env) { + printf("error: call not implemented\n"); +} + +void waf_load(wasm_exec_env_t exec_env, int offset, int length, int index) { + printf("load %d %d %d\n", offset, length, index); +} + +static NativeSymbol native_symbols[] = { + {"emit", waf_emit, "(i)"}, + {"read", waf_read, "(*~)i"}, + {"key", waf_key, "()i"}, + {"call", waf_call, "()"}, + {"load", waf_load, /*"(*~i)"*/ "(iii)"}, +}; + +int main(int argc, char *argv_main[]) { + char error_buf[128]; + int ret = -1; + + if (!wasm_runtime_init()) { + printf("Init runtime environment failed.\n"); + goto fail; + } + + if (!wasm_runtime_register_natives("shell", native_symbols, sizeof(native_symbols) / sizeof(NativeSymbol))) { + goto fail; + } + + wasm_module_t module = wasm_runtime_load(waforth_core, sizeof(waforth_core), error_buf, sizeof(error_buf)); + if (!module) { + printf("Load wasm module failed. error: %s\n", error_buf); + goto fail; + } + + uint32_t stack_size = 10485760, heap_size = 10485760; + wasm_module_inst_t module_inst = wasm_runtime_instantiate(module, stack_size, heap_size, error_buf, sizeof(error_buf)); + if (!module_inst) { + printf("Instantiate wasm module failed. error: %s\n", error_buf); + goto fail; + } + + wasm_exec_env_t exec_env = wasm_runtime_create_exec_env(module_inst, stack_size); + if (!exec_env) { + printf("Create wasm execution environment failed.\n"); + goto fail; + } + + wasm_function_inst_t interpret = wasm_runtime_lookup_function(module_inst, "interpret", NULL); + if (!interpret) { + printf("The interpret wasm function is not found.\n"); + goto fail; + } + + printf("WAForth\n"); + wasm_val_t results[1] = {{.kind = WASM_I32, .of.i32 = 0}}; + while (true) { + if (!wasm_runtime_call_wasm_a(exec_env, interpret, 1, results, 0, NULL)) { + printf("interpret failed. %s\n", wasm_runtime_get_exception(module_inst)); + goto fail; + } + } + + /* + float ret_val; + ret_val = results[0].of.f32; + printf("Native finished calling wasm function generate_float(), returned a " + "float value: %ff\n", + ret_val); + */ + + ret = 0; + +fail: + if (exec_env) { + wasm_runtime_destroy_exec_env(exec_env); + } + if (module_inst) { + // if (wasm_buffer) + // wasm_runtime_module_free(module_inst, wasm_buffer); + wasm_runtime_deinstantiate(module_inst); + } + if (module) { + wasm_runtime_unload(module); + } + wasm_runtime_destroy(); + + printf("Done\n"); + return ret; +}