better instruction mapping; bugfixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 4 Jul 2022 04:11:33 +0000 (23:11 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 4 Jul 2022 04:11:33 +0000 (23:11 -0500)
build.sh
include/vm.h
src/vm/code_builder.c
src/vm/vm.c
src/wasm/module_parsing.c.incl

index 160e4565e3a07b4bdb49c758614569f3f8208fcd..e4095d852c2eba224e201e6293ee036675a9d936 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -2,7 +2,7 @@
 
 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"
+FLAGS="-O3"
 LIBS="-pthread"
 INCLUDES="-I include"
 TARGET="libonyx_embedder.so"
index ab7700483d24d4893c016db6769b4e74d044b5fc..b69260154333262912931bc8f16930ab05a04354 100644 (file)
@@ -124,6 +124,7 @@ ovm_state_t *ovm_state_new(ovm_engine_t *engine, ovm_program_t *program);
 void         ovm_state_delete(ovm_state_t *state);
 void ovm_state_link_external_funcs(ovm_program_t *program, ovm_state_t *state, ovm_linkable_func_t *funcs);
 void ovm_state_register_external_func(ovm_state_t *state, i32 idx, void (*func)(void *, ovm_value_t *, ovm_value_t *), void *data);
+ovm_value_t ovm_state_register_get(ovm_state_t *state, i32 idx);
 void ovm_state_register_set(ovm_state_t *state, i32 idx, ovm_value_t val);
 
 //
@@ -319,11 +320,13 @@ struct ovm_instr_t {
 #define OVMI_CVT_I64           0x66   // %r = (t) %a
 #define OVMI_CVT_I64_S         0x67   // %r = (t) %a (sign aware)
 #define OVMI_CVT_F32           0x68   // %r = (t) %a
-#define OVMI_CVT_F64           0x69   // %r = (t) %a
-#define OVMI_TRANSMUTE_I32     0x6A   // %r = *(t *) &%a (reinterpret bytes)
-#define OVMI_TRANSMUTE_I64     0x6B   // %r = *(t *) &%a (reinterpret bytes)
-#define OVMI_TRANSMUTE_F32     0x6C   // %r = *(t *) &%a (reinterpret bytes)
-#define OVMI_TRANSMUTE_F64     0x6D   // %r = *(t *) &%a (reinterpret bytes)
+#define OVMI_CVT_F32_S         0x69   // %r = (t) %a (sign aware)
+#define OVMI_CVT_F64           0x6A   // %r = (t) %a
+#define OVMI_CVT_F64_S         0x6B   // %r = (t) %a (sign aware)
+#define OVMI_TRANSMUTE_I32     0x6C   // %r = *(t *) &%a (reinterpret bytes)
+#define OVMI_TRANSMUTE_I64     0x6D   // %r = *(t *) &%a (reinterpret bytes)
+#define OVMI_TRANSMUTE_F32     0x6E   // %r = *(t *) &%a (reinterpret bytes)
+#define OVMI_TRANSMUTE_F64     0x6F   // %r = *(t *) &%a (reinterpret bytes)
 
 #define OVMI_CMPXCHG           0x70   // %r = %r == %a ? %b : %r 
 
index bcca1722c5d9372b637b072068d24de898034967..4f60d2c08cc3ad421306140524be1ca899e940cb 100644 (file)
@@ -21,7 +21,7 @@ static inline int NEXT_VALUE(ovm_code_builder_t *b) {
         return b->param_count + b->local_count;
     }
     
-    b->highest_value_number = bh_max(b->highest_value_number, bh_arr_last(b->execution_stack));
+    b->highest_value_number = bh_max(b->highest_value_number, bh_arr_last(b->execution_stack) + 1);
     return bh_arr_last(b->execution_stack) + 1;
 #endif
 }
@@ -80,10 +80,6 @@ void ovm_code_builder_pop_label_target(ovm_code_builder_t *builder) {
         target.instr = bh_arr_length(builder->program->code);
     }
 
-    // if (target.kind == label_kind_if) {
-    //     target.instr += 1;
-    // }
-
     fori (i, 0, bh_arr_length(builder->branch_patches)) {
         branch_patch_t patch = builder->branch_patches[i];
         if (patch.label_idx != target.idx) continue;
index 4c8de37decd1c6540a5999f7d13571e3c3bc46d8..353e2eb5c9f9cc5f59018308382518cc7a459897 100644 (file)
@@ -68,9 +68,8 @@ int ovm_program_register_static_ints(ovm_program_t *program, int len, int *data)
     new_entry.start_idx = bh_arr_length(program->static_integers);
     new_entry.len = len;
 
-    bh_arr_insert_end(program->static_integers, len);
     fori (i, 0, (int) len) {
-        program->static_integers[i + new_entry.start_idx] = data[i];
+        bh_arr_push(program->static_integers, data[i]);
     }
 
     bh_arr_push(program->static_data, new_entry);
@@ -496,6 +495,7 @@ void ovm_state_delete(ovm_state_t *state) {
     bh_arr_free(state->params);
     bh_arr_free(state->stack_frames);
     bh_arr_free(state->registers);
+    bh_arr_free(state->external_funcs);
 
     bh_free(store->heap_allocator, state);
 }
@@ -508,6 +508,12 @@ void ovm_state_register_external_func(ovm_state_t *state, i32 idx, void (*func)(
     bh_arr_set_at(state->external_funcs, idx, external_func);
 }
 
+ovm_value_t ovm_state_register_get(ovm_state_t *state, i32 idx) {
+    assert(idx < bh_arr_length(state->registers));
+
+    return state->registers[idx];
+}
+
 void ovm_state_register_set(ovm_state_t *state, i32 idx, ovm_value_t val) {
     if (idx >= bh_arr_length(state->registers)) return;
 
@@ -539,8 +545,17 @@ static inline void ovm__func_setup_stack_frame(ovm_engine_t *engine, ovm_state_t
     bh_arr_insert_end(state->numbered_values, func->value_number_count);
 }
 
+static inline ovm_stack_frame_t ovm__func_teardown_stack_frame(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *program) {
+    ovm_stack_frame_t frame = bh_arr_pop(state->stack_frames);
+    bh_arr_fastdeleten(state->numbered_values, frame.value_number_count);
+
+    state->value_number_offset = bh_arr_last(state->stack_frames).value_number_base;
+    return frame;
+}
+
 ovm_value_t ovm_func_call(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *program, i32 func_idx, i32 param_count, ovm_value_t *params) {
     ovm_func_t func = program->funcs[func_idx];
+    assert(func.value_number_count >= func.param_count);
 
     switch (func.kind) {
         case OVM_FUNC_INTERNAL: {
@@ -566,12 +581,9 @@ ovm_value_t ovm_func_call(ovm_engine_t *engine, ovm_state_t *state, ovm_program_
             ovm_value_t result = {0};
             ovm_external_func_t external_func = state->external_funcs[func.external_func_idx];
             external_func.native_func(external_func.userdata, state->params, &result);
-
-            bh_arr_pop(state->stack_frames);
-            state->value_number_offset = bh_arr_last(state->stack_frames).value_number_base;
-            bh_arr_fastdeleten(state->numbered_values, func.value_number_count);
             bh_arr_fastdeleten(state->params, func.param_count);
 
+            ovm__func_teardown_stack_frame(engine, state, program);
             return result;
         }
 
@@ -627,7 +639,7 @@ void ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *progr
     assert(state);
     assert(program);
 
-#define VAL(loc) (state->numbered_values[(u32) (loc + state->value_number_offset)])
+#define VAL(loc) state->numbered_values[(u32) (loc + state->value_number_offset)]
 
     ovm_instr_t *code = program->code;
     bool release_mutex_at_end = false;
@@ -963,12 +975,12 @@ void ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *progr
             }
 
             case OVMI_REG_GET: {
-                VAL(instr.r) = state->registers[instr.a];
+                VAL(instr.r) = ovm_state_register_get(state, instr.a);
                 break;
             }
 
             case OVMI_REG_SET: {
-                state->registers[instr.r] = VAL(instr.a);
+                ovm_state_register_set(state, instr.r, VAL(instr.a));
                 break;
             }
 
@@ -984,20 +996,15 @@ void ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *progr
                 break;
 
             case OVMI_RETURN: {
-                ovm_stack_frame_t frame = bh_arr_pop(state->stack_frames); 
-
                 ovm_value_t val = VAL(instr.a);
-                bh_arr_fastdeleten(state->numbered_values, frame.value_number_count);
+                ovm_stack_frame_t frame = ovm__func_teardown_stack_frame(engine, state, program); 
 
-                if (bh_arr_length(state->stack_frames) == 0) {
-                    state->value_number_offset = 0;
+                if (frame.return_number_value >= 0) {
                     VAL(frame.return_number_value) = val;
-                    return;
                 }
 
-                state->value_number_offset = bh_arr_last(state->stack_frames).value_number_base;
-                if (frame.return_number_value >= 0) {
-                    VAL(frame.return_number_value) = val;
+                if (bh_arr_length(state->stack_frames) == 0) {
+                    return;
                 }
 
                 ovm_func_t *new_func = bh_arr_last(state->stack_frames).func;
@@ -1036,9 +1043,7 @@ void ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *progr
                 external_func.native_func(external_func.userdata, state->params + extra_params, &result); \
                 bh_arr_fastdeleten(state->params, func->param_count); \
  \
-                ovm_stack_frame_t frame = bh_arr_pop(state->stack_frames); \
-                bh_arr_fastdeleten(state->numbered_values, frame.value_number_count); \
-                state->value_number_offset = bh_arr_last(state->stack_frames).value_number_base; \
+                ovm__func_teardown_stack_frame(engine, state, program); \
  \
                 if (instr.r >= 0) { \
                     VAL(instr.r) = result; \
@@ -1109,13 +1114,19 @@ void ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *progr
             case OVM_TYPED_INSTR(OVMI_CVT_I64,   OVM_TYPE_F64): CVT(u64, f64, OVM_TYPE_F64, f64);
             case OVM_TYPED_INSTR(OVMI_CVT_I64_S, OVM_TYPE_F64): CVT(i64, f64, OVM_TYPE_F64, f64);
 
-            case OVM_TYPED_INSTR(OVMI_CVT_F32, OVM_TYPE_I32): CVT(f32, u32, OVM_TYPE_I32, u32);
-            case OVM_TYPED_INSTR(OVMI_CVT_F32, OVM_TYPE_I64): CVT(f32, u64, OVM_TYPE_I64, u64);
-            case OVM_TYPED_INSTR(OVMI_CVT_F32, OVM_TYPE_F64): CVT(f32, f64, OVM_TYPE_F64, f64);
-
-            case OVM_TYPED_INSTR(OVMI_CVT_F64, OVM_TYPE_I32): CVT(f64, i32, OVM_TYPE_I32, u32);
-            case OVM_TYPED_INSTR(OVMI_CVT_F64, OVM_TYPE_I64): CVT(f64, i64, OVM_TYPE_I64, u64);
-            case OVM_TYPED_INSTR(OVMI_CVT_F64, OVM_TYPE_F32): CVT(f64, f32, OVM_TYPE_F32, f32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I32): CVT(f32, u32, OVM_TYPE_I32, u32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I64): CVT(f32, u64, OVM_TYPE_I64, u64);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_F64): CVT(f32, f64, OVM_TYPE_F64, f64);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32_S, OVM_TYPE_I32): CVT(f32, i32, OVM_TYPE_I32, i32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32_S, OVM_TYPE_I64): CVT(f32, i64, OVM_TYPE_I64, i64);
+            case OVM_TYPED_INSTR(OVMI_CVT_F32_S, OVM_TYPE_F64): CVT(f32, f64, OVM_TYPE_F64, f64);
+
+            case OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I32): CVT(f64, u32, OVM_TYPE_I32, u32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I64): CVT(f64, u64, OVM_TYPE_I64, u64);
+            case OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_F32): CVT(f64, f32, OVM_TYPE_F32, f32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F64_S, OVM_TYPE_I32): CVT(f64, i32, OVM_TYPE_I32, i32);
+            case OVM_TYPED_INSTR(OVMI_CVT_F64_S, OVM_TYPE_I64): CVT(f64, i64, OVM_TYPE_I64, i64);
+            case OVM_TYPED_INSTR(OVMI_CVT_F64_S, OVM_TYPE_F32): CVT(f64, f32, OVM_TYPE_F32, f32);
 
 #undef CVT
 
index 5ed0321b862b2c12ac315e3ecb7afab8c879cb95..48af61b62beac35746a3ebdc26c150de6f10b549 100644 (file)
@@ -833,15 +833,15 @@ static void parse_instruction(build_context *ctx) {
         case 0xA6: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_COPYSIGN, OVM_TYPE_F64)); break;
 
         case 0xA7: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_I64,   OVM_TYPE_I32)); break;
-        case 0xA8: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I32)); break;
+        case 0xA8: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32_S, OVM_TYPE_I32)); break;
         case 0xA9: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I32)); break;
-        case 0xAA: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I32)); break;
+        case 0xAA: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64_S, OVM_TYPE_I32)); break;
         case 0xAB: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I32)); break;
         case 0xAC: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_I32_S, OVM_TYPE_I64)); break;
         case 0xAD: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_I32,   OVM_TYPE_I64)); break;
-        case 0xAE: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I64)); break;
+        case 0xAE: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32_S, OVM_TYPE_I64)); break;
         case 0xAF: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F32,   OVM_TYPE_I64)); break;
-        case 0xB0: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I64)); break;
+        case 0xB0: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64_S, OVM_TYPE_I64)); break;
         case 0xB1: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_F64,   OVM_TYPE_I64)); break;
         case 0xB2: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_I32_S, OVM_TYPE_F32)); break;
         case 0xB3: ovm_code_builder_add_unop (&ctx->builder, OVM_TYPED_INSTR(OVMI_CVT_I32,   OVM_TYPE_F32)); break;