From fae29086afbcbd4e7202060fa151aa4da00a0d65 Mon Sep 17 00:00:00 2001 From: Shaw Summa Date: Mon, 23 Oct 2023 23:36:30 -0400 Subject: [PATCH] works for ints --- vm/be/tb.c | 146 ++++++++++++++++------------------ vm/ir.c | 4 - vm/ir.h | 2 - vm/lang/paka.c | 28 +------ vm/lang/paka.h | 3 + vm/obj.c | 211 +++++++++++++++++++++++++++++++++++++++++-------- vm/obj.h | 10 +++ vm/rblock.c | 8 +- vm/std/std.h | 8 -- vm/type.c | 31 +------- 10 files changed, 272 insertions(+), 179 deletions(-) diff --git a/vm/be/tb.c b/vm/be/tb.c index 673bdf2c..284c8bef 100644 --- a/vm/be/tb.c +++ b/vm/be/tb.c @@ -1,8 +1,6 @@ #include "./tb.h" -#include - #include "../../tb/include/tb.h" #include "../check.h" #include "../rblock.h" @@ -87,7 +85,29 @@ TB_DataType vm_tb_func_tag(TB_Function *fun, vm_tag_t tag) { TB_Node *vm_tb_func_read_arg(TB_Function *fun, TB_Node **regs, vm_arg_t arg) { switch (arg.type) { case VM_ARG_NUM: { - return tb_inst_float64(fun, arg.num.value.f64); + switch (arg.num.tag) { + case VM_TAG_I8: { + return tb_inst_sint(fun, TB_TYPE_I8, arg.num.value.i8); + } + case VM_TAG_I16: { + return tb_inst_sint(fun, TB_TYPE_I16, arg.num.value.i16); + } + case VM_TAG_I32: { + return tb_inst_sint(fun, TB_TYPE_I32, arg.num.value.i32); + } + case VM_TAG_I64: { + return tb_inst_sint(fun, TB_TYPE_I64, arg.num.value.i64); + } + case VM_TAG_F32: { + return tb_inst_float32(fun, arg.num.value.f32); + } + case VM_TAG_F64: { + return tb_inst_float64(fun, arg.num.value.f64); + } + default: { + __builtin_trap(); + } + } } case VM_ARG_REG: { if (regs[arg.reg] == NULL) { @@ -153,17 +173,6 @@ TB_Node *vm_tb_func_body(vm_tb_state_t *state, TB_Function *fun, TB_Node **args, tb_inst_ret(fun, 0, NULL); } else { - TB_Node *global_addr = tb_inst_uint(fun, TB_TYPE_PTR, (uint64_t) &rblock->cache); - TB_Node *global = tb_inst_load( fun, TB_TYPE_PTR, global_addr, 1, false); - TB_Node *cond = tb_inst_cmp_eq(fun, global, tb_inst_uint(fun, TB_TYPE_PTR, 0)); - - TB_Node *has_global = tb_inst_region(fun); - TB_Node *no_global = tb_inst_region(fun); - - tb_inst_if(fun, cond, no_global, has_global); - - tb_inst_set_control(fun, no_global); - TB_PrototypeParam comp_args[2] = { {TB_TYPE_PTR}, {TB_TYPE_PTR}, @@ -177,9 +186,9 @@ TB_Node *vm_tb_func_body(vm_tb_state_t *state, TB_Function *fun, TB_Node **args, TB_Node *comp_params[2]; - GC_add_roots(rblock, rblock + 1); - comp_params[0] = tb_inst_uint(fun, TB_TYPE_PTR, (uint64_t)state); + + GC_add_roots(rblock, rblock + 1); comp_params[1] = tb_inst_uint(fun, TB_TYPE_PTR, (uint64_t)rblock); TB_MultiOutput multi = tb_inst_call( @@ -189,69 +198,34 @@ TB_Node *vm_tb_func_body(vm_tb_state_t *state, TB_Function *fun, TB_Node **args, 2, comp_params); - { - TB_PrototypeParam *call_params = vm_malloc(sizeof(TB_PrototypeParam) * (rblock->block->nargs + 1)); - - call_params[0] = (TB_PrototypeParam){TB_TYPE_PTR}; - - for (size_t arg = 0; arg < rblock->block->nargs; arg++) { - call_params[arg + 1] = (TB_PrototypeParam){ - vm_tb_func_tag(fun, rblock->regs->tags[rblock->block->args[arg].reg]), - }; - } - - TB_FunctionPrototype *call_proto = tb_prototype_create(state->module, VM_TB_CC, rblock->block->nargs + 1, call_params, 0, NULL, false); - - TB_Node **call_args = vm_malloc(sizeof(TB_Node *) * (rblock->block->nargs + 1)); - - call_args[0] = tb_inst_param(fun, 0); - - for (size_t i = 0; i < rblock->block->nargs; i++) { - call_args[i + 1] = args[i]; - } + TB_PrototypeParam *call_params = vm_malloc(sizeof(TB_PrototypeParam) * (rblock->block->nargs + 1)); - tb_inst_call( - fun, - call_proto, - multi.single, - rblock->block->nargs + 1, - call_args); + call_params[0] = (TB_PrototypeParam){TB_TYPE_PTR}; - tb_inst_ret(fun, 0, NULL); + for (size_t arg = 0; arg < rblock->block->nargs; arg++) { + call_params[arg + 1] = (TB_PrototypeParam){ + vm_tb_func_tag(fun, rblock->regs->tags[rblock->block->args[arg].reg]), + }; } - tb_inst_set_control(fun, has_global); - - { - TB_PrototypeParam *call_params = vm_malloc(sizeof(TB_PrototypeParam) * (rblock->block->nargs + 1)); - - call_params[0] = (TB_PrototypeParam){TB_TYPE_PTR}; - - for (size_t arg = 0; arg < rblock->block->nargs; arg++) { - call_params[arg + 1] = (TB_PrototypeParam){ - vm_tb_func_tag(fun, rblock->regs->tags[rblock->block->args[arg].reg]), - }; - } + TB_FunctionPrototype *call_proto = tb_prototype_create(state->module, VM_TB_CC, rblock->block->nargs + 1, call_params, 0, NULL, false); - TB_FunctionPrototype *call_proto = tb_prototype_create(state->module, VM_TB_CC, rblock->block->nargs + 1, call_params, 0, NULL, false); + TB_Node **call_args = vm_malloc(sizeof(TB_Node *) * (rblock->block->nargs + 1)); - TB_Node **call_args = vm_malloc(sizeof(TB_Node *) * (rblock->block->nargs + 1)); + call_args[0] = tb_inst_param(fun, 0); - call_args[0] = tb_inst_param(fun, 0); + for (size_t i = 0; i < rblock->block->nargs; i++) { + call_args[i + 1] = args[i]; + } - for (size_t i = 0; i < rblock->block->nargs; i++) { - call_args[i + 1] = args[i]; - } - - tb_inst_call( - fun, - call_proto, - global, - rblock->block->nargs + 1, - call_args); + tb_inst_call( + fun, + call_proto, + multi.single, + rblock->block->nargs + 1, + call_args); - tb_inst_ret(fun, 0, NULL); - } + tb_inst_ret(fun, 0, NULL); } tb_inst_set_control(fun, ctrl); @@ -711,13 +685,33 @@ void vm_tb_print(uint32_t tag, void *value) { .tag = tag, }; switch (tag) { - case VM_TAG_F64: { - val.value.f64 = *(double *)value; - if (fabs(val.value.f64) > 100000000000000000000000000000000000.0) { + case VM_TAG_I8: { + val.value.i8 = *(int8_t *)value; + break; + } + case VM_TAG_I16: { + val.value.i16 = *(int16_t *)value; + break; + } + case VM_TAG_I32: { + val.value.i32 = *(int32_t *)value; + break; + } + case VM_TAG_I64: { + val.value.i64 = *(int64_t *)value; + if (val.value.i64 > 100) { __builtin_trap(); } break; } + case VM_TAG_F32: { + val.value.f32 = *(float *)value; + break; + } + case VM_TAG_F64: { + val.value.f64 = *(double *)value; + break; + } case VM_TAG_STR: { val.value.str = *(const char **)value; break; @@ -772,7 +766,7 @@ void vm_tb_func_print_value(vm_tb_state_t *state, TB_Function *fun, vm_tag_t tag void *vm_tb_rfunc_comp(vm_tb_state_t *state, vm_rblock_t *rblock) { void *test = rblock->cache; - printf("%p [cache = %p]\n", rblock, test); + // printf("%p [cache = %p]\n", rblock, test); if (test != NULL) { return test; } @@ -817,7 +811,7 @@ void *vm_tb_rfunc_comp(vm_tb_state_t *state, vm_rblock_t *rblock) { for (size_t i = 0; i < block->nargs; i++) { regs[block->args[i].reg] = args[i]; - vm_tb_func_print_value(state, fun, rblock->regs->tags[block->args[i].reg], args[i]); + // vm_tb_func_print_value(state, fun, rblock->regs->tags[block->args[i].reg], args[i]); } TB_Node *main = vm_tb_func_body_once(state, fun, regs, block); @@ -830,7 +824,7 @@ void *vm_tb_rfunc_comp(vm_tb_state_t *state, vm_rblock_t *rblock) { tb_pass_print(passes); fflush(stdout); #endif - // tb_pass_optimize(passes); + tb_pass_optimize(passes); #if defined(VM_DUMP_TB_OPT) fprintf(stdout, "\n--- opt tb ---\n"); tb_pass_print(passes); diff --git a/vm/ir.c b/vm/ir.c index 82ec3306..575281be 100644 --- a/vm/ir.c +++ b/vm/ir.c @@ -256,10 +256,6 @@ void vm_print_instr(FILE *out, vm_instr_t val) { fprintf(out, "std"); break; } - case VM_IOP_TYPE: { - fprintf(out, "type"); - break; - } case VM_IOP_LEN: { fprintf(out, "len"); break; diff --git a/vm/ir.h b/vm/ir.h index fad53774..d7531fac 100644 --- a/vm/ir.h +++ b/vm/ir.h @@ -66,8 +66,6 @@ enum { VM_IOP_LEN, // objects VM_IOP_STD, - // intro - VM_IOP_TYPE, }; struct vm_rblock_t { diff --git a/vm/lang/paka.c b/vm/lang/paka.c index 6a98c563..f7a84b82 100644 --- a/vm/lang/paka.c +++ b/vm/lang/paka.c @@ -406,26 +406,6 @@ redo:; arg = out; goto redo; } - if (vm_paka_parser_match(parser, "::")) { - vm_paka_parser_strip_spaces(parser); - if (vm_paka_parser_match_keyword(parser, "type")) { - vm_arg_t out = (vm_arg_t){ - .type = VM_ARG_REG, - .reg = vm_paka_find_reg(comp->regs), - }; - vm_instr_t instr = (vm_instr_t){ - .op = VM_IOP_TYPE, - .out = out, - .args[0] = arg, - }; - vm_block_realloc(comp->write, instr); - arg = out; - goto redo; - } - return (vm_arg_t){ - .type = VM_ARG_UNK, - }; - } if (vm_paka_parser_match(parser, ".")) { vm_paka_parser_strip_spaces(parser); vm_block_t *next = vm_paka_blocks_new(comp->blocks); @@ -601,8 +581,8 @@ vm_arg_t vm_paka_parser_expr_single(vm_paka_parser_t *parser, } return (vm_arg_t){ .type = VM_ARG_NUM, - .num.tag = VM_TAG_F64, - .num.value.f64 = n, + .num.tag = VM_LANG_PAKA_NUM_TAG, + .num.value.VM_LANG_PAKA_NUM_FIELD = n, }; } } @@ -691,8 +671,8 @@ vm_arg_t vm_paka_parser_expr_single(vm_paka_parser_t *parser, .args[0] = (vm_arg_t){ .type = VM_ARG_NIL, - .num.tag = VM_TAG_F64, - .num.value.f64 = 0, + .num.tag = VM_LANG_PAKA_NUM_TAG, + .num.value.VM_LANG_PAKA_NUM_FIELD = 0, }, }; comp->names = last_names; diff --git a/vm/lang/paka.h b/vm/lang/paka.h index ed6ac974..75aae130 100644 --- a/vm/lang/paka.h +++ b/vm/lang/paka.h @@ -89,4 +89,7 @@ vm_paka_parser_block_full_t vm_paka_parser_block_full(vm_paka_parser_t *parser, vm_block_t *vm_paka_parse(const char *src); vm_paka_blocks_t vm_paka_parse_blocks(const char *src); +#define VM_LANG_PAKA_NUM_TAG VM_TAG_I64 +#define VM_LANG_PAKA_NUM_FIELD i64 + #endif diff --git a/vm/obj.c b/vm/obj.c index fd2cf274..1c506980 100644 --- a/vm/obj.c +++ b/vm/obj.c @@ -1,8 +1,178 @@ #include "./obj.h" -#include "./ir.h" +#include + +#include "./ir.h" #include "./std/libs/io.h" + +bool vm_value_eq(vm_std_value_t lhs, vm_std_value_t rhs) { + switch (lhs.tag) { + case VM_TAG_NIL: { + return rhs.tag == VM_TAG_NIL; + } + case VM_TAG_BOOL: { + return rhs.tag == VM_TAG_BOOL && lhs.value.b == rhs.value.b; + } + case VM_TAG_I8: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.i8 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.i8 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.i8 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.i8 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.i8 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.i8 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_I16: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.i16 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.i16 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.i16 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.i16 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.i16 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.i16 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_I32: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.i32 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.i32 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.i32 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.i32 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.i32 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.i32 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_I64: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.i64 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.i64 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.i64 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.i64 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.i64 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.i64 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_F32: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.f32 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.f32 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.f32 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.f32 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.f32 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.f32 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_F64: { + switch (rhs.tag) { + case VM_TAG_I8: { + return lhs.value.f64 == rhs.value.i8; + } + case VM_TAG_I16: { + return lhs.value.f64 == rhs.value.i16; + } + case VM_TAG_I32: { + return lhs.value.f64 == rhs.value.i32; + } + case VM_TAG_I64: { + return lhs.value.f64 == rhs.value.i64; + } + case VM_TAG_F32: { + return lhs.value.f64 == rhs.value.f32; + } + case VM_TAG_F64: { + return lhs.value.f64 == rhs.value.f64; + } + default: { + return false; + } + } + } + case VM_TAG_STR: { + return rhs.tag == VM_TAG_STR && !strcmp(lhs.value.str, rhs.value.str); + } + default: { + return lhs.tag == rhs.tag && lhs.value.all == rhs.value.all; + } + } +} + vm_table_t *vm_table_new(void) { vm_table_t *ret = vm_malloc(sizeof(vm_table_t)); *ret = (vm_table_t){0}; @@ -11,38 +181,15 @@ vm_table_t *vm_table_new(void) { static vm_pair_t *vm_table_lookup(vm_table_t *table, vm_value_t key_val, uint32_t key_tag) { uint32_t head = 0; + vm_std_value_t lhs = (vm_std_value_t) { + .tag = key_tag, + .value = key_val, + }; while (head * sizeof(vm_pair_t) < table->nbytes) { vm_pair_t *pair = &table->pairs[head]; - if (pair->key_tag == key_tag) { - switch (key_tag) { - case VM_TAG_NIL: { - return pair; - } - case VM_TAG_BOOL: { - if (pair->key_val.b == key_val.b) { - return pair; - } - break; - } - case VM_TAG_F64: { - if (pair->key_val.f64 == key_val.f64) { - return pair; - } - break; - } - case VM_TAG_STR: { - if (!strcmp(pair->key_val.str, key_val.str)) { - return pair; - } - break; - } - default: { - if (pair->key_val.all == key_val.all) { - return pair; - } - break; - } - } + vm_std_value_t rhs = (vm_std_value_t){.tag = pair->key_tag, .value = pair->key_val}; + if (vm_value_eq(lhs, rhs)) { + return pair; } head += 1; } @@ -79,7 +226,7 @@ void vm_table_set_pair(vm_table_t *table, vm_pair_t *pair) { vm_pair_t *vm_table_get_pair(vm_table_t *table, vm_pair_t *out) { vm_value_t key_val = out->key_val; - vm_tag_t key_tag = (vm_tag_t) out->key_tag; + vm_tag_t key_tag = (vm_tag_t)out->key_tag; vm_pair_t *pair = vm_table_lookup(table, key_val, key_tag); if (pair != NULL) { out->val_val = pair->val_val; diff --git a/vm/obj.h b/vm/obj.h index f8cbb128..f119e800 100644 --- a/vm/obj.h +++ b/vm/obj.h @@ -13,6 +13,9 @@ typedef struct vm_pair_t vm_pair_t; struct vm_table_t; typedef struct vm_table_t vm_table_t; +struct vm_std_value_t; +typedef struct vm_std_value_t vm_std_value_t; + union vm_value_t { bool b; int8_t i8; @@ -26,6 +29,11 @@ union vm_value_t { void *all; }; +struct vm_std_value_t { + vm_value_t value; + uint32_t tag; +}; + struct vm_pair_t { // uint8_t buf[256-24]; vm_value_t key_val; @@ -40,6 +48,8 @@ struct vm_table_t { uint8_t alloc; }; +bool vm_value_eq(vm_std_value_t lhs, vm_std_value_t rhs); + vm_table_t *vm_table_new(void); void vm_table_set(vm_table_t *table, vm_value_t key_val, vm_value_t val_val, uint32_t key_tag, uint32_t val_tag); diff --git a/vm/rblock.c b/vm/rblock.c index 76154dec..64685b3e 100644 --- a/vm/rblock.c +++ b/vm/rblock.c @@ -38,7 +38,7 @@ vm_block_t *vm_rblock_version(vm_rblock_t *rblock) { } else if (instr.args[1].type == VM_ARG_NUM) { instr.args[3] = (vm_arg_t){ .type = VM_ARG_TAG, - .tag = VM_TAG_F64, + .tag = instr.args[1].num.tag, }; } if (instr.args[2].type == VM_ARG_REG) { @@ -49,7 +49,7 @@ vm_block_t *vm_rblock_version(vm_rblock_t *rblock) { } else if (instr.args[2].type == VM_ARG_NUM) { instr.args[4] = (vm_arg_t){ .type = VM_ARG_TAG, - .tag = VM_TAG_F64, + .tag = instr.args[1].num.tag, }; } } @@ -69,7 +69,7 @@ vm_block_t *vm_rblock_version(vm_rblock_t *rblock) { if (branch.args[1].type == VM_ARG_REG) { branch.tag = regs->tags[branch.args[1].reg]; } else if (branch.args[1].type == VM_ARG_NUM) { - branch.tag = VM_TAG_F64; + branch.tag = branch.args[1].num.tag; } if (branch.args[1].type == VM_ARG_REG) { branch.args[3] = (vm_arg_t){ @@ -79,7 +79,7 @@ vm_block_t *vm_rblock_version(vm_rblock_t *rblock) { } else if (branch.args[1].type == VM_ARG_NUM) { branch.args[3] = (vm_arg_t){ .type = VM_ARG_TAG, - .tag = VM_TAG_F64, + .tag = branch.args[1].num.tag, }; } vm_block_t *from = branch.targets[0]; diff --git a/vm/std/std.h b/vm/std/std.h index 3c4f09fb..a6944389 100644 --- a/vm/std/std.h +++ b/vm/std/std.h @@ -3,14 +3,6 @@ #include "../obj.h" -struct vm_std_value_t; -typedef struct vm_std_value_t vm_std_value_t; - -struct vm_std_value_t { - vm_value_t value; - uint32_t tag; -}; - vm_table_t *vm_std_new(void); #endif diff --git a/vm/type.c b/vm/type.c index dccbb764..2ec04d38 100644 --- a/vm/type.c +++ b/vm/type.c @@ -94,33 +94,6 @@ vm_instr_t vm_rblock_type_specialize_instr(vm_tags_t *types, vm_instr_t instr) { instr.tag = VM_TAG_TAB; return instr; } - if (instr.op == VM_IOP_TYPE) { - vm_tag_t tag = VM_TAG_NIL; - if (instr.args[0].type == VM_ARG_NIL) { - tag = VM_TAG_NIL; - } - if (instr.args[0].type == VM_ARG_BOOL) { - tag = VM_TAG_BOOL; - } - if (instr.args[0].type == VM_ARG_NUM) { - tag = VM_TAG_F64; - } - if (instr.args[0].type == VM_ARG_STR) { - tag = VM_TAG_STR; - } - if (instr.args[0].type == VM_ARG_REG) { - tag = types->tags[instr.args[0].reg]; - } - return (vm_instr_t){ - .op = VM_IOP_MOVE, - .out = instr.out, - .tag = VM_TAG_F64, - .args[0] = (vm_arg_t){ - .type = VM_ARG_NUM, - .num.tag = VM_TAG_F64, - .num.value.f64 = tag, - }}; - } if (instr.op == VM_IOP_MOVE) { if (instr.args[0].type == VM_ARG_STR) { instr.tag = VM_TAG_STR; @@ -148,7 +121,7 @@ vm_instr_t vm_rblock_type_specialize_instr(vm_tags_t *types, vm_instr_t instr) { } for (size_t i = 0; instr.args[i].type != VM_ARG_NONE; i++) { if (instr.args[i].type == VM_ARG_NUM) { - instr.tag = VM_TAG_F64; + instr.tag = instr.args[i].num.tag; return instr; } } @@ -176,7 +149,7 @@ vm_branch_t vm_rblock_type_specialize_branch(vm_tags_t *types, } for (size_t i = 0; i < 2; i++) { if (branch.args[i].type == VM_ARG_NUM) { - branch.tag = VM_TAG_F64; + branch.tag = branch.args[i].num.tag; return branch; } }