mirror of
https://github.com/remko/waforth
synced 2024-12-27 09:59:29 +01:00
standalone: Switch to wasmtime
This commit is contained in:
parent
177c2808b7
commit
e5b1e5e892
5 changed files with 101 additions and 63 deletions
13
.github/workflows/publish-standalone.yml
vendored
Normal file
13
.github/workflows/publish-standalone.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
name: Publish Standalone
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-standalone:
|
||||||
|
needs: build
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- run: make -C src/standalone install-deps all
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/.vscode/*.log
|
||||||
node_modules/
|
node_modules/
|
||||||
public/waforth/
|
public/waforth/
|
||||||
public/thurtle/
|
public/thurtle/
|
||||||
|
|
1
src/standalone/.gitignore
vendored
1
src/standalone/.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
/waforth
|
/waforth
|
||||||
/waforth_core.h
|
/waforth_core.h
|
||||||
/wasm-micro-runtime
|
/wasm-micro-runtime
|
||||||
|
/wasmtime-*
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
WAMR_DIR=wasm-micro-runtime
|
WASMTIME_DIR=wasmtime-v0.37.0-x86_64-macos-c-api
|
||||||
CC=clang
|
WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v0.37.0/wasmtime-v0.37.0-x86_64-macos-c-api.tar.xz
|
||||||
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
|
CFLAGS=-I$(WASMTIME_DIR)/include
|
||||||
LIBS=-liwasm
|
LDFLAGS=
|
||||||
|
LIBS=$(WASMTIME_DIR)/lib/libwasmtime.a
|
||||||
|
|
||||||
BIN2H=../../scripts/bin2h
|
BIN2H=../../scripts/bin2h
|
||||||
WAT2WASM=wat2wasm
|
WAT2WASM=wat2wasm
|
||||||
|
WAT2WASM_FLAGS=--debug-names
|
||||||
|
|
||||||
OBJECTS=main.o
|
OBJECTS=main.o
|
||||||
|
|
||||||
all: $(OBJECTS)
|
all: waforth
|
||||||
$(CC) -o waforth $(OBJECTS) $(LDFLAGS) $(LIBS)
|
|
||||||
|
waforth: $(OBJECTS)
|
||||||
|
$(CC) -o $@ $(OBJECTS) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
main.o: waforth_core.h
|
main.o: waforth_core.h
|
||||||
|
|
||||||
|
@ -18,4 +22,14 @@ waforth_core.wasm: ../waforth.wat
|
||||||
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $<
|
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $<
|
||||||
|
|
||||||
waforth_core.h: waforth_core.wasm
|
waforth_core.h: waforth_core.wasm
|
||||||
$(BIN2H) ../waforth.wasm waforth_core.h
|
$(BIN2H) $< $@
|
||||||
|
|
||||||
|
.PHONY: install-deps
|
||||||
|
install-deps:
|
||||||
|
-rm -rf wasmtime-*
|
||||||
|
curl -L -s $(WASMTIME_RELEASE_URL) | tar xvz
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
-rm -f waforth_core.wasm waforth_core.h $(OBJECTS) waforth
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "waforth_core.h"
|
|
||||||
#include "wasm_c_api.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "waforth_core.h"
|
||||||
|
#include "wasm.h"
|
||||||
|
|
||||||
#define CORE_TABLE_EXPORT_INDEX 0
|
#define CORE_TABLE_EXPORT_INDEX 0
|
||||||
#define CORE_MEMORY_EXPORT_INDEX 1
|
#define CORE_MEMORY_EXPORT_INDEX 1
|
||||||
#define CORE_INTERPRET_EXPORT_INDEX 6
|
#define CORE_INTERPRET_EXPORT_INDEX 6
|
||||||
|
@ -10,6 +11,10 @@ wasm_memory_t *memory;
|
||||||
wasm_table_t *table;
|
wasm_table_t *table;
|
||||||
wasm_store_t *store;
|
wasm_store_t *store;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Utility
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
wasm_trap_t *trap_from_string(const char *s) {
|
wasm_trap_t *trap_from_string(const char *s) {
|
||||||
wasm_name_t message;
|
wasm_name_t message;
|
||||||
wasm_name_new_from_string_nt(&message, s);
|
wasm_name_new_from_string_nt(&message, s);
|
||||||
|
@ -18,6 +23,17 @@ wasm_trap_t *trap_from_string(const char *s) {
|
||||||
return trap;
|
return trap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_trap(wasm_trap_t *trap) {
|
||||||
|
wasm_name_t message;
|
||||||
|
wasm_trap_message(trap, &message);
|
||||||
|
printf(">> %s\n", message.data);
|
||||||
|
wasm_name_delete(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Callbacks
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
wasm_trap_t *emit_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
wasm_trap_t *emit_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||||
printf("%c", args->data[0].of.i32);
|
printf("%c", args->data[0].of.i32);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -29,6 +45,9 @@ wasm_trap_t *read_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||||
size_t len = args->data[1].of.i32;
|
size_t len = args->data[1].of.i32;
|
||||||
while (!(n = getline(&addr, &len, stdin))) {
|
while (!(n = getline(&addr, &len, stdin))) {
|
||||||
}
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
results->data[0].kind = WASM_I32;
|
results->data[0].kind = WASM_I32;
|
||||||
results->data[0].of.i32 = n;
|
results->data[0].of.i32 = n;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -49,8 +68,14 @@ wasm_trap_t *load_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) {
|
||||||
}
|
}
|
||||||
wasm_extern_t *externs[] = {wasm_table_as_extern(table), wasm_memory_as_extern(memory)};
|
wasm_extern_t *externs[] = {wasm_table_as_extern(table), wasm_memory_as_extern(memory)};
|
||||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||||
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL);
|
wasm_trap_t *trap = NULL;
|
||||||
|
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, &trap);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
|
printf("> Error instantiating loaded module!\n");
|
||||||
|
if (trap) {
|
||||||
|
print_trap(trap);
|
||||||
|
wasm_trap_delete(trap);
|
||||||
|
}
|
||||||
return trap_from_string("error instantiating module");
|
return trap_from_string("error instantiating module");
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -64,41 +89,9 @@ wasm_trap_t *call_cb(void *env, const wasm_val_vec_t *args, wasm_val_vec_t *resu
|
||||||
return trap;
|
return trap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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),
|
// Main
|
||||||
// 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[]) {
|
int main(int argc, char *argv_main[]) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
@ -120,7 +113,7 @@ int main(int argc, char *argv_main[]) {
|
||||||
wasm_func_t *read_fn = wasm_func_new(store, read_ft, read_cb);
|
wasm_func_t *read_fn = wasm_func_new(store, read_ft, read_cb);
|
||||||
wasm_functype_delete(read_ft);
|
wasm_functype_delete(read_ft);
|
||||||
|
|
||||||
wasm_functype_t *key_ft = wasm_functype_new_1_0(wasm_valtype_new_i32());
|
wasm_functype_t *key_ft = wasm_functype_new_0_1(wasm_valtype_new_i32());
|
||||||
wasm_func_t *key_fn = wasm_func_new(store, key_ft, key_cb);
|
wasm_func_t *key_fn = wasm_func_new(store, key_ft, key_cb);
|
||||||
wasm_functype_delete(key_ft);
|
wasm_functype_delete(key_ft);
|
||||||
|
|
||||||
|
@ -135,47 +128,64 @@ int main(int argc, char *argv_main[]) {
|
||||||
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_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_func_as_extern(call_fn)};
|
||||||
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs);
|
||||||
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL);
|
wasm_trap_t *trap = NULL;
|
||||||
|
wasm_instance_t *instance = wasm_instance_new(store, module, &imports, &trap);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
printf("> Error instantiating module!\n");
|
printf("error instantiating core module\n");
|
||||||
|
if (trap) {
|
||||||
|
print_trap(trap);
|
||||||
|
wasm_trap_delete(trap);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_extern_vec_t exports;
|
wasm_extern_vec_t exports;
|
||||||
wasm_instance_exports(instance, &exports);
|
wasm_instance_exports(instance, &exports);
|
||||||
if (exports.size == 0) {
|
if (exports.size == 0) {
|
||||||
printf("> Error accessing exports!\n");
|
printf("error accessing export\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory = wasm_extern_as_memory(exports.data[CORE_MEMORY_EXPORT_INDEX]);
|
memory = wasm_extern_as_memory(exports.data[CORE_MEMORY_EXPORT_INDEX]);
|
||||||
if (memory == NULL) {
|
if (memory == NULL) {
|
||||||
printf("> Error accessing export!\n");
|
printf("error accessing `memory` export\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
table = wasm_extern_as_table(exports.data[CORE_TABLE_EXPORT_INDEX]);
|
table = wasm_extern_as_table(exports.data[CORE_TABLE_EXPORT_INDEX]);
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
printf("> Error accessing export!\n");
|
printf("error accessing `table` export\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wasm_func_t *interpret_fn = wasm_extern_as_func(exports.data[CORE_INTERPRET_EXPORT_INDEX]);
|
const wasm_func_t *interpret_fn = wasm_extern_as_func(exports.data[CORE_INTERPRET_EXPORT_INDEX]);
|
||||||
if (interpret_fn == NULL) {
|
if (interpret_fn == NULL) {
|
||||||
printf("> Error accessing export!\n");
|
printf("error accessing `interpret` export\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_val_vec_t args = WASM_EMPTY_VEC;
|
printf("WAForth\n");
|
||||||
wasm_val_vec_t results = WASM_EMPTY_VEC;
|
wasm_val_t as[1] = {WASM_I32_VAL(0)};
|
||||||
wasm_trap_t *trap = wasm_func_call(interpret_fn, &args, &results);
|
wasm_val_vec_t args = WASM_ARRAY_VEC(as);
|
||||||
if (trap) {
|
wasm_val_t vs[] = {WASM_INIT_VAL};
|
||||||
printf("> Error calling function!\n");
|
wasm_val_vec_t results_vec = WASM_ARRAY_VEC(vs);
|
||||||
print_trap(trap);
|
while (true) {
|
||||||
return -1;
|
trap = wasm_func_call(interpret_fn, &args, &results_vec);
|
||||||
|
if (trap == NULL) {
|
||||||
|
// No trap means the input buffer was no longer filled when asked.
|
||||||
|
// This means the program should exit.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wasm_name_t message;
|
||||||
|
wasm_trap_message(trap, &message);
|
||||||
|
// `unreachable` is called when we want to reset the call stack, and start the interpreter
|
||||||
|
// loop again (i.e. when QUIT is called)
|
||||||
|
if (strstr(message.data, "wasm `unreachable` instruction executed") == NULL) {
|
||||||
|
printf("error: %s\n", message.data);
|
||||||
|
}
|
||||||
|
wasm_name_delete(&message);
|
||||||
|
wasm_trap_delete(trap);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Instantiated\n");
|
|
||||||
|
|
||||||
wasm_extern_vec_delete(&exports);
|
wasm_extern_vec_delete(&exports);
|
||||||
wasm_instance_delete(instance);
|
wasm_instance_delete(instance);
|
||||||
|
@ -187,6 +197,5 @@ int main(int argc, char *argv_main[]) {
|
||||||
wasm_module_delete(module);
|
wasm_module_delete(module);
|
||||||
wasm_store_delete(store);
|
wasm_store_delete(store);
|
||||||
wasm_engine_delete(engine);
|
wasm_engine_delete(engine);
|
||||||
printf("Done\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue