summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-12-07 13:40:51 +0100
committerJo-Philipp Wich <jo@mein.io>2021-12-08 15:53:40 +0100
commit99fdafd8c03a7baee265ce3dd22af5b2d02fdeb6 (patch)
treea76772653a70c610085c90f80c13ab8eda0cf010
parent0d29b2558987eda5d8a913638f40d506172606ac (diff)
vm: introduce value registry
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>
-rw-r--r--include/ucode/types.h1
-rw-r--r--include/ucode/vm.h5
-rw-r--r--types.c1
-rw-r--r--vm.c31
4 files changed, 38 insertions, 0 deletions
diff --git a/include/ucode/types.h b/include/ucode/types.h
index ccb0e1b..49d910b 100644
--- a/include/ucode/types.h
+++ b/include/ucode/types.h
@@ -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;
diff --git a/include/ucode/vm.h b/include/ucode/vm.h
index 1e9357f..caebb7a 100644
--- a/include/ucode/vm.h
+++ b/include/ucode/vm.h
@@ -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);
diff --git a/types.c b/types.c
index c3032e1..a8ca023 100644
--- a/types.c
+++ b/types.c
@@ -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++) {
diff --git a/vm.c b/vm.c
index a1be51b..e21bc4b 100644
--- a/vm.c
+++ b/vm.c
@@ -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);
+}