diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-07 20:03:17 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-18 10:58:11 +0100 |
commit | 725bb75b7b66dd1e0a381908e831cede0402cb6e (patch) | |
tree | b8ee8c737198e5b5bad6b809457c59be2a7f8bb5 | |
parent | 6b2e79af9fe6e7d05d31245fc9049540a96d5d31 (diff) |
compiler, vm: use a program wide constant list
Instead of storing constant values per function, maintain a global program
wide list for all constant values within the current compilation unit.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | chunk.c | 14 | ||||
-rw-r--r-- | compiler.c | 14 | ||||
-rw-r--r-- | include/ucode/chunk.h | 2 | ||||
-rw-r--r-- | include/ucode/program.h | 3 | ||||
-rw-r--r-- | include/ucode/types.h | 2 | ||||
-rw-r--r-- | program.c | 16 | ||||
-rw-r--r-- | vallist.c | 8 | ||||
-rw-r--r-- | vm.c | 41 |
8 files changed, 46 insertions, 54 deletions
@@ -45,7 +45,6 @@ uc_chunk_init(uc_chunk_t *chunk) chunk->debuginfo.variables.count = 0; chunk->debuginfo.variables.entries = NULL; - uc_vallist_init(&chunk->constants); uc_vallist_init(&chunk->debuginfo.varnames); } @@ -54,7 +53,6 @@ uc_chunk_free(uc_chunk_t *chunk) { uc_vector_clear(chunk); uc_vector_clear(&chunk->ehranges); - uc_vallist_free(&chunk->constants); uc_vector_clear(&chunk->debuginfo.offsets); uc_vector_clear(&chunk->debuginfo.variables); @@ -136,18 +134,6 @@ uc_chunk_pop(uc_chunk_t *chunk) } } -uc_value_t * -uc_chunk_get_constant(uc_chunk_t *chunk, size_t idx) -{ - return uc_vallist_get(&chunk->constants, idx); -} - -ssize_t -uc_chunk_add_constant(uc_chunk_t *chunk, uc_value_t *val) -{ - return uc_vallist_add(&chunk->constants, val); -} - size_t uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off) { @@ -483,8 +483,7 @@ uc_compiler_set_u32(uc_compiler_t *compiler, size_t off, uint32_t n) static size_t uc_compiler_emit_constant(uc_compiler_t *compiler, size_t srcpos, uc_value_t *val) { - uc_chunk_t *chunk = uc_compiler_current_chunk(compiler); - size_t cidx = uc_chunk_add_constant(chunk, val); + size_t cidx = uc_program_add_constant(compiler->program, val); uc_compiler_emit_insn(compiler, srcpos, I_LOAD); uc_compiler_emit_u32(compiler, 0, cidx); @@ -495,8 +494,7 @@ uc_compiler_emit_constant(uc_compiler_t *compiler, size_t srcpos, uc_value_t *va static size_t uc_compiler_emit_regexp(uc_compiler_t *compiler, size_t srcpos, uc_value_t *val) { - uc_chunk_t *chunk = uc_compiler_current_chunk(compiler); - size_t cidx = uc_chunk_add_constant(chunk, val); + size_t cidx = uc_program_add_constant(compiler->program, val); uc_compiler_emit_insn(compiler, srcpos, I_LREXP); uc_compiler_emit_u32(compiler, 0, cidx); @@ -1086,7 +1084,7 @@ uc_compiler_emit_variable_rw(uc_compiler_t *compiler, uc_value_t *varname, uc_to ((sub_insn & 0xff) << 24) | idx); } else { - idx = uc_chunk_add_constant(uc_compiler_current_chunk(compiler), varname); + idx = uc_program_add_constant(compiler->program, varname); insn = sub_insn ? I_UVAR : (type ? I_SVAR : I_LVAR); uc_compiler_emit_insn(compiler, compiler->parser->prev.pos, insn); @@ -1195,8 +1193,7 @@ uc_compiler_compile_arrowfn(uc_compiler_t *compiler, uc_value_t *args, bool rest if (fn) uc_compiler_set_u32(compiler, load_off, - uc_chunk_add_constant(uc_compiler_current_chunk(compiler), - &fn->header)); + uc_program_add_constant(compiler->program, &fn->header)); return true; } @@ -1635,8 +1632,7 @@ uc_compiler_compile_function(uc_compiler_t *compiler) if (fn) uc_compiler_set_u32(compiler, load_off, - uc_chunk_add_constant(uc_compiler_current_chunk(compiler), - &fn->header)); + uc_program_add_constant(compiler->program, &fn->header)); /* if a local variable of the same name already existed, overwrite its value * with the compiled function here */ diff --git a/include/ucode/chunk.h b/include/ucode/chunk.h index 0005e3c..6804eeb 100644 --- a/include/ucode/chunk.h +++ b/include/ucode/chunk.h @@ -28,8 +28,6 @@ void uc_chunk_init(uc_chunk_t *chunk); void uc_chunk_free(uc_chunk_t *chunk); size_t uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t line); -ssize_t uc_chunk_add_constant(uc_chunk_t *chunk, uc_value_t *value); -uc_value_t *uc_chunk_get_constant(uc_chunk_t *chunk, size_t idx); void uc_chunk_pop(uc_chunk_t *chunk); size_t uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off); diff --git a/include/ucode/program.h b/include/ucode/program.h index 19b3c9f..9bbc67e 100644 --- a/include/ucode/program.h +++ b/include/ucode/program.h @@ -28,4 +28,7 @@ uc_value_t *uc_program_function_new(uc_program_t *, const char *, size_t, uc_sou size_t uc_program_function_id(uc_program_t *, uc_value_t *); uc_value_t *uc_program_function_load(uc_program_t *, size_t); +uc_value_t *uc_program_get_constant(uc_program_t *, size_t); +ssize_t uc_program_add_constant(uc_program_t *, uc_value_t *); + #endif /* __PROGRAM_H_ */ diff --git a/include/ucode/types.h b/include/ucode/types.h index 7bd0ea9..be10ac5 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -90,7 +90,6 @@ uc_declare_vector(uc_offsetinfo_t, uint8_t); typedef struct { size_t count; uint8_t *entries; - uc_value_list_t constants; uc_ehranges_t ehranges; struct { uc_variables_t variables; @@ -204,6 +203,7 @@ uc_declare_vector(uc_resource_types_t, uc_resource_type_t *); /* Program structure definitions */ typedef struct uc_program { + uc_value_list_t constants; uc_weakref_t functions; } uc_program_t; @@ -15,6 +15,7 @@ */ #include "ucode/program.h" +#include "ucode/vallist.h" uc_program_t * @@ -27,6 +28,8 @@ uc_program_new(void) prog->functions.next = &prog->functions; prog->functions.prev = &prog->functions; + uc_vallist_init(&prog->constants); + return prog; } @@ -60,6 +63,7 @@ uc_program_free(uc_program_t *prog) ucv_put(&func->header); } + uc_vallist_free(&prog->constants); free(prog); } @@ -101,3 +105,15 @@ uc_program_function_load(uc_program_t *prog, size_t id) return NULL; } + +uc_value_t * +uc_program_get_constant(uc_program_t *prog, size_t idx) +{ + return uc_vallist_get(&prog->constants, idx); +} + +ssize_t +uc_program_add_constant(uc_program_t *prog, uc_value_t *val) +{ + return uc_vallist_add(&prog->constants, val); +} @@ -553,8 +553,7 @@ uc_value_t * uc_vallist_get(uc_value_list_t *list, size_t idx) { char str[sizeof(TAG_TYPE)]; - uc_function_t *func; - uc_chunk_t *chunk; + uc_program_t *program; size_t n, len; switch (uc_vallist_type(list, idx)) { @@ -593,10 +592,9 @@ uc_vallist_get(uc_value_list_t *list, size_t idx) return ucv_string_new_length(list->data + TAG_GET_OFFSET(list->index[idx]) + sizeof(uint32_t), len); case TAG_FUNC: - chunk = container_of(list, uc_chunk_t, constants); - func = container_of(chunk, uc_function_t, chunk); + program = container_of(list, uc_program_t, constants); - return uc_program_function_load(func->program, TAG_GET_NV(list->index[idx])); + return uc_program_function_load(program, TAG_GET_NV(list->index[idx])); default: return NULL; @@ -24,6 +24,7 @@ #include "ucode/vm.h" #include "ucode/compiler.h" +#include "ucode/program.h" #include "ucode/lib.h" /* uc_error_context_format() */ #undef __insn @@ -201,16 +202,22 @@ uc_vm_frame_chunk(uc_callframe_t *frame) return frame->closure ? &frame->closure->function->chunk : NULL; } +static uc_program_t * +uc_vm_frame_program(uc_callframe_t *frame) +{ + return frame->closure ? frame->closure->function->program : NULL; +} + static uc_callframe_t * uc_vm_current_frame(uc_vm_t *vm) { return uc_vector_last(&vm->callframes); } -static uc_chunk_t * -uc_vm_current_chunk(uc_vm_t *vm) +static uc_program_t * +uc_vm_current_program(uc_vm_t *vm) { - return uc_vm_frame_chunk(uc_vm_current_frame(vm)); + return uc_vm_frame_program(uc_vm_current_frame(vm)); } static bool @@ -319,18 +326,6 @@ uc_vm_frame_dump(uc_vm_t *vm, uc_callframe_t *frame) uc_vm_format_val(vm, frame->ctx)); if (chunk) { - fprintf(stderr, " |- %zu constants\n", - chunk->constants.isize); - - for (i = 0; i < chunk->constants.isize; i++) { - v = uc_chunk_get_constant(chunk, i); - - fprintf(stderr, " | [%zu] %s\n", - i, uc_vm_format_val(vm, v)); - - ucv_put(v); - } - closure = frame->closure; function = closure->function; @@ -649,7 +644,7 @@ uc_dump_insn(uc_vm_t *vm, uint8_t *pos, uc_vm_insn_t insn) case I_LOAD: case I_LVAR: case I_SVAR: - cnst = uc_chunk_get_constant(uc_vm_frame_chunk(uc_vector_last(&vm->callframes)), vm->arg.u32); + cnst = uc_program_get_constant(uc_vm_frame_program(uc_vector_last(&vm->callframes)), vm->arg.u32); fprintf(stderr, "\t; %s", cnst ? uc_vm_format_val(vm, cnst) : "(?)"); @@ -676,7 +671,7 @@ uc_dump_insn(uc_vm_t *vm, uint8_t *pos, uc_vm_insn_t insn) case I_UVAR: if (!cnst) - cnst = uc_chunk_get_constant(uc_vm_frame_chunk(uc_vector_last(&vm->callframes)), vm->arg.u32 & 0x00ffffff); + cnst = uc_program_get_constant(uc_vm_frame_program(uc_vector_last(&vm->callframes)), vm->arg.u32 & 0x00ffffff); fprintf(stderr, "\t; %s (%s)", cnst ? uc_vm_format_val(vm, cnst) : "(?)", @@ -915,7 +910,7 @@ uc_vm_insn_load(uc_vm_t *vm, uc_vm_insn_t insn) { switch (insn) { case I_LOAD: - uc_vm_stack_push(vm, uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32)); + uc_vm_stack_push(vm, uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32)); break; case I_LOAD8: @@ -938,7 +933,7 @@ uc_vm_insn_load(uc_vm_t *vm, uc_vm_insn_t insn) static void uc_vm_insn_load_regexp(uc_vm_t *vm, uc_vm_insn_t insn) { - uc_value_t *re, *jstr = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32); + uc_value_t *re, *jstr = uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32); bool icase = false, newline = false, global = false; char *str, *err = NULL; @@ -987,7 +982,7 @@ uc_vm_insn_load_var(uc_vm_t *vm, uc_vm_insn_t insn) bool found; scope = vm->globals; - name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32); + name = uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32); while (ucv_type(name) == UC_STRING) { val = ucv_object_get(scope, ucv_string_get(name), &found); @@ -1128,7 +1123,7 @@ static void uc_vm_insn_load_closure(uc_vm_t *vm, uc_vm_insn_t insn) { uc_callframe_t *frame = uc_vm_current_frame(vm); - uc_value_t *fno = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32); + uc_value_t *fno = uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32); uc_function_t *function = (uc_function_t *)fno; uc_closure_t *closure = (uc_closure_t *)ucv_closure_new(vm, function, insn == I_ARFN); volatile int32_t uv; @@ -1163,7 +1158,7 @@ uc_vm_insn_store_var(uc_vm_t *vm, uc_vm_insn_t insn) bool found; scope = vm->globals; - name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32); + name = uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32); while (ucv_type(name) == UC_STRING) { ucv_object_get(scope, ucv_string_get(name), &found); @@ -1562,7 +1557,7 @@ uc_vm_insn_update_var(uc_vm_t *vm, uc_vm_insn_t insn) bool found; scope = vm->globals; - name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32 & 0x00FFFFFF); + name = uc_program_get_constant(uc_vm_current_program(vm), vm->arg.u32 & 0x00FFFFFF); assert(ucv_type(name) == UC_STRING); |