diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-07-07 20:57:50 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-07-07 21:04:15 +0200 |
commit | 96f140bd8c39ccb44efa630b0ff6096d53b94456 (patch) | |
tree | 2a149ebaa7e7f47b5baf93ccd2d33d35142f7ed0 | |
parent | df5db5f1deb809b8570185b2fd046a38db13537d (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.c | 21 |
1 files changed, 16 insertions, 5 deletions
@@ -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; } |