diff --git a/main/minivm.c b/main/minivm.c index 134d480..2c99e01 100644 --- a/main/minivm.c +++ b/main/minivm.c @@ -1,5 +1,5 @@ #include "../vm/backend/backend.h" -#include "../vm/vm.h" +#include "../vm/obj.h" #include "../vm/ir.h" #include "../vm/io.h" #include "../vm/std.h" diff --git a/main/primes.py b/main/primes.py index 0b2fcc4..01fa5a0 100644 --- a/main/primes.py +++ b/main/primes.py @@ -26,7 +26,7 @@ if i % n == n - 1: f.write('\n ') f.write('\n};\n\n') - f.write('static uint32_t vm_primes_mod(uint8_t p, uint32_t n) {\n') + f.write('static inline uint32_t vm_primes_mod(uint8_t p, uint32_t n) {\n') f.write(' switch (p) {\n') f.write(' default:\n') f.write(' __builtin_unreachable();\n') diff --git a/makefile b/makefile index e95883c..66bb9ee 100644 --- a/makefile +++ b/makefile @@ -22,7 +22,7 @@ BASE_LDFLAGS := ${OPT} ${LDFLAGS} ${LIBM_FLAGS} # object files and depends MAIN_SRCS = main/minivm.c VM_SRCS := $(shell find vm | grep \\.c) -MI_SRCS := vendor/mimalloc/src/prim/prim.c vendor/mimalloc/src/alloc-posix.c vendor/mimalloc/src/alloc-aligned.c vendor/mimalloc/src/alloc.c vendor/mimalloc/src/arena.c vendor/mimalloc/src/bitmap.c vendor/mimalloc/src/heap.c vendor/mimalloc/src/init.c vendor/mimalloc/src/libc.c vendor/mimalloc/src/options.c vendor/mimalloc/src/os.c vendor/mimalloc/src/page.c vendor/mimalloc/src/random.c vendor/mimalloc/src/segment-map.c vendor/mimalloc/src/segment.c vendor/mimalloc/src/stats.c +# MI_SRCS := vendor/mimalloc/src/prim/prim.c vendor/mimalloc/src/alloc-posix.c vendor/mimalloc/src/alloc-aligned.c vendor/mimalloc/src/alloc.c vendor/mimalloc/src/arena.c vendor/mimalloc/src/bitmap.c vendor/mimalloc/src/heap.c vendor/mimalloc/src/init.c vendor/mimalloc/src/libc.c vendor/mimalloc/src/options.c vendor/mimalloc/src/os.c vendor/mimalloc/src/page.c vendor/mimalloc/src/random.c vendor/mimalloc/src/segment-map.c vendor/mimalloc/src/segment.c vendor/mimalloc/src/stats.c TS_SRCS += vendor/tree-sitter/lib/src/alloc.c vendor/tree-sitter/lib/src/get_changed_ranges.c vendor/tree-sitter/lib/src/language.c vendor/tree-sitter/lib/src/lexer.c vendor/tree-sitter/lib/src/node.c vendor/tree-sitter/lib/src/parser.c vendor/tree-sitter/lib/src/query.c vendor/tree-sitter/lib/src/stack.c vendor/tree-sitter/lib/src/subtree.c vendor/tree-sitter/lib/src/tree_cursor.c vendor/tree-sitter/lib/src/tree.c vendor/tree-sitter/lib/src/wasm_store.c IC_SRCS := vendor/isocline/src/isocline.c MAIN_SRCS += ${VM_SRCS} ${TS_SRCS} ${IC_SRCS} ${MI_SRCS} @@ -50,12 +50,12 @@ clean: .dummy rm -rf build gcc-pgo: .dummy - $(MAKE) -Bj minivm OPT="$(OPT) -fgcse-sm -fgcse-las -fipa-pta -fdevirtualize-at-ltrans -fdevirtualize-speculatively -fno-exceptions -fomit-frame-pointer -fprofile-generate" + $(MAKE) -Bj minivm OPT="-g3 $(OPT) -fprofile-generate" build/bin/minivm test/lua/fib/fib.lua build/bin/minivm test/lua/tables/trees.lua build/bin/minivm test/lua/closure/funcret.lua build/bin/minivm test/lang/lr1.lua - $(MAKE) -Bj minivm OPT="$(OPT) -fgcse-sm -fgcse-las -fipa-pta -fdevirtualize-at-ltrans -fdevirtualize-speculatively -fno-exceptions -fomit-frame-pointer -fprofile-use" + $(MAKE) -Bj minivm OPT="$(OPT) -fgcse-sm -fgcse-las -fipa-pta -fomit-frame-pointer -fno-reorder-functions -fprofile-use" clang-pgo: .dummy $(MAKE) -Bj minivm OPT="$(OPT) -mllvm -polly -fno-exceptions -fprofile-instr-generate" diff --git a/vm/ast/ast.c b/vm/ast/ast.c index c789a23..fe34f6a 100644 --- a/vm/ast/ast.c +++ b/vm/ast/ast.c @@ -1,4 +1,5 @@ #include "ast.h" +#include "../lib.h" void vm_ast_free_form(vm_ast_form_t form) { for (size_t i = 0; i < form.len; i++) { diff --git a/vm/ast/ast.h b/vm/ast/ast.h index b88215e..90fbf09 100644 --- a/vm/ast/ast.h +++ b/vm/ast/ast.h @@ -1,8 +1,6 @@ #if !defined(VM_HEADER_AST_AST) #define VM_HEADER_AST_AST -#include "../lib.h" -#include "../obj.h" #include "../errors.h" struct vm_ast_form_t; diff --git a/vm/ast/build.c b/vm/ast/build.c index 532094d..3ae610a 100644 --- a/vm/ast/build.c +++ b/vm/ast/build.c @@ -1,6 +1,8 @@ #include #include "build.h" +#include "../lib.h" +#include "../obj.h" #define VM_MACRO_SELECT(_0, _1, _2, NAME, ...) NAME #define vm_ast_form(TYPE_, ...) \ diff --git a/vm/ast/build.h b/vm/ast/build.h index 3b29069..411c5bf 100644 --- a/vm/ast/build.h +++ b/vm/ast/build.h @@ -3,6 +3,7 @@ #define VM_HEADER_LANG_BUILD #include "ast.h" +#include "../vm.h" vm_ast_node_t vm_ast_build_empty(vm_ast_node_t lhs, vm_ast_node_t rhs); // blocks diff --git a/vm/ast/comp.c b/vm/ast/comp.c index 8749534..7b416c8 100644 --- a/vm/ast/comp.c +++ b/vm/ast/comp.c @@ -7,6 +7,8 @@ #include "../ir.h" #include "../gc.h" #include "../errors.h" +#include "../lib.h" +#include "../obj.h" struct vm_ast_comp_t; typedef struct vm_ast_comp_t vm_ast_comp_t; diff --git a/vm/ast/comp.h b/vm/ast/comp.h index b3fa1c0..4f5c83a 100644 --- a/vm/ast/comp.h +++ b/vm/ast/comp.h @@ -3,7 +3,6 @@ #define VM_HEADER_AST_COMP #include "ast.h" -#include "../ir.h" vm_ir_block_t *vm_ast_comp_more(vm_t *vm, vm_ast_node_t node); diff --git a/vm/backend/backend.c b/vm/backend/backend.c index 0613384..e451488 100644 --- a/vm/backend/backend.c +++ b/vm/backend/backend.c @@ -6,14 +6,13 @@ #include "../gc.h" #include "../ir.h" #include "../obj.h" -#include "../vm.h" +#include "../tables.h" #include "../math.h" #include "../io.h" #define VM_INLINE inline #if VM_USE_SPALL_INSTR - #include "../../vendor/spall/auto.h" #define VM_OPCODE_SPALL_BEGIN(s) ({ \ @@ -182,7 +181,7 @@ static VM_INLINE vm_obj_t vm_interp_pow(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { } static VM_INLINE vm_obj_t vm_interp_concat(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { - if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { + if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { vm_io_buffer_t *buf = vm_io_buffer_new(); vm_io_buffer_object_tostring(buf, v1); vm_io_buffer_object_tostring(buf, v2); diff --git a/vm/gc.c b/vm/gc.c index a12b25a..94a0850 100644 --- a/vm/gc.c +++ b/vm/gc.c @@ -1,7 +1,10 @@ #include "gc.h" +#include "obj.h" #include "ir.h" #include "lib.h" +#include "tables.h" + #include struct vm_gc_objs_t; @@ -81,8 +84,8 @@ static inline void vm_gc_mark_block(vm_ir_block_t *restrict block) { static inline void vm_gc_mark_obj(vm_obj_t obj) { - if (vm_obj_is_string(obj)) { - vm_io_buffer_t *buffer = vm_obj_get_string(obj); + if (vm_obj_is_buffer(obj)) { + vm_io_buffer_t *buffer = vm_obj_get_buffer(obj); buffer->mark = true; } else if (vm_obj_is_table(obj)) { vm_obj_table_t *restrict table = vm_obj_get_table(obj); @@ -112,7 +115,7 @@ void vm_gc_mark(vm_t *vm, vm_obj_t *top) { vm_gc_mark_block(blocks->block); } vm_gc_mark_obj(vm->std); - for (vm_obj_t *head = vm->base; head < top; head++) { + for (vm_obj_t *head = vm->base; head <= top; head++) { vm_gc_mark_obj(*head); } } @@ -128,8 +131,8 @@ void vm_gc_sweep(vm_t *vm) { #endif for (size_t i = 0; i < gc->objs.len; i++) { vm_obj_t obj = gc->objs.objs[i]; - if (vm_obj_is_string(obj)) { - vm_io_buffer_t *buffer = vm_obj_get_string(obj); + if (vm_obj_is_buffer(obj)) { + vm_io_buffer_t *buffer = vm_obj_get_buffer(obj); if (!buffer->mark) { vm_free(buffer->buf); vm_free(buffer); @@ -246,7 +249,7 @@ void vm_gc_add(vm_t *vm, vm_obj_t obj) { vm_gc_t *restrict gc = vm->gc; vm_gc_objs_add(&gc->objs, obj); #if VM_GC_STATS - if (vm_obj_is_string(obj)) { + if (vm_obj_is_buffer(obj)) { gc->stats.by_type.string.count += 1; } else if (vm_obj_is_table(obj)) { gc->stats.by_type.table.count += 1; diff --git a/vm/io.c b/vm/io.c index 258d48a..d204ac9 100644 --- a/vm/io.c +++ b/vm/io.c @@ -2,6 +2,8 @@ #include "io.h" #include "math.h" #include "lib.h" +#include "obj.h" +#include "tables.h" #include @@ -105,8 +107,8 @@ void vm_io_buffer_print_lit(vm_io_buffer_t *out, vm_obj_t value) { vm_io_buffer_format(out, VM_FORMAT_FLOAT, vm_obj_get_number(value)); } else if (vm_obj_is_ffi(value)) { vm_io_buffer_format(out, "", vm_obj_get_ffi(value)); - } else if (vm_obj_is_string(value)) { - vm_io_buffer_format(out, "\"%s\"", vm_obj_get_string(value)->buf); + } else if (vm_obj_is_buffer(value)) { + vm_io_buffer_format(out, "\"%s\"", vm_obj_get_buffer(value)->buf); } else if (vm_obj_is_table(value)) { vm_io_buffer_format(out, "", vm_obj_get_table(value)); } else if (vm_obj_is_closure(value)) { @@ -147,9 +149,9 @@ void vm_io_buffer_obj_debug(vm_io_buffer_t *out, size_t indent, const char *pref vm_io_indent(out, indent, prefix); vm_io_buffer_format(out, VM_FORMAT_FLOAT "\n", vm_obj_get_number(value)); } - if (vm_obj_is_string(value)) { + if (vm_obj_is_buffer(value)) { vm_io_indent(out, indent, prefix); - vm_io_buffer_format(out, "\"%s\"\n", vm_obj_get_string(value)->buf); + vm_io_buffer_format(out, "\"%s\"\n", vm_obj_get_buffer(value)->buf); } if (vm_obj_is_closure(value)) { vm_io_indent(out, indent, prefix); @@ -183,9 +185,9 @@ void vm_io_buffer_obj_debug(vm_io_buffer_t *out, size_t indent, const char *pref snprintf(buf, 63, "[[" VM_FORMAT_FLOAT "]] = ", vm_obj_get_number(key)); vm_io_buffer_obj_debug(out, indent + 1, buf, tab->entries[vm_primes_table[tab->size] + i], &next); } - else if (vm_obj_is_string(key)) { + else if (vm_obj_is_buffer(key)) { vm_io_buffer_t *buf = vm_io_buffer_new(); - vm_io_buffer_format(buf, "%s = ", vm_obj_get_string(key)->buf); + vm_io_buffer_format(buf, "%s = ", vm_obj_get_buffer(key)->buf); vm_io_buffer_obj_debug(out, indent + 1, buf->buf, tab->entries[vm_primes_table[tab->size] + i], &next); vm_free(buf->buf); vm_free(buf); @@ -218,8 +220,8 @@ void vm_io_buffer_object_tostring(vm_io_buffer_t *buf, vm_obj_t value) { if (vm_obj_is_number(value)) { vm_io_buffer_format(buf, VM_FORMAT_FLOAT, vm_obj_get_number(value)); } - if (vm_obj_is_string(value)) { - vm_io_buffer_format(buf, "%s", vm_obj_get_string(value)->buf); + if (vm_obj_is_buffer(value)) { + vm_io_buffer_format(buf, "%s", vm_obj_get_buffer(value)->buf); } if (vm_obj_is_closure(value)) { vm_io_buffer_format(buf, "", vm_obj_get_closure(value)); diff --git a/vm/lib.c b/vm/lib.c index 06dbeab..d0db4d0 100644 --- a/vm/lib.c +++ b/vm/lib.c @@ -1,5 +1,7 @@ #include "vm.h" +#include "lib.h" +#include #if VM_MALLOC_MI #include "../vendor/mimalloc/include/mimalloc.h" @@ -29,22 +31,42 @@ char *vm_strdup(const char *x) { #include void *vm_malloc(size_t x) { - return malloc(x); + if (x == 0) { + return NULL; + } + void *ret = malloc(x); + assert(ret != NULL); + return ret; } void *vm_calloc(size_t x) { - return calloc(x, 1); + if (x == 0) { + return NULL; + } + void *ret = calloc(x, 1); + assert(ret != NULL); + return ret; } void *vm_realloc(void *x, size_t y) { - return realloc(x, y); + if (y == 0) { + vm_free(x); + } + void *ret = realloc(x, y); + assert(ret != NULL); + return ret; } void vm_free(const void *x) { - free((void *) (x)); + if (x != NULL) { + free((void *) (x)); + } } char *vm_strdup(const char *x) { - return strdup(x); + assert(x != NULL); + char *ret = strdup(x); + assert(ret != NULL); + return ret; } #endif \ No newline at end of file diff --git a/vm/lib.h b/vm/lib.h index ed65a62..dc3ce72 100644 --- a/vm/lib.h +++ b/vm/lib.h @@ -14,5 +14,4 @@ void *vm_realloc(void *ptr, size_t size); void vm_free(const void *ptr); char *vm_strdup(const char *str); - #endif diff --git a/vm/lua/ast.c b/vm/lua/ast.c index ff7a86c..13e0f81 100644 --- a/vm/lua/ast.c +++ b/vm/lua/ast.c @@ -1,10 +1,12 @@ -#include "../ast/ast.h" #include "../../vendor/tree-sitter/lib/include/tree_sitter/api.h" #include "../ast/build.h" #include "../ast/comp.h" #include "../io.h" #include "../ir.h" +#include "../lib.h" +#include "../obj.h" +#include "../tables.h" const TSLanguage *tree_sitter_lua(void); diff --git a/vm/lua/repl.c b/vm/lua/repl.c index b501abe..3fdaaa9 100644 --- a/vm/lua/repl.c +++ b/vm/lua/repl.c @@ -5,6 +5,9 @@ #include "../ir.h" #include "../io.h" #include "../vm.h" +#include "../lib.h" +#include "../obj.h" +#include "../tables.h" #include "../ast/ast.h" #include "../backend/backend.h" @@ -33,7 +36,7 @@ with_new_std:; for (size_t i = 0; i < len; i++) { vm_obj_t std_key = std->entries[i]; if (vm_obj_is_table(std_key)) { - const char *got = vm_obj_get_string(std_key)->buf; + const char *got = vm_obj_get_buffer(std_key)->buf; size_t i = 0; while (got[i] != '\0') { if (last_word[i] == '\0') { diff --git a/vm/math.c b/vm/math.c index 2b41fa6..9a50eac 100644 --- a/vm/math.c +++ b/vm/math.c @@ -1,5 +1,6 @@ #include "math.h" +#include "obj.h" #include "errors.h" bool vm_obj_unsafe_eq(vm_obj_t v1, vm_obj_t v2) { @@ -9,8 +10,8 @@ bool vm_obj_unsafe_eq(vm_obj_t v1, vm_obj_t v2) { return vm_obj_get_boolean(v1) == vm_obj_get_boolean(v2); } else if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_get_number(v1) == vm_obj_get_number(v2); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) == 0; + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) == 0; } else if (vm_obj_is_table(v1) && vm_obj_is_table(v2)) { return vm_obj_get_table(v1) == vm_obj_get_table(v2); } else if (vm_obj_is_closure(v1) && vm_obj_is_closure(v2)) { @@ -25,8 +26,8 @@ bool vm_obj_unsafe_eq(vm_obj_t v1, vm_obj_t v2) { bool vm_obj_unsafe_lt(vm_obj_t v1, vm_obj_t v2) { if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_get_number(v1) < vm_obj_get_number(v2); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) < 0; + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) < 0; } else { return false; } @@ -35,22 +36,23 @@ bool vm_obj_unsafe_lt(vm_obj_t v1, vm_obj_t v2) { bool vm_obj_unsafe_le(vm_obj_t v1, vm_obj_t v2) { if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_get_number(v1) <= vm_obj_get_number(v2); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) <= 0; + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) <= 0; } else { return false; } } vm_obj_t vm_obj_eq(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { + (void) vm; if (vm_obj_is_nil(v1) && vm_obj_is_nil(v2)) { return vm_obj_of_boolean(true); } else if (vm_obj_is_boolean(v1) && vm_obj_is_boolean(v2)) { return vm_obj_of_boolean(vm_obj_get_boolean(v1) == vm_obj_get_boolean(v2)); } else if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_of_boolean(vm_obj_get_number(v1) == vm_obj_get_number(v2)); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return vm_obj_of_boolean(strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) == 0); + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return vm_obj_of_boolean(strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) == 0); } else if (vm_obj_is_table(v1) && vm_obj_is_table(v2)) { // TODO: use metamethod return vm_obj_of_boolean(vm_obj_get_table(v1) == vm_obj_get_table(v2)); @@ -64,20 +66,22 @@ vm_obj_t vm_obj_eq(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { } vm_obj_t vm_obj_lt(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { + (void) vm; if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_of_boolean(vm_obj_get_number(v1) < vm_obj_get_number(v2)); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return vm_obj_of_boolean(strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) < 0); + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return vm_obj_of_boolean(strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) < 0); } else { return vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "not comparable")); } } vm_obj_t vm_obj_le(vm_t *vm, vm_obj_t v1, vm_obj_t v2) { + (void) vm; if (vm_obj_is_number(v1) && vm_obj_is_number(v2)) { return vm_obj_of_boolean(vm_obj_get_number(v1) < vm_obj_get_number(v2)); - } else if (vm_obj_is_string(v1) && vm_obj_is_string(v2)) { - return vm_obj_of_boolean(strcmp(vm_obj_get_string(v1)->buf, vm_obj_get_string(v2)->buf) < 0); + } else if (vm_obj_is_buffer(v1) && vm_obj_is_buffer(v2)) { + return vm_obj_of_boolean(strcmp(vm_obj_get_buffer(v1)->buf, vm_obj_get_buffer(v2)->buf) < 0); } else { return vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "not comparable")); } diff --git a/vm/obj.c b/vm/obj.c index dbb16c4..d796f5e 100644 --- a/vm/obj.c +++ b/vm/obj.c @@ -1,142 +1,141 @@ - -#include - -#include "obj.h" -#include "gc.h" -#include "io.h" -#include "math.h" -#include "lib.h" - -vm_obj_t vm_obj_of_string(vm_t *vm, const char *str) { - vm_obj_t ret = vm_obj_of_buffer(vm_io_buffer_from_str(str)); - vm_gc_add(vm, ret); - return ret; -} - -uint32_t vm_obj_hash(vm_obj_t value) { - if (vm_obj_is_number(value)) { - double n = vm_obj_get_number(value); - if (n == floor(n) && INT32_MIN <= n && n <= INT32_MAX) { - return (uint32_t) (int32_t) n * 31; - } - return (uint32_t) (*(uint64_t *)&n >> 12) * 37; - } - if (vm_obj_is_string(value)) { - vm_io_buffer_t *restrict buf = vm_obj_get_string(value); - if (buf->hash == 0) { - uint32_t ret = 0x811c9dc5; - for (size_t i = 0; i < buf->len; i++) { - char c = buf->buf[i]; - if (c == '\0') { - break; - } - ret *= 0x01000193; - ret ^= c; - } - buf->hash = ret; - } - return buf->hash; - } - if (vm_obj_is_boolean(value)) { - return UINT32_MAX - (uint32_t)vm_obj_get_boolean(value); - } - if (vm_obj_is_ffi(value)) { - return (uint32_t)(size_t)vm_obj_get_ffi(value) >> 4; - } - if (vm_obj_is_closure(value)) { - return (uint32_t)(size_t)vm_obj_get_closure(value) >> 4; - } - if (vm_obj_is_table(value)) { - return (uint32_t)(size_t)vm_obj_get_table(value) >> 4; - } - return 0; -} - -vm_obj_t vm_table_get(vm_obj_table_t *table, vm_obj_t key) { - size_t len = vm_primes_table[table->size]; - size_t init_look = vm_primes_mod(table->size, vm_obj_hash(key)); - size_t look = init_look; - do { - vm_obj_t found_key = table->entries[look]; - if (vm_obj_is_nil(found_key)) { - return vm_obj_of_nil(); - } - if (vm_obj_unsafe_eq(key, found_key)) { - return table->entries[vm_primes_table[table->size] + look]; - } - look += 1; - if (look == len) { - look = 0; - } - } while (look != init_look); - - return vm_obj_of_nil(); -} - -void vm_table_set(vm_obj_table_t *restrict table, vm_obj_t key, vm_obj_t value) { - size_t len = vm_primes_table[table->size]; - size_t look = vm_primes_mod(table->size, vm_obj_hash(key)); - for (size_t i = 0; i < len; i++) { - vm_obj_t table_key = table->entries[look]; - if (vm_obj_is_nil(table_key)) { - break; - } - if (vm_obj_unsafe_eq(key, table_key)) { - if (vm_obj_is_nil(value)) { - if (vm_obj_is_number(key)) { - double f64val = vm_obj_get_number(key); - if (1 <= f64val && f64val <= table->len) { - int32_t i64val = (int32_t)f64val; - if ((double)i64val == f64val) { - table->len = i64val - 1; - } - } - } - table->entries[look] = value; - } - table->entries[vm_primes_table[table->size] + look] = value; - return; - } - look += 1; - if (look == len) { - look = 0; - } - } - if ((table->used) * 100u > vm_primes_table[table->size] * 75u) { - vm_obj_table_t ret; - ret.size = table->size + 1; - ret.used = 0; - ret.len = 0; - ret.mark = table->mark; -#if VM_EMPTY_BYTE == 0 - ret.entries = vm_calloc(sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); -#else - ret.entries = vm_malloc(sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); - memset(ret.entries, VM_EMPTY_BYTE, sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); -#endif - for (size_t i = 0; i < vm_primes_table[table->size]; i++) { - vm_obj_t in_key = table->entries[i]; - if (!vm_obj_is_nil(in_key)) { - vm_table_set(&ret, in_key, table->entries[vm_primes_table[table->size] + i]); - } - } - vm_table_set(&ret, key, value); - vm_free(table->entries); - *table = ret; - } else { - table->used += 1; - table->entries[look] = key; - table->entries[vm_primes_table[table->size] + look] = value; - int32_t next = table->len + 1; - if (vm_obj_is_number(key) && vm_obj_get_number(key) == next) { - while (true) { - vm_obj_t got = vm_table_get(table, vm_obj_of_number(next + 1)); - if (vm_obj_is_nil(got)) { - break; - } - next += 1; - } - table->len = next; - } - } -} + +#include + +#include "vm.h" +#include "io.h" +#include "gc.h" + +bool vm_obj_is_nil(vm_obj_t o) { + return nanbox_is_empty(o); +} +bool vm_obj_is_boolean(vm_obj_t o) { + return nanbox_is_boolean(o); +} +bool vm_obj_is_number(vm_obj_t o) { + return nanbox_is_number(o); +} +bool vm_obj_is_buffer(vm_obj_t o) { + return nanbox_is_aux1(o); +} +bool vm_obj_is_table(vm_obj_t o) { + return nanbox_is_aux2(o); +} +bool vm_obj_is_closure(vm_obj_t o) { + return nanbox_is_aux3(o); +} +bool vm_obj_is_ffi(vm_obj_t o) { + return nanbox_is_aux4(o); +} +bool vm_obj_is_block(vm_obj_t o) { + return nanbox_is_aux5(o); +} +bool vm_obj_is_error(vm_obj_t o) { + return nanbox_is_pointer(o); +} + +bool vm_obj_get_boolean(vm_obj_t o) { + assert(vm_obj_is_boolean(o)); + return nanbox_to_boolean(o); +} +double vm_obj_get_number(vm_obj_t o) { + assert(vm_obj_is_number(o)); + return nanbox_to_double(o); +} +vm_io_buffer_t *vm_obj_get_buffer(vm_obj_t o) { + assert(vm_obj_is_buffer(o)); + return ((vm_io_buffer_t *) nanbox_to_aux(o)); +} +vm_obj_table_t *vm_obj_get_table(vm_obj_t o) { + assert(vm_obj_is_table(o)); + return ((vm_obj_table_t *) nanbox_to_aux(o)); +} +vm_obj_closure_t *vm_obj_get_closure(vm_obj_t o) { + assert(vm_obj_is_closure(o)); + return ((vm_obj_closure_t *) nanbox_to_aux(o)); +} +vm_ffi_t *vm_obj_get_ffi(vm_obj_t o) { + assert(vm_obj_is_ffi(o)); + return ((vm_ffi_t *) nanbox_to_aux(o)); +} +vm_ir_block_t *vm_obj_get_block(vm_obj_t o) { + assert(vm_obj_is_block(o)); + return ((vm_ir_block_t *) nanbox_to_aux(o)); +} +vm_error_t *vm_obj_get_error(vm_obj_t o) { + assert(vm_obj_is_error(o)); + return ((vm_error_t *) nanbox_to_pointer(o)); +} + +vm_obj_t vm_obj_of_nil(void) { + return nanbox_empty(); +} +vm_obj_t vm_obj_of_boolean(bool b) { + return nanbox_from_boolean(b); +} +vm_obj_t vm_obj_of_number(double n) { + return nanbox_from_double(n); +} +vm_obj_t vm_obj_of_buffer(vm_io_buffer_t *o) { + return nanbox_from_aux1(o); +} +vm_obj_t vm_obj_of_table(vm_obj_table_t *o) { + return nanbox_from_aux2(o); +} +vm_obj_t vm_obj_of_closure(vm_obj_closure_t *o) { + return nanbox_from_aux3(o); +} +vm_obj_t vm_obj_of_ffi(vm_ffi_t *o) { + return nanbox_from_aux4(o); +} +vm_obj_t vm_obj_of_block(vm_ir_block_t *o) { + return nanbox_from_aux5(o); +} +vm_obj_t vm_obj_of_error(vm_error_t *o) { + return nanbox_from_pointer(o); +} + +// extras +uint32_t vm_obj_hash(vm_obj_t value) { + if (vm_obj_is_number(value)) { + double n = vm_obj_get_number(value); + if (n == floor(n) && INT32_MIN <= n && n <= INT32_MAX) { + return (uint32_t) (int32_t) n * 31; + } + return (uint32_t) (*(uint64_t *)&n >> 12) * 37; + } + if (vm_obj_is_buffer(value)) { + vm_io_buffer_t *restrict buf = vm_obj_get_buffer(value); + if (buf->hash == 0) { + uint32_t ret = 0x811c9dc5; + for (size_t i = 0; i < buf->len; i++) { + char c = buf->buf[i]; + if (c == '\0') { + break; + } + ret *= 0x01000193; + ret ^= c; + } + buf->hash = ret; + } + return buf->hash; + } + if (vm_obj_is_boolean(value)) { + return UINT32_MAX - (uint32_t)vm_obj_get_boolean(value); + } + if (vm_obj_is_ffi(value)) { + return (uint32_t)(size_t)vm_obj_get_ffi(value) >> 4; + } + if (vm_obj_is_closure(value)) { + return (uint32_t)(size_t)vm_obj_get_closure(value) >> 4; + } + if (vm_obj_is_table(value)) { + return (uint32_t)(size_t)vm_obj_get_table(value) >> 4; + } + return 0; +} + +vm_obj_t vm_obj_of_string(vm_t *vm, const char *str) { + vm_obj_t ret = vm_obj_of_buffer(vm_io_buffer_from_str(str)); + vm_gc_add(vm, ret); + return ret; +} diff --git a/vm/obj.h b/vm/obj.h index 44f8930..cbc5254 100644 --- a/vm/obj.h +++ b/vm/obj.h @@ -3,11 +3,37 @@ #include "vm.h" +bool vm_obj_is_nil(vm_obj_t obj); +bool vm_obj_is_boolean(vm_obj_t obj); +bool vm_obj_is_number(vm_obj_t obj); +bool vm_obj_is_buffer(vm_obj_t obj); +bool vm_obj_is_table(vm_obj_t obj); +bool vm_obj_is_closure(vm_obj_t obj); +bool vm_obj_is_ffi(vm_obj_t obj); +bool vm_obj_is_block(vm_obj_t obj); +bool vm_obj_is_error(vm_obj_t obj); + +bool vm_obj_get_boolean(vm_obj_t obj); +double vm_obj_get_number(vm_obj_t obj); +vm_io_buffer_t *vm_obj_get_buffer(vm_obj_t obj); +vm_obj_table_t *vm_obj_get_table(vm_obj_t obj); +vm_obj_closure_t *vm_obj_get_closure(vm_obj_t obj); +vm_ffi_t *vm_obj_get_ffi(vm_obj_t obj); +vm_ir_block_t *vm_obj_get_block(vm_obj_t obj); +vm_error_t *vm_obj_get_error(vm_obj_t obj); + +vm_obj_t vm_obj_of_nil(void); +vm_obj_t vm_obj_of_boolean(bool from); +vm_obj_t vm_obj_of_number(double from); +vm_obj_t vm_obj_of_buffer(vm_io_buffer_t *from); +vm_obj_t vm_obj_of_table(vm_obj_table_t *from); +vm_obj_t vm_obj_of_closure(vm_obj_closure_t *from); +vm_obj_t vm_obj_of_ffi(vm_ffi_t *from); +vm_obj_t vm_obj_of_block(vm_ir_block_t *from); +vm_obj_t vm_obj_of_error(vm_error_t *from); + +// extras vm_obj_t vm_obj_of_string(vm_t *vm, const char *str); uint32_t vm_obj_hash(vm_obj_t value); -vm_obj_table_t *vm_table_new(vm_t *vm); -void vm_table_set(vm_obj_table_t *table, vm_obj_t key, vm_obj_t value); -vm_obj_t vm_table_get(vm_obj_table_t *table, vm_obj_t key); - #endif diff --git a/vm/obj.inc b/vm/obj.inc deleted file mode 100644 index 8c23a52..0000000 --- a/vm/obj.inc +++ /dev/null @@ -1,89 +0,0 @@ - -static inline bool vm_obj_is_nil(vm_obj_t o) { - return nanbox_is_empty(o); -} -static inline bool vm_obj_is_boolean(vm_obj_t o) { - return nanbox_is_boolean(o); -} -static inline bool vm_obj_is_number(vm_obj_t o) { - return nanbox_is_number(o); -} -static inline bool vm_obj_is_string(vm_obj_t o) { - return nanbox_is_aux1(o); -} -static inline bool vm_obj_is_table(vm_obj_t o) { - return nanbox_is_aux2(o); -} -static inline bool vm_obj_is_closure(vm_obj_t o) { - return nanbox_is_aux3(o); -} -static inline bool vm_obj_is_ffi(vm_obj_t o) { - return nanbox_is_aux4(o); -} -static inline bool vm_obj_is_block(vm_obj_t o) { - return nanbox_is_aux5(o); -} -static inline bool vm_obj_is_error(vm_obj_t o) { - return nanbox_is_pointer(o); -} - -static inline bool vm_obj_get_boolean(vm_obj_t o) { - assert(vm_obj_is_boolean(o)); - return nanbox_to_boolean(o); -} -static inline double vm_obj_get_number(vm_obj_t o) { - assert(vm_obj_is_number(o)); - return nanbox_to_double(o); -} -static inline vm_io_buffer_t *vm_obj_get_string(vm_obj_t o) { - assert(vm_obj_is_string(o)); - return ((vm_io_buffer_t *) nanbox_to_aux(o)); -} -static inline vm_obj_table_t *vm_obj_get_table(vm_obj_t o) { - assert(vm_obj_is_table(o)); - return ((vm_obj_table_t *) nanbox_to_aux(o)); -} -static inline vm_obj_closure_t *vm_obj_get_closure(vm_obj_t o) { - assert(vm_obj_is_closure(o)); - return ((vm_obj_closure_t *) nanbox_to_aux(o)); -} -static inline vm_ffi_t *vm_obj_get_ffi(vm_obj_t o) { - assert(vm_obj_is_ffi(o)); - return ((vm_ffi_t *) nanbox_to_aux(o)); -} -static inline vm_ir_block_t *vm_obj_get_block(vm_obj_t o) { - assert(vm_obj_is_block(o)); - return ((vm_ir_block_t *) nanbox_to_aux(o)); -} -static inline vm_error_t *vm_obj_get_error(vm_obj_t o) { - assert(vm_obj_is_error(o)); - return ((vm_error_t *) nanbox_to_pointer(o)); -} - -static inline vm_obj_t vm_obj_of_nil(void) { - return nanbox_empty(); -} -static inline vm_obj_t vm_obj_of_boolean(bool b) { - return nanbox_from_boolean(b); -} -static inline vm_obj_t vm_obj_of_number(double n) { - return nanbox_from_double(n); -} -static inline vm_obj_t vm_obj_of_buffer(vm_io_buffer_t *o) { - return nanbox_from_aux1(o); -} -static inline vm_obj_t vm_obj_of_table(vm_obj_table_t *o) { - return nanbox_from_aux2(o); -} -static inline vm_obj_t vm_obj_of_closure(vm_obj_closure_t *o) { - return nanbox_from_aux3(o); -} -static inline vm_obj_t vm_obj_of_ffi(vm_ffi_t *o) { - return nanbox_from_aux4(o); -} -static inline vm_obj_t vm_obj_of_block(vm_ir_block_t *o) { - return nanbox_from_aux5(o); -} -static inline vm_obj_t vm_obj_of_error(vm_error_t *o) { - return nanbox_from_pointer(o); -} diff --git a/vm/primes.inc b/vm/primes.inc index 2a93430..d1f818a 100644 --- a/vm/primes.inc +++ b/vm/primes.inc @@ -3,82 +3,82 @@ #include static uint32_t vm_primes_table[32] = { - 1, 3, 7, 13, 29, - 53, 89, 157, 283, 491, - 863, 1511, 2663, 4657, 8147, - 14251, 24979, 43721, 76519, 133877, - 234331, 410093, 717659, 1255913, 2197849, - 3846239, 6730909, 11779121, 20613457, 36073561, - 63128731, 110475283, + 2, 5, 11, 23, 53, + 89, 157, 283, 491, 863, + 1511, 2663, 4657, 8147, 14251, + 24979, 43721, 76519, 133877, 234331, + 410093, 717659, 1255913, 2197849, 3846239, + 6730909, 11779121, 20613457, 36073561, 63128731, + 110475283, 193331729, }; -static uint32_t vm_primes_mod(uint8_t p, uint32_t n) { +static inline uint32_t vm_primes_mod(uint8_t p, uint32_t n) { switch (p) { default: __builtin_unreachable(); case 0: - return n % 1; + return n % 2; case 1: - return n % 3; + return n % 5; case 2: - return n % 7; + return n % 11; case 3: - return n % 13; + return n % 23; case 4: - return n % 29; - case 5: return n % 53; - case 6: + case 5: return n % 89; - case 7: + case 6: return n % 157; - case 8: + case 7: return n % 283; - case 9: + case 8: return n % 491; - case 10: + case 9: return n % 863; - case 11: + case 10: return n % 1511; - case 12: + case 11: return n % 2663; - case 13: + case 12: return n % 4657; - case 14: + case 13: return n % 8147; - case 15: + case 14: return n % 14251; - case 16: + case 15: return n % 24979; - case 17: + case 16: return n % 43721; - case 18: + case 17: return n % 76519; - case 19: + case 18: return n % 133877; - case 20: + case 19: return n % 234331; - case 21: + case 20: return n % 410093; - case 22: + case 21: return n % 717659; - case 23: + case 22: return n % 1255913; - case 24: + case 23: return n % 2197849; - case 25: + case 24: return n % 3846239; - case 26: + case 25: return n % 6730909; - case 27: + case 26: return n % 11779121; - case 28: + case 27: return n % 20613457; - case 29: + case 28: return n % 36073561; - case 30: + case 29: return n % 63128731; - case 31: + case 30: return n % 110475283; + case 31: + return n % 193331729; } } diff --git a/vm/std.c b/vm/std.c index e2d7795..48bf28f 100644 --- a/vm/std.c +++ b/vm/std.c @@ -9,6 +9,7 @@ #include "errors.h" #include "ir.h" #include "obj.h" +#include "tables.h" #include "gc.h" #include "io.h" #include "lib.h" @@ -21,11 +22,11 @@ void vm_std_os_exit(vm_t *vm, size_t nargs, vm_obj_t *args) { void vm_std_load(vm_t *vm, size_t nargs, vm_obj_t *args) { (void)vm; - if (!vm_obj_is_string(args[0])) { + if (!vm_obj_is_buffer(args[0])) { *args = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "cannot load non-string value")); return; } - const char *str = vm_obj_get_string(args[0])->buf; + const char *str = vm_obj_get_buffer(args[0])->buf; vm_ir_block_t *entry = vm_lang_lua_compile(vm, str, "__load__"); vm_obj_closure_t *closure = vm_malloc(sizeof(vm_obj_closure_t)); @@ -56,8 +57,8 @@ void vm_std_assert(vm_t *vm, size_t nargs, vm_obj_t *args) { } void vm_std_error(vm_t *vm, size_t nargs, vm_obj_t *args) { - if (vm_obj_is_string(args[0])) { - *args = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_UNKNOWN, vm_obj_get_string(args[0])->buf)); + if (vm_obj_is_buffer(args[0])) { + *args = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_UNKNOWN, vm_obj_get_buffer(args[0])->buf)); return; } vm_obj_t msg = args[0]; @@ -130,7 +131,7 @@ void vm_std_type(vm_t *vm, size_t nargs, vm_obj_t *args) { ret = "booolean"; } else if (vm_obj_is_number(args[0])) { ret = "number"; - } else if (vm_obj_is_string(args[0])) { + } else if (vm_obj_is_buffer(args[0])) { ret = "string"; } else if (vm_obj_is_table(args[0])) { ret = "table"; @@ -154,9 +155,9 @@ void vm_std_tostring(vm_t *vm, size_t nargs, vm_obj_t *args) { void vm_std_tonumber(vm_t *vm, size_t nargs, vm_obj_t *args) { if (vm_obj_is_number(args[0])) { - } else if (vm_obj_is_string(args[0])) { + } else if (vm_obj_is_buffer(args[0])) { double num; - if (sscanf(vm_obj_get_string(args[0])->buf, "%lf", &num) == 0) { + if (sscanf(vm_obj_get_buffer(args[0])->buf, "%lf", &num) == 0) { args[0] = vm_obj_of_nil(); return; } @@ -198,20 +199,20 @@ void vm_std_io_write(vm_t *vm, size_t nargs, vm_obj_t *args) { } void vm_std_string_len(vm_t *vm, size_t nargs, vm_obj_t *args) { - if (nargs == 0 || !vm_obj_is_string(args[0])) { + if (nargs == 0 || !vm_obj_is_buffer(args[0])) { args[0] = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "string.sub: first argument not a string")); return; } - args[0] = vm_obj_of_number(vm_obj_get_string(args[0])->len); + args[0] = vm_obj_of_number(vm_obj_get_buffer(args[0])->len); return; } void vm_std_string_sub(vm_t *vm, size_t nargs, vm_obj_t *args) { - if (nargs == 0 || !vm_obj_is_string(args[0])) { + if (nargs == 0 || !vm_obj_is_buffer(args[0])) { args[0] = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "string.sub: first argument not a string")); return; } - vm_io_buffer_t *buf = vm_obj_get_string(args[0]); + vm_io_buffer_t *buf = vm_obj_get_buffer(args[0]); if (nargs == 1 || !vm_obj_is_number(args[1])) { args[0] = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "string.sub: second argument not a number")); return; @@ -243,12 +244,12 @@ void vm_std_string_format(vm_t *vm, size_t nargs, vm_obj_t *args) { (void)vm; size_t argnum = 0; vm_obj_t fmt = args[argnum++]; - if (!vm_obj_is_string(fmt)) { + if (!vm_obj_is_buffer(fmt)) { args[0] = vm_obj_of_error(vm_error_from_msg(VM_LOCATION_RANGE_FUNC, "invalid format (not a string)")); return; } vm_io_buffer_t *out = vm_io_buffer_new(); - const char *str = vm_obj_get_string(fmt)->buf; + const char *str = vm_obj_get_buffer(fmt)->buf; while (*str != '\0') { const char *head = str; char got = *str++; @@ -381,9 +382,9 @@ void vm_std_string_format(vm_t *vm, size_t nargs, vm_obj_t *args) { return; } case 's': { - if (vm_obj_is_string(arg)) { + if (vm_obj_is_buffer(arg)) { strcpy(&format[len], "s"); - vm_io_buffer_format(out, format, vm_obj_get_string(arg)->buf); + vm_io_buffer_format(out, format, vm_obj_get_buffer(arg)->buf); } else if (vm_obj_is_number(arg)) { strcpy(&format[len], &VM_FORMAT_FLOAT[1]); vm_io_buffer_format(out, format, vm_obj_get_number(arg)); @@ -459,16 +460,16 @@ void vm_std_table_values(vm_t *vm, size_t nargs, vm_obj_t *args) { } void vm_std_vm_import(vm_t *vm, size_t nargs, vm_obj_t *args) { - if (!vm_obj_is_string(args[0])) { + if (!vm_obj_is_buffer(args[0])) { args[0] = vm_obj_of_string(vm, "import() must take a string"); return; } - const char *src = vm_io_read(vm_obj_get_string(args[0])->buf); + const char *src = vm_io_read(vm_obj_get_buffer(args[0])->buf); if (src == NULL) { args[0] = vm_obj_of_string(vm, "import() no such file"); return; } - vm_ir_block_t *block = vm_lang_lua_compile(vm, src, vm_obj_get_string(args[0])->buf); + vm_ir_block_t *block = vm_lang_lua_compile(vm, src, vm_obj_get_buffer(args[0])->buf); args[0] = vm_run_repl(vm, block); vm_free(src); return; diff --git a/vm/tables.c b/vm/tables.c new file mode 100644 index 0000000..f8add11 --- /dev/null +++ b/vm/tables.c @@ -0,0 +1,95 @@ + + +#include "tables.h" +#include "obj.h" +#include "math.h" +#include "lib.h" + +vm_obj_t vm_table_get(vm_obj_table_t *table, vm_obj_t key) { + size_t len = vm_primes_table[table->size]; + size_t init_look = vm_primes_mod(table->size, vm_obj_hash(key)); + size_t look = init_look; + do { + vm_obj_t found_key = table->entries[look]; + if (vm_obj_is_nil(found_key)) { + return vm_obj_of_nil(); + } + if (vm_obj_unsafe_eq(key, found_key)) { + return table->entries[vm_primes_table[table->size] + look]; + } + look += 1; + if (look == len) { + look = 0; + } + } while (look != init_look); + + return vm_obj_of_nil(); +} + +void vm_table_set(vm_obj_table_t *restrict table, vm_obj_t key, vm_obj_t value) { + size_t len = vm_primes_table[table->size]; + size_t look = vm_primes_mod(table->size, vm_obj_hash(key)); + for (size_t i = 0; i < len; i++) { + vm_obj_t table_key = table->entries[look]; + if (vm_obj_is_nil(table_key)) { + break; + } + if (vm_obj_unsafe_eq(key, table_key)) { + if (vm_obj_is_nil(value)) { + if (vm_obj_is_number(key)) { + double f64val = vm_obj_get_number(key); + if (1 <= f64val && f64val <= table->len) { + int32_t i64val = (int32_t)f64val; + if ((double)i64val == f64val) { + table->len = i64val - 1; + } + } + } + table->entries[look] = value; + } + table->entries[vm_primes_table[table->size] + look] = value; + return; + } + look += 1; + if (look == len) { + look = 0; + } + } + if ((table->used) * 100u > vm_primes_table[table->size] * 75u) { + vm_obj_table_t ret; + ret.size = table->size + 1; + ret.used = 0; + ret.len = 0; + ret.mark = table->mark; +#if VM_EMPTY_BYTE == 0 + ret.entries = vm_calloc(sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); +#else + ret.entries = vm_malloc(sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); + memset(ret.entries, VM_EMPTY_BYTE, sizeof(vm_obj_t) * vm_primes_table[ret.size] * 2); +#endif + for (size_t i = 0; i < vm_primes_table[table->size]; i++) { + vm_obj_t in_key = table->entries[i]; + if (!vm_obj_is_nil(in_key)) { + vm_table_set(&ret, in_key, table->entries[vm_primes_table[table->size] + i]); + } + } + vm_table_set(&ret, key, value); + vm_free(table->entries); + *table = ret; + } else { + table->used += 1; + table->entries[look] = key; + table->entries[vm_primes_table[table->size] + look] = value; + int32_t next = table->len + 1; + if (vm_obj_is_number(key) && vm_obj_get_number(key) == next) { + while (true) { + vm_obj_t got = vm_table_get(table, vm_obj_of_number(next + 1)); + if (vm_obj_is_nil(got)) { + break; + } + next += 1; + } + table->len = next; + } + } +} diff --git a/vm/tables.h b/vm/tables.h new file mode 100644 index 0000000..6018273 --- /dev/null +++ b/vm/tables.h @@ -0,0 +1,8 @@ + +#include "vm.h" + +vm_obj_table_t *vm_table_new(vm_t *vm); +void vm_table_set(vm_obj_table_t *table, vm_obj_t key, vm_obj_t value); +vm_obj_t vm_table_get(vm_obj_table_t *table, vm_obj_t key); + +#include "primes.inc" diff --git a/vm/vm.h b/vm/vm.h index 6b99f95..9892abf 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -9,8 +9,8 @@ #define VM_VERSION "0.0.5" -#define VM_MALLOC_MI 1 -#define VM_MALLOC_SYS 0 +#define VM_MALLOC_MI 0 +#define VM_MALLOC_SYS 1 #define VM_GC_MIN 256 #define VM_GC_FACTOR 1.4 @@ -87,7 +87,4 @@ struct vm_t { vm_t *vm_state_new(void); void vm_state_delete(vm_t *vm); -#include "obj.inc" -#include "primes.inc" - #endif