From: Brendan Hansen Date: Mon, 4 Jul 2022 04:11:33 +0000 (-0500) Subject: better instruction mapping; bugfixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ae1c9e0c42a925ce3e93d4ca0f7d4a391731cae2;p=onyx-embedder.git better instruction mapping; bugfixes --- diff --git a/build.sh b/build.sh index 160e456..e4095d8 100755 --- 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" diff --git a/include/vm.h b/include/vm.h index ab77004..b692601 100644 --- a/include/vm.h +++ b/include/vm.h @@ -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 diff --git a/src/vm/code_builder.c b/src/vm/code_builder.c index bcca172..4f60d2c 100644 --- a/src/vm/code_builder.c +++ b/src/vm/code_builder.c @@ -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; diff --git a/src/vm/vm.c b/src/vm/vm.c index 4c8de37..353e2eb 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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 diff --git a/src/wasm/module_parsing.c.incl b/src/wasm/module_parsing.c.incl index 5ed0321..48af61b 100644 --- a/src/wasm/module_parsing.c.incl +++ b/src/wasm/module_parsing.c.incl @@ -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;