summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-07-07 20:57:50 +0200
committerJo-Philipp Wich <jo@mein.io>2021-07-07 21:04:15 +0200
commit96f140bd8c39ccb44efa630b0ff6096d53b94456 (patch)
tree2a149ebaa7e7f47b5baf93ccd2d33d35142f7ed0
parentdf5db5f1deb809b8570185b2fd046a38db13537d (diff)
lib, vm: ensure that require() compiles modules only once
Cache the result of a successful require operation in a global.modules object and return the cached value for subsequent require calls on the same module name. This ensures that a given module is only compiled and executed once, regardless of how many times it is used. A reload of the module can be forced by deleting the corresponding key in the global module table. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--lib.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/lib.c b/lib.c
index 23e9ac2..624b063 100644
--- a/lib.c
+++ b/lib.c
@@ -1585,14 +1585,19 @@ uc_require_path(uc_vm *vm, const char *path_template, const char *name, uc_value
{
uc_stringbuf_t *buf = xprintbuf_new();
const char *p, *q, *last;
- bool rv = false;
+ uc_value_t *modtable;
+ bool rv;
- *res = NULL;
+ modtable = ucv_property_get(vm->globals, "modules");
+ *res = ucv_object_get(modtable, name, &rv);
+
+ if (rv)
+ goto out;
p = strchr(path_template, '*');
if (!p)
- goto invalid;
+ goto out;
ucv_stringbuf_addstr(buf, path_template, p - path_template);
@@ -1611,7 +1616,7 @@ uc_require_path(uc_vm *vm, const char *path_template, const char *name, uc_value
last = q + 1;
}
else if (!isalnum(*q) && *q != '_') {
- goto invalid;
+ goto out;
}
}
@@ -1620,7 +1625,10 @@ uc_require_path(uc_vm *vm, const char *path_template, const char *name, uc_value
else if (!strcmp(p + 1, ".uc"))
rv = uc_require_ucode(vm, buf->buf, NULL, res);
-invalid:
+ if (rv)
+ ucv_object_add(modtable, name, *res);
+
+out:
printbuf_free(buf);
return rv;
@@ -2955,7 +2963,9 @@ uc_alloc_global(uc_vm *vm)
for (i = 0; i < ARRAY_SIZE(path); i++)
ucv_array_push(arr, ucv_string_new(path[i]));
+ /* register module related constants */
ucv_object_add(global, "REQUIRE_SEARCH_PATH", arr);
+ ucv_object_add(global, "modules", ucv_object_new(vm));
/* register global math constants */
ucv_object_add(global, "NaN", ucv_double_new(NAN));
@@ -2964,5 +2974,6 @@ uc_alloc_global(uc_vm *vm)
/* register global property */
ucv_object_add(global, "global", ucv_get(global));
+
return global;
}