diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-07 19:42:12 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-18 10:57:42 +0100 |
commit | 6b2e79af9fe6e7d05d31245fc9049540a96d5d31 (patch) | |
tree | 20aeea16dc72454610be5bf58e83b5070e1c6da8 /vallist.c | |
parent | 0e5b273c3d25d1dce3b469f3a6865f430554e730 (diff) |
types: add initial infrastructure for function serialization
- Introduce a new "program" entity which holds the list of functions
created during compilation
- Instead of storing pointers to the in-memory function representation
in the constant list, store the index of the function within the
program's function list
- When loading functions from the constant list, retrieve the function
by index from the program entity
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'vallist.c')
-rw-r--r-- | vallist.c | 45 |
1 files changed, 16 insertions, 29 deletions
@@ -24,6 +24,7 @@ #include "ucode/util.h" #include "ucode/chunk.h" +#include "ucode/program.h" #include "ucode/vallist.h" #include "ucode/vm.h" @@ -271,17 +272,6 @@ uc_vallist_init(uc_value_list_t *list) void uc_vallist_free(uc_value_list_t *list) { - uc_value_t *o; - size_t i; - - for (i = 0; i < list->isize; i++) { - if (TAG_GET_TYPE(list->index[i]) == TAG_PTR) { - o = uc_vallist_get(list, i); - ucv_put(o); - ucv_put(o); - } - } - free(list->index); free(list->data); uc_vallist_init(list); @@ -476,22 +466,13 @@ find_str(uc_value_list_t *list, const char *s, size_t slen) } static void -add_ptr(uc_value_list_t *list, void *ptr) +add_func(uc_value_list_t *list, uc_function_t *func) { - size_t sz = TAG_ALIGN(sizeof(ptr)); + size_t id = uc_program_function_id(func->program, &func->header); - if ((TAG_TYPE)list->dsize + sz > TAG_MASK) { - fprintf(stderr, "Constant data too large\n"); - abort(); - } - - list->data = xrealloc(list->data, list->dsize + sz); - - memset(list->data + list->dsize, 0, sz); - memcpy(list->data + list->dsize, &ptr, sizeof(ptr)); + assert(id != 0 && TAG_FIT_NV(id)); - list->index[list->isize++] = (uint64_t)(TAG_PTR | (list->dsize << TAG_BITS)); - list->dsize += sz; + list->index[list->isize++] = (TAG_TYPE)(TAG_FUNC | TAG_SET_NV(id)); } ssize_t @@ -545,7 +526,7 @@ uc_vallist_add(uc_value_list_t *list, uc_value_t *value) break; case UC_FUNCTION: - add_ptr(list, value); + add_func(list, (uc_function_t *)value); break; default: @@ -564,10 +545,16 @@ uc_vallist_type(uc_value_list_t *list, size_t idx) return TAG_GET_TYPE(list->index[idx]); } +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + 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; size_t n, len; switch (uc_vallist_type(list, idx)) { @@ -605,11 +592,11 @@ 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_PTR: - if (TAG_GET_OFFSET(list->index[idx]) + sizeof(void *) > list->dsize) - return NULL; + case TAG_FUNC: + chunk = container_of(list, uc_chunk_t, constants); + func = container_of(chunk, uc_function_t, chunk); - return ucv_get(*(uc_value_t **)(list->data + TAG_GET_OFFSET(list->index[idx]))); + return uc_program_function_load(func->program, TAG_GET_NV(list->index[idx])); default: return NULL; |