mirror of
https://github.com/remko/waforth
synced 2024-12-27 09:59:29 +01:00
standalone: Switch to wasm-c-api
This commit is contained in:
parent
cc284482ea
commit
177c2808b7
2 changed files with 158 additions and 76 deletions
|
@ -1,7 +1,7 @@
|
|||
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
|
||||
CFLAGS=-g -I$(WAMR_DIR)/core/iwasm/include -DWASM_ENABLE_DEBUG_INTERP
|
||||
LDFLAGS=-g -L$(WAMR_DIR)/product-mini/platforms/darwin/build -rpath $(WAMR_DIR)/product-mini/platforms/darwin/build
|
||||
LIBS=-liwasm
|
||||
|
||||
BIN2H=../../scripts/bin2h
|
||||
|
|
|
@ -1,110 +1,192 @@
|
|||
#include "waforth_core.h"
|
||||
#include "wasm_export.h"
|
||||
#include "wasm_c_api.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void waf_emit(wasm_exec_env_t exec_env, int c) {
|
||||
printf("%c", c);
|
||||
#define CORE_TABLE_EXPORT_INDEX 0
|
||||
#define CORE_MEMORY_EXPORT_INDEX 1
|
||||
#define CORE_INTERPRET_EXPORT_INDEX 6
|
||||
|
||||
wasm_memory_t *memory;
|
||||
wasm_table_t *table;
|
||||
wasm_store_t *store;
|
||||
|
||||
wasm_trap_t *trap_from_string(const char *s) {
|
||||
wasm_name_t message;
|
||||
wasm_name_new_from_string_nt(&message, s);
|
||||
wasm_trap_t *trap = wasm_trap_new(store, &message);
|
||||
wasm_name_delete(&message);
|
||||
return trap;
|
||||
}
|
||||
|
||||
int waf_read(wasm_exec_env_t exec_env, char *addr, size_t len) {
|
||||
wasm_trap_t *emit_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||
printf("%c", args->data[0].of.i32);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wasm_trap_t *read_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||
int n = 0;
|
||||
char *addr = &wasm_memory_data(memory)[args->data[0].of.i32];
|
||||
size_t len = args->data[1].of.i32;
|
||||
while (!(n = getline(&addr, &len, stdin))) {
|
||||
}
|
||||
return n;
|
||||
results->data[0].kind = WASM_I32;
|
||||
results->data[0].of.i32 = n;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int waf_key(wasm_exec_env_t exec_env) {
|
||||
printf("key \n");
|
||||
return 0x20;
|
||||
wasm_trap_t *key_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void waf_call(wasm_exec_env_t exec_env) {
|
||||
printf("error: call not implemented\n");
|
||||
wasm_trap_t *load_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||
wasm_byte_t *addr = &wasm_memory_data(memory)[args->data[0].of.i32];
|
||||
size_t len = args->data[1].of.i32;
|
||||
wasm_byte_vec_t data = {.data = addr, .size = len};
|
||||
wasm_module_t *module = wasm_module_new(store, &data);
|
||||
if (!module) {
|
||||
return trap_from_string("error compiling module");
|
||||
}
|
||||
wasm_extern_t *externs[] = {wasm_table_as_extern(table), wasm_memory_as_extern(memory)};
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
return trap_from_string("error instantiating module");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void waf_load(wasm_exec_env_t exec_env, int offset, int length, int index) {
|
||||
printf("load %d %d %d\n", offset, length, index);
|
||||
wasm_trap_t *call_cb(void *env, const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||
wasm_name_t message;
|
||||
wasm_name_new_from_string_nt(&message, "'call' not available in standalone");
|
||||
wasm_trap_t *trap = wasm_trap_new((wasm_store_t *)env, &message);
|
||||
wasm_name_delete(&message);
|
||||
return trap;
|
||||
}
|
||||
|
||||
static NativeSymbol native_symbols[] = {
|
||||
{"emit", waf_emit, "(i)"},
|
||||
{"read", waf_read, "(*~)i"},
|
||||
{"key", waf_key, "()i"},
|
||||
{"call", waf_call, "()"},
|
||||
{"load", waf_load, /*"(*~i)"*/ "(iii)"},
|
||||
};
|
||||
// void print_frame(wasm_frame_t *frame) {
|
||||
// printf("> %p @ 0x%zx = %" PRIu32 ".0x%zx\n", wasm_frame_instance(frame), wasm_frame_module_offset(frame), wasm_frame_func_index(frame),
|
||||
// wasm_frame_func_offset(frame));
|
||||
// }
|
||||
|
||||
void print_trap(wasm_trap_t *trap) {
|
||||
printf("Printing message...\n");
|
||||
wasm_name_t message;
|
||||
wasm_trap_message(trap, &message);
|
||||
printf("> %s\n", message.data);
|
||||
|
||||
// printf("Printing origin...\n");
|
||||
// wasm_frame_t *frame = wasm_trap_origin(trap);
|
||||
// if (frame) {
|
||||
// print_frame(frame);
|
||||
// wasm_frame_delete(frame);
|
||||
// } else {
|
||||
// printf("> Empty origin.\n");
|
||||
// }
|
||||
|
||||
// printf("Printing trace...\n");
|
||||
// wasm_frame_vec_t trace;
|
||||
// wasm_trap_trace(trap, &trace);
|
||||
// if (trace.size > 0) {
|
||||
// for (size_t i = 0; i < trace.size; ++i) {
|
||||
// print_frame(trace.data[i]);
|
||||
// }
|
||||
// } else {
|
||||
// printf("> Empty trace.\n");
|
||||
// }
|
||||
|
||||
// wasm_frame_vec_delete(&trace);
|
||||
wasm_trap_delete(trap);
|
||||
wasm_name_delete(&message);
|
||||
}
|
||||
|
||||
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));
|
||||
wasm_engine_t *engine = wasm_engine_new();
|
||||
store = wasm_store_new(engine);
|
||||
wasm_byte_vec_t core = {.data = (wasm_byte_t *)waforth_core, .size = sizeof(waforth_core)};
|
||||
wasm_module_t *module = wasm_module_new(store, &core);
|
||||
if (!module) {
|
||||
printf("Load wasm module failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
printf("error compiling\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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_functype_t *emit_ft = wasm_functype_new_1_0(wasm_valtype_new_i32());
|
||||
wasm_func_t *emit_fn = wasm_func_new(store, emit_ft, emit_cb);
|
||||
wasm_functype_delete(emit_ft);
|
||||
|
||||
wasm_functype_t *read_ft = wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32());
|
||||
wasm_func_t *read_fn = wasm_func_new(store, read_ft, read_cb);
|
||||
wasm_functype_delete(read_ft);
|
||||
|
||||
wasm_functype_t *key_ft = wasm_functype_new_1_0(wasm_valtype_new_i32());
|
||||
wasm_func_t *key_fn = wasm_func_new(store, key_ft, key_cb);
|
||||
wasm_functype_delete(key_ft);
|
||||
|
||||
wasm_functype_t *load_ft = wasm_functype_new_2_0(wasm_valtype_new_i32(), wasm_valtype_new_i32());
|
||||
wasm_func_t *load_fn = wasm_func_new(store, load_ft, load_cb);
|
||||
wasm_functype_delete(load_ft);
|
||||
|
||||
wasm_functype_t *call_ft = wasm_functype_new_0_0();
|
||||
wasm_func_t *call_fn = wasm_func_new_with_env(store, call_ft, call_cb, store, NULL);
|
||||
wasm_functype_delete(call_ft);
|
||||
|
||||
wasm_extern_t *externs[] = {wasm_func_as_extern(emit_fn), wasm_func_as_extern(read_fn), wasm_func_as_extern(key_fn), wasm_func_as_extern(load_fn),
|
||||
wasm_func_as_extern(call_fn)};
|
||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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_extern_vec_t exports;
|
||||
wasm_instance_exports(instance, &exports);
|
||||
if (exports.size == 0) {
|
||||
printf("> Error accessing exports!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
memory = wasm_extern_as_memory(exports.data[CORE_MEMORY_EXPORT_INDEX]);
|
||||
if (memory == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
table = wasm_extern_as_table(exports.data[CORE_TABLE_EXPORT_INDEX]);
|
||||
if (table == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
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);
|
||||
const wasm_func_t *interpret_fn = wasm_extern_as_func(exports.data[CORE_INTERPRET_EXPORT_INDEX]);
|
||||
if (interpret_fn == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return -1;
|
||||
}
|
||||
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();
|
||||
|
||||
wasm_val_vec_t args = WASM_EMPTY_VEC;
|
||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
||||
wasm_trap_t *trap = wasm_func_call(interpret_fn, &args, &results);
|
||||
if (trap) {
|
||||
printf("> Error calling function!\n");
|
||||
print_trap(trap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Instantiated\n");
|
||||
|
||||
wasm_extern_vec_delete(&exports);
|
||||
wasm_instance_delete(instance);
|
||||
wasm_func_delete(call_fn);
|
||||
wasm_func_delete(load_fn);
|
||||
wasm_func_delete(key_fn);
|
||||
wasm_func_delete(read_fn);
|
||||
wasm_func_delete(emit_fn);
|
||||
wasm_module_delete(module);
|
||||
wasm_store_delete(store);
|
||||
wasm_engine_delete(engine);
|
||||
printf("Done\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue