From 0fc6d95cc9ad8dd0ea76a5a70a7a474eb662bedd Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 15 Jun 2022 22:34:31 -0500 Subject: [PATCH] starting work on easy code builder --- include/vm_codebuilder.h | 25 ++++++++++++++++++ src/vm/code_builder.c | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 include/vm_codebuilder.h create mode 100644 src/vm/code_builder.c diff --git a/include/vm_codebuilder.h b/include/vm_codebuilder.h new file mode 100644 index 0000000..671e335 --- /dev/null +++ b/include/vm_codebuilder.h @@ -0,0 +1,25 @@ +#ifndef _OVM_CODE_BUILDER_H +#define _OVM_CODE_BUILDER_H + +#include "vm.h" + +typedef struct ovm_code_builder_t ovm_code_builder_t; + +// +// A new code builder will be "made" for each function +// being compiled. +struct ovm_code_builder_t { + bh_arr(i32) execution_stack; + + i32 param_count, local_count; + + ovm_program_t *program; + i32 start_instr; +}; + +ovm_code_builder_t ovm_code_builder_new(ovm_program_t *program, i32 param_count, i32 local_count); +void ovm_code_builder_add_binop(ovm_code_builder_t *builder, u32 instr); +void ovm_code_builder_add_imm(ovm_code_builder_t *builder, u32 ovm_type, void *imm); + + +#endif diff --git a/src/vm/code_builder.c b/src/vm/code_builder.c new file mode 100644 index 0000000..c64e368 --- /dev/null +++ b/src/vm/code_builder.c @@ -0,0 +1,57 @@ + +#include "vm_codebuilder.h" + +#define PUSH_VALUE(b, r) (bh_arr_push((b)->execution_stack, r)) +#define POP_VALUE(b) (bh_arr_length((b)->execution_stack) == 0 ? (assert(("invalid value pop", 0)), 0) : bh_arr_pop((b)->execution_stack)) +#define NEXT_VALUE(b) ((bh_arr_length((b)->execution_stack) == 0 ? (b)->param_count + (b)->local_count : bh_arr_last((b)->execution_stack)) + 1) + +// #define POP_VALUE(b) bh_arr_pop((b)->execution_stack) + +ovm_code_builder_t ovm_code_builder_new(ovm_program_t *program, i32 param_count, i32 local_count) { + ovm_code_builder_t builder; + builder.param_count = param_count; + builder.local_count = local_count; + builder.start_instr = bh_arr_length(program->code); + builder.program = program; + + builder.execution_stack = NULL; + bh_arr_new(bh_heap_allocator(), builder.execution_stack, 32); + + return builder; +} + + +void ovm_code_builder_add_binop(ovm_code_builder_t *builder, u32 instr) { + i32 right = POP_VALUE(builder); + i32 left = POP_VALUE(builder); + i32 result = NEXT_VALUE(builder); + + ovm_instr_t binop; + binop.full_instr = instr; + binop.r = result; + binop.a = left; + binop.b = right; + + ovm_program_add_instructions(builder->program, 1, &binop); + PUSH_VALUE(builder, result); +} + +void ovm_code_builder_add_imm(ovm_code_builder_t *builder, u32 ovm_type, void *imm) { + ovm_instr_t imm_instr; + imm_instr.full_instr = OVM_TYPED_INSTR(OVMI_IMM, ovm_type); + imm_instr.r = NEXT_VALUE(builder); + + switch (ovm_type) { + case OVM_TYPE_I8: imm_instr.i = (u32) *(u8 *) imm; break; + case OVM_TYPE_I16: imm_instr.i = (u32) *(u16 *) imm; break; + case OVM_TYPE_I32: imm_instr.i = *(u32 *) imm; break; + case OVM_TYPE_I64: imm_instr.l = *(u64 *) imm; break; + case OVM_TYPE_F32: imm_instr.f = *(f32 *) imm; break; + case OVM_TYPE_F64: imm_instr.d = *(f64 *) imm; break; + default: assert(("bad ovm type for add_imm", 0)); + } + + ovm_program_add_instructions(builder->program, 1, &imm_instr); + PUSH_VALUE(builder, imm_instr.r); +} + -- 2.25.1