summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-01-07 20:03:17 +0100
committerJo-Philipp Wich <jo@mein.io>2022-01-18 10:58:11 +0100
commit725bb75b7b66dd1e0a381908e831cede0402cb6e (patch)
treeb8ee8c737198e5b5bad6b809457c59be2a7f8bb5
parent6b2e79af9fe6e7d05d31245fc9049540a96d5d31 (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.c14
-rw-r--r--compiler.c14
-rw-r--r--include/ucode/chunk.h2
-rw-r--r--include/ucode/program.h3
-rw-r--r--include/ucode/types.h2
-rw-r--r--program.c16
-rw-r--r--vallist.c8
-rw-r--r--vm.c41
8 files changed, 46 insertions, 54 deletions
diff --git a/chunk.c b/chunk.c
index ab576da..5dbd1a1 100644
--- a/chunk.c
+++ b/chunk.c
@@ -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)
{
diff --git a/compiler.c b/compiler.c
index 745707b..97962b1 100644
--- a/compiler.c
+++ b/compiler.c
@@ -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;
diff --git a/program.c b/program.c
index c413f38..5d3a104 100644
--- a/program.c
+++ b/program.c
@@ -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);
+}
diff --git a/vallist.c b/vallist.c
index abf29ad..d7826a0 100644
--- a/vallist.c
+++ b/vallist.c
@@ -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;
diff --git a/vm.c b/vm.c
index b8cf50f..1766dc6 100644
--- a/vm.c
+++ b/vm.c
@@ -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);