Skip to content

Commit

Permalink
vm: introduce value registry
Browse files Browse the repository at this point in the history
Introduce a new, lazily allocated value registry which can be used by C
code to store values which should not be garbage collected.

The registry is a plain ucode object internally and treated as GC root
but not exposed to ucode script code, this allows it to retain references
to values which are otherwise completely unreachable from ucode scripts.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  • Loading branch information
jow- committed Dec 8, 2021
1 parent 0d29b25 commit 99fdafd
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/ucode/types.h
Expand Up @@ -250,6 +250,7 @@ struct uc_vm {
uc_upvalref_t *open_upvals;
uc_parse_config_t *config;
uc_value_t *globals;
uc_value_t *registry;
uc_source_t *sources;
uc_weakref_t values;
uc_resource_types_t restypes;
Expand Down
5 changes: 5 additions & 0 deletions include/ucode/vm.h
Expand Up @@ -119,6 +119,11 @@ void uc_vm_free(uc_vm_t *vm);
uc_value_t *uc_vm_scope_get(uc_vm_t *vm);
void uc_vm_scope_set(uc_vm_t *vm, uc_value_t *ctx);

bool uc_vm_registry_exists(uc_vm_t *vm, const char *key);
uc_value_t *uc_vm_registry_get(uc_vm_t *vm, const char *key);
void uc_vm_registry_set(uc_vm_t *vm, const char *key, uc_value_t *value);
bool uc_vm_registry_delete(uc_vm_t *vm, const char *key);

void uc_vm_stack_push(uc_vm_t *vm, uc_value_t *value);
uc_value_t *uc_vm_stack_pop(uc_vm_t *vm);
uc_value_t *uc_vm_stack_peek(uc_vm_t *vm, size_t offset);
Expand Down
1 change: 1 addition & 0 deletions types.c
Expand Up @@ -2078,6 +2078,7 @@ ucv_gc_common(uc_vm_t *vm, bool final)
if (!final) {
/* mark reachable objects */
ucv_gc_mark(vm->globals);
ucv_gc_mark(vm->registry);
ucv_gc_mark(vm->exception.stacktrace);

for (i = 0; i < vm->callframes.count; i++) {
Expand Down
31 changes: 31 additions & 0 deletions vm.c
Expand Up @@ -2480,3 +2480,34 @@ uc_vm_trace_set(uc_vm_t *vm, uint32_t level)
{
vm->trace = level;
}

bool
uc_vm_registry_exists(uc_vm_t *vm, const char *key)
{
bool exists;

ucv_object_get(vm->registry, key, &exists);

return exists;
}

uc_value_t *
uc_vm_registry_get(uc_vm_t *vm, const char *key)
{
return ucv_object_get(vm->registry, key, NULL);
}

void
uc_vm_registry_set(uc_vm_t *vm, const char *key, uc_value_t *value)
{
if (!vm->registry)
vm->registry = ucv_object_new(vm);

ucv_object_add(vm->registry, key, value);
}

bool
uc_vm_registry_delete(uc_vm_t *vm, const char *key)
{
return ucv_object_delete(vm->registry, key);
}

0 comments on commit 99fdafd

Please sign in to comment.