CC="gcc"
WARNINGS='-Wimplicit -Wmisleading-indentation -Wparentheses -Wsequence-point -Wreturn-type -Wshift-negative-value -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-function -Wunused-label -Wmaybe-uninitialized -Wsign-compare -Wstrict-overflow -Wduplicated-branches -Wduplicated-cond -Wtrigraphs -Waddress -Wlogical-op'
# FLAGS="-g3 -DOVM_VERBOSE=1"
-FLAGS="-O3"
+FLAGS="-Ofast"
LIBS="-pthread"
INCLUDES="-I include"
-TARGET="libonyx_embedder.so"
+TARGET="libovmwasm.so"
C_FILES="src/wasm.c src/vm/*.c src/wasm/*.c"
$CC $FLAGS $INCLUDES -shared -fPIC -o $TARGET $C_FILES $LIBS $WARNINGS
# LIBS="-L$(pwd) -lonyx_embedder -lm -Wl,-rpath=./"
#
# $CC $FLAGS $INCLUDES -o $TARGET $C_FILES $LIBS $WARNINGS
-
-
-flex -o src/tools/lex.yy.c src/tools/asm.l
-
-TARGET="bin/assembler"
-C_FILES="src/tools/assembler.c src/tools/lex.yy.c"
-
-$CC $FLAGS $INCLUDES -o $TARGET $C_FILES $LIBS $WARNINGS
+#
+#
+# flex -o src/tools/lex.yy.c src/tools/asm.l
+#
+# TARGET="bin/assembler"
+# C_FILES="src/tools/assembler.c src/tools/lex.yy.c"
+#
+# $CC $FLAGS $INCLUDES -o $TARGET $C_FILES $LIBS $WARNINGS
+++ /dev/null
-#ifndef _ONYX_WASM_H
-#define _ONYX_WASM_H
-
-#include "wasm.h"
-#include "vm.h"
-
-// Core Utils
-
-struct wasm_config_t {
- bool debug_enabled;
-};
-
-void wasm_config_enable_debug(wasm_config_t *config, bool enabled);
-
-struct wasm_engine_t {
- wasm_config_t *config;
-
- ovm_store_t *store;
- ovm_engine_t *engine;
-};
-
-struct wasm_store_t {
- wasm_engine_t *engine;
-};
-
-
-// Types
-
-struct wasm_valtype_t {
- wasm_valkind_t kind;
-};
-
-struct wasm_functype_inner_t {
- wasm_valtype_vec_t params;
- wasm_valtype_vec_t results;
-};
-
-struct wasm_globaltype_inner_t {
- wasm_valtype_t *content;
- wasm_mutability_t mutability;
-
- wasm_val_t initial_value;
-};
-
-struct wasm_tabletype_inner_t {
- wasm_valtype_t *element;
- wasm_limits_t limits;
-
- i32 static_arr;
-};
-
-struct wasm_memorytype_inner_t {
- wasm_limits_t limits;
-};
-
-struct wasm_externtype_t {
- wasm_externkind_t kind;
- union {
- struct wasm_functype_inner_t func;
- struct wasm_globaltype_inner_t global;
- struct wasm_tabletype_inner_t table;
- struct wasm_memorytype_inner_t memory;
- };
-};
-
-struct wasm_functype_t { wasm_externtype_t type; };
-struct wasm_globaltype_t { wasm_externtype_t type; };
-struct wasm_tabletype_t { wasm_externtype_t type; };
-struct wasm_memorytype_t { wasm_externtype_t type; };
-
-struct wasm_importtype_t {
- wasm_name_t module_name;
- wasm_name_t import_name;
- wasm_externtype_t *type;
-
- //
- // This is only used by imported functions
- // to specify which slot the function binding
- // should be placed. When making a functype by
- // hand, this proably will never be used.
- int external_func_idx;
-};
-
-struct wasm_exporttype_t {
- wasm_name_t name;
- wasm_externtype_t *type;
- int index;
-};
-
-
-// Runtime Objects
-
-struct wasm_ref_t {
-};
-
-struct wasm_frame_t {
-};
-
-struct wasm_trap_t {
- wasm_message_t msg;
-};
-
-struct wasm_foreign_t {
-};
-
-struct wasm_data_t {
- void *data;
- unsigned int length;
- unsigned int offset;
- bool passive;
-};
-
-struct wasm_module_t {
- wasm_store_t *store;
-
- wasm_functype_vec_t type_section;
-
- wasm_functype_vec_t functypes;
- wasm_globaltype_vec_t globaltypes;
- wasm_tabletype_vec_t tabletypes;
- wasm_memorytype_vec_t memorytypes;
- wasm_importtype_vec_t imports;
- wasm_exporttype_vec_t exports;
-
- int start_func_idx;
-
- unsigned int elem_count;
- unsigned int *elem_entries; // Array of function indicies
-
- bool data_count_present;
- unsigned int data_count;
- struct wasm_data_t *data_entries;
-
- ovm_program_t *program;
- bool valid;
-
- int memory_init_idx;
- int memory_init_external_idx;
-};
-
-struct wasm_func_inner_t {
- bool env_present;
- void *env;
- void (*func_ptr)();
- void (*finalizer)(void *);
-
- const wasm_functype_t *type;
-};
-
-struct wasm_global_inner_t {
- int register_index;
- ovm_state_t *state;
- ovm_engine_t *engine;
-
- wasm_val_t initial_value;
-
- const wasm_globaltype_t *type;
-};
-
-struct wasm_table_inner_t {
- ovm_program_t *program;
- ovm_engine_t *engine;
-
- i32 static_arr;
-
- const wasm_tabletype_t *type;
-};
-
-struct wasm_memory_inner_t {
- ovm_engine_t* engine;
-
- const wasm_memorytype_t *type;
-};
-
-struct wasm_extern_t {
- const wasm_externtype_t *type;
- union {
- struct wasm_func_inner_t func;
- struct wasm_global_inner_t global;
- struct wasm_table_inner_t table;
- struct wasm_memory_inner_t memory;
- };
-};
-
-struct wasm_func_t { wasm_extern_t inner; };
-struct wasm_global_t { wasm_extern_t inner; };
-struct wasm_table_t { wasm_extern_t inner; };
-struct wasm_memory_t { wasm_extern_t inner; };
-
-struct wasm_instance_t {
- const wasm_module_t *module;
- wasm_store_t *store;
-
- bh_arr(wasm_func_t *) funcs;
- bh_arr(wasm_memory_t *) memories;
- bh_arr(wasm_table_t *) tables;
- bh_arr(wasm_global_t *) globals;
-
- wasm_extern_vec_t exports;
-
- ovm_state_t *state;
-};
-
-
-bool wasm_functype_equals(wasm_functype_t *a, wasm_functype_t *b);
-
-wasm_functype_t *wasm_module_index_functype(wasm_module_t *module, int index);
-wasm_tabletype_t *wasm_module_index_tabletype(wasm_module_t *module, int index);
-wasm_globaltype_t *wasm_module_index_globaltype(wasm_module_t *module, int index);
-wasm_memorytype_t *wasm_module_index_memorytype(wasm_module_t *module, int index);
-
-
-
-#define WASM_DECLARE_VEC_IMPL(type, ptr_or_none) \
- void wasm_##type##_vec_new_empty(wasm_##type##_vec_t *out) { \
- out->size = 0; \
- out->data = NULL; \
- } \
- \
- void wasm_##type##_vec_new_uninitialized(wasm_##type##_vec_t *out, size_t size) { \
- out->data = malloc(sizeof(wasm_##type##_t ptr_or_none) * size); \
- out->size = size; \
- } \
- \
- void wasm_##type##_vec_new(wasm_##type##_vec_t *out, size_t size, wasm_##type##_t ptr_or_none const data[]) { \
- out->data = malloc(sizeof(wasm_##type##_t ptr_or_none) * size); \
- out->size = size; \
- \
- fori (i, 0, (i32) size) { \
- out->data[i] = data[i]; \
- } \
- } \
- \
- void wasm_##type##_vec_copy(wasm_##type##_vec_t *out, const wasm_##type##_vec_t *in) { \
- wasm_##type##_vec_new(out, in->size, in->data); \
- } \
- \
- void wasm_##type##_vec_delete(wasm_##type##_vec_t *vec) { \
- if (vec->data) free(vec->data); \
- }
-
-#endif
--- /dev/null
+#ifndef _OVM_WASM_H
+#define _OVM_WASM_H
+
+#include "wasm.h"
+#include "vm.h"
+
+// Core Utils
+
+struct wasm_config_t {
+ bool debug_enabled;
+};
+
+void wasm_config_enable_debug(wasm_config_t *config, bool enabled);
+
+struct wasm_engine_t {
+ wasm_config_t *config;
+
+ ovm_store_t *store;
+ ovm_engine_t *engine;
+};
+
+struct wasm_store_t {
+ wasm_engine_t *engine;
+ wasm_instance_t *instance;
+};
+
+
+// Types
+
+struct wasm_valtype_t {
+ wasm_valkind_t kind;
+};
+
+struct wasm_functype_inner_t {
+ wasm_valtype_vec_t params;
+ wasm_valtype_vec_t results;
+};
+
+struct wasm_globaltype_inner_t {
+ wasm_valtype_t *content;
+ wasm_mutability_t mutability;
+
+ wasm_val_t initial_value;
+};
+
+struct wasm_tabletype_inner_t {
+ wasm_valtype_t *element;
+ wasm_limits_t limits;
+
+ i32 static_arr;
+};
+
+struct wasm_memorytype_inner_t {
+ wasm_limits_t limits;
+};
+
+struct wasm_externtype_t {
+ wasm_externkind_t kind;
+ union {
+ struct wasm_functype_inner_t func;
+ struct wasm_globaltype_inner_t global;
+ struct wasm_tabletype_inner_t table;
+ struct wasm_memorytype_inner_t memory;
+ };
+};
+
+struct wasm_functype_t { wasm_externtype_t type; };
+struct wasm_globaltype_t { wasm_externtype_t type; };
+struct wasm_tabletype_t { wasm_externtype_t type; };
+struct wasm_memorytype_t { wasm_externtype_t type; };
+
+struct wasm_importtype_t {
+ wasm_name_t module_name;
+ wasm_name_t import_name;
+ wasm_externtype_t *type;
+
+ //
+ // This is only used by imported functions
+ // to specify which slot the function binding
+ // should be placed. When making a functype by
+ // hand, this proably will never be used.
+ int external_func_idx;
+};
+
+struct wasm_exporttype_t {
+ wasm_name_t name;
+ wasm_externtype_t *type;
+ int index;
+};
+
+
+// Runtime Objects
+
+struct wasm_ref_t {
+};
+
+struct wasm_frame_t {
+ wasm_instance_t *instance;
+ int func_idx;
+ size_t func_offset;
+ size_t module_offset;
+};
+
+struct wasm_trap_t {
+ wasm_message_t msg;
+ wasm_frame_vec_t frames;
+
+ wasm_store_t *store;
+};
+
+struct wasm_foreign_t {
+};
+
+struct wasm_data_t {
+ void *data;
+ unsigned int length;
+ unsigned int offset;
+ bool passive;
+};
+
+struct wasm_module_t {
+ wasm_store_t *store;
+
+ wasm_functype_vec_t type_section;
+
+ wasm_functype_vec_t functypes;
+ wasm_globaltype_vec_t globaltypes;
+ wasm_tabletype_vec_t tabletypes;
+ wasm_memorytype_vec_t memorytypes;
+ wasm_importtype_vec_t imports;
+ wasm_exporttype_vec_t exports;
+
+ int start_func_idx;
+
+ unsigned int elem_count;
+ unsigned int *elem_entries; // Array of function indicies
+
+ bool data_count_present;
+ unsigned int data_count;
+ struct wasm_data_t *data_entries;
+
+ ovm_program_t *program;
+ bool valid;
+
+ int memory_init_idx;
+ int memory_init_external_idx;
+};
+
+struct wasm_func_inner_t {
+ bool env_present;
+ void *env;
+ void (*func_ptr)();
+ void (*finalizer)(void *);
+
+ const wasm_functype_t *type;
+};
+
+struct wasm_global_inner_t {
+ int register_index;
+ ovm_state_t *state;
+ ovm_engine_t *engine;
+
+ wasm_val_t initial_value;
+
+ const wasm_globaltype_t *type;
+};
+
+struct wasm_table_inner_t {
+ ovm_program_t *program;
+ ovm_engine_t *engine;
+
+ int static_arr;
+
+ const wasm_tabletype_t *type;
+};
+
+struct wasm_memory_inner_t {
+ ovm_engine_t* engine;
+
+ const wasm_memorytype_t *type;
+};
+
+struct wasm_extern_t {
+ const wasm_externtype_t *type;
+ union {
+ struct wasm_func_inner_t func;
+ struct wasm_global_inner_t global;
+ struct wasm_table_inner_t table;
+ struct wasm_memory_inner_t memory;
+ };
+};
+
+struct wasm_func_t { wasm_extern_t inner; };
+struct wasm_global_t { wasm_extern_t inner; };
+struct wasm_table_t { wasm_extern_t inner; };
+struct wasm_memory_t { wasm_extern_t inner; };
+
+struct wasm_instance_t {
+ const wasm_module_t *module;
+ wasm_store_t *store;
+
+ bh_arr(wasm_func_t *) funcs;
+ bh_arr(wasm_memory_t *) memories;
+ bh_arr(wasm_table_t *) tables;
+ bh_arr(wasm_global_t *) globals;
+
+ wasm_extern_vec_t exports;
+
+ ovm_state_t *state;
+};
+
+
+bool wasm_functype_equals(wasm_functype_t *a, wasm_functype_t *b);
+
+wasm_functype_t *wasm_module_index_functype(wasm_module_t *module, int index);
+wasm_tabletype_t *wasm_module_index_tabletype(wasm_module_t *module, int index);
+wasm_globaltype_t *wasm_module_index_globaltype(wasm_module_t *module, int index);
+wasm_memorytype_t *wasm_module_index_memorytype(wasm_module_t *module, int index);
+
+
+
+#define WASM_DECLARE_VEC_IMPL(type, ptr_or_none) \
+ void wasm_##type##_vec_new_empty(wasm_##type##_vec_t *out) { \
+ out->size = 0; \
+ out->data = NULL; \
+ } \
+ \
+ void wasm_##type##_vec_new_uninitialized(wasm_##type##_vec_t *out, size_t size) { \
+ out->data = malloc(sizeof(wasm_##type##_t ptr_or_none) * size); \
+ out->size = size; \
+ } \
+ \
+ void wasm_##type##_vec_new(wasm_##type##_vec_t *out, size_t size, wasm_##type##_t ptr_or_none const data[]) { \
+ out->data = malloc(sizeof(wasm_##type##_t ptr_or_none) * size); \
+ out->size = size; \
+ \
+ fori (i, 0, (i32) size) { \
+ out->data[i] = data[i]; \
+ } \
+ } \
+ \
+ void wasm_##type##_vec_copy(wasm_##type##_vec_t *out, const wasm_##type##_vec_t *in) { \
+ wasm_##type##_vec_new(out, in->size, in->data); \
+ } \
+ \
+ void wasm_##type##_vec_delete(wasm_##type##_vec_t *vec) { \
+ if (vec->data) free(vec->data); \
+ }
+
+#endif
#define OVMI_SAR 0x0D // %r = %a >>> %b
#define OVMI_IMM 0x10 // %r = i/l/f/d
-#define OVMI_MOV 0x10 // %r = %a
-#define OVMI_LOAD 0x11 // %r = mem[%a + %b]
-#define OVMI_STORE 0x12 // mem[%r + %b] = %a
-#define OVMI_COPY 0x13 // memcpy(%r, %a, %b)
-#define OVMI_FILL 0x14 // memset(%r, %a, %b)
-#define OVMI_REG_GET 0x15 // %r = #a
-#define OVMI_REG_SET 0x16 // #r = %a
-#define OVMI_IDX_ARR 0x17 // %r = (a)[%b]
+#define OVMI_MOV 0x11 // %r = %a
+#define OVMI_LOAD 0x12 // %r = mem[%a + %b]
+#define OVMI_STORE 0x13 // mem[%r + %b] = %a
+#define OVMI_COPY 0x14 // memcpy(%r, %a, %b)
+#define OVMI_FILL 0x15 // memset(%r, %a, %b)
+#define OVMI_REG_GET 0x16 // %r = #a
+#define OVMI_REG_SET 0x17 // #r = %a
+#define OVMI_IDX_ARR 0x18 // %r = (a)[%b]
#define OVMI_LT 0x20 // %r = %a < %b
#define OVMI_LT_S 0x21 // %r = %a < %b
#include "bh.h"
#include "stb_ds.h"
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
wasm_config_t *wasm_config_new() {
wasm_config_t *config = malloc(sizeof(*config));
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_engine_t *wasm_engine_new() {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
WASM_DECLARE_VEC_IMPL(extern, *)
-// TODO
+#include "ovm_wasm.h"
+
+
+void wasm_frame_delete(wasm_frame_t *frame) {
+ // Don't have to free the frame because it was allocated on the
+ // arena allocator.
+}
+
+WASM_DECLARE_VEC_IMPL(frame, *)
+
+wasm_frame_t *wasm_frame_copy(const wasm_frame_t* frame) {
+ if (!frame) return NULL;
+ assert(frame->instance);
+
+ wasm_frame_t *new_frame = bh_alloc_item(frame->instance->store->engine->store->arena_allocator, wasm_frame_t);
+ memcpy(new_frame, frame, sizeof(*frame));
+
+ return new_frame;
+}
+
+wasm_instance_t* wasm_frame_instance(const wasm_frame_t* frame) {
+ return frame->instance;
+}
+
+u32 wasm_frame_func_index(const wasm_frame_t *frame) {
+ return frame->func_idx;
+}
+
+size_t wasm_frame_func_offset(const wasm_frame_t *frame) {
+ return frame->func_offset;
+}
+
+size_t wasm_frame_module_offset(const wasm_frame_t *frame) {
+ return frame->module_offset;
+}
+
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_func_t *wasm_func_new(wasm_store_t *store, const wasm_functype_t *type, wasm_func_callback_t callback) {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_global_t *wasm_global_new(wasm_store_t *store, const wasm_globaltype_t *type, const wasm_val_t *initial) {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
#include <alloca.h>
+static_assert(sizeof(ovm_value_t) == sizeof(wasm_val_t));
+
typedef struct wasm_ovm_binding wasm_ovm_binding;
struct wasm_ovm_binding {
int func_idx;
instance->store = store;
instance->module = module;
+ if (store->instance) {
+ bh_printf("A WASM store should only be used for a single instance!\n");
+ return NULL;
+ }
+
+ store->instance = instance;
+
instance->funcs = NULL;
instance->memories = NULL;
instance->tables = NULL;
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_memory_t *wasm_memory_new(wasm_store_t *store, const wasm_memorytype_t *type) {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm_codebuilder.h"
#include "./module_parsing.h"
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_store_t *wasm_store_new(wasm_engine_t *engine) {
wasm_store_t *store = bh_alloc(engine->store->arena_allocator, sizeof(wasm_store_t));
store->engine = engine;
+ store->instance = NULL;
return store;
}
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_table_t *wasm_table_new(wasm_store_t *store, const wasm_tabletype_t *type, wasm_ref_t *init) {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
wasm_trap_t *wasm_trap_new(wasm_store_t *store, const wasm_message_t *msg) {
wasm_trap_t *trap = bh_alloc(store->engine->store->arena_allocator, sizeof(*trap));
+ trap->store = store;
trap->msg = *msg;
+ //
+ // Generate frames
+ bh_arr(ovm_stack_frame_t) ovm_frames = store->instance->state->stack_frames;
+ int frame_count = bh_arr_length(ovm_frames);
+
+ wasm_frame_vec_new_uninitialized(&trap->frames, frame_count);
+
+ fori (i, 0, frame_count) {
+ ovm_stack_frame_t *ovm_frame = &ovm_frames[frame_count - 1 - i];
+ wasm_frame_t *frame = bh_alloc(store->engine->store->arena_allocator, sizeof(*frame));
+ frame->instance = store->instance;
+ frame->func_idx = ovm_frame->func->id;
+ frame->func_offset = 0;
+ frame->module_offset = 0;
+
+ trap->frames.data[i] = frame;
+ }
+
return trap;
}
}
wasm_frame_t *wasm_trap_origin(const wasm_trap_t *trap) {
- return NULL;
+ return trap->frames.data[0];
}
void wasm_trap_trace(const wasm_trap_t *trap, wasm_frame_vec_t *frames) {
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"
//
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
void wasm_val_delete(wasm_val_t* v) {
// Apparently this is suppose to do nothing...
#include "bh.h"
#include "wasm.h"
-#include "onyx_wasm.h"
+#include "ovm_wasm.h"
#include "vm.h"