summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib.c4
-rw-r--r--lib.h8
-rw-r--r--lib/fs.c8
-rw-r--r--lib/math.c2
-rw-r--r--lib/ubus.c4
-rw-r--r--lib/uci.c4
-rw-r--r--module.h8
-rw-r--r--types.c70
-rw-r--r--types.h19
-rw-r--r--vm.c9
10 files changed, 59 insertions, 77 deletions
diff --git a/lib.c b/lib.c
index ce09d99..6438bec 100644
--- a/lib.c
+++ b/lib.c
@@ -1490,7 +1490,7 @@ uc_printf(uc_vm *vm, size_t nargs)
static bool
uc_require_so(uc_vm *vm, const char *path, uc_value_t **res)
{
- void (*init)(uc_value_t *);
+ void (*init)(uc_vm *, uc_value_t *);
uc_value_t *scope;
struct stat st;
void *dlh;
@@ -1519,7 +1519,7 @@ uc_require_so(uc_vm *vm, const char *path, uc_value_t **res)
scope = ucv_object_new(vm);
- init(scope);
+ init(vm, scope);
*res = scope;
diff --git a/lib.h b/lib.h
index 2d27b04..5425da2 100644
--- a/lib.h
+++ b/lib.h
@@ -94,7 +94,7 @@ uc_to_int64(uc_value_t *v)
/* ressource type helper */
static inline uc_ressource_type_t *
-_uc_declare_type(const char *name, const uc_cfunction_list *list, size_t len, void (*freefn)(void *))
+_uc_declare_type(uc_vm *vm, const char *name, const uc_cfunction_list *list, size_t len, void (*freefn)(void *))
{
uc_value_t *proto = ucv_object_new(NULL);
@@ -102,11 +102,11 @@ _uc_declare_type(const char *name, const uc_cfunction_list *list, size_t len, vo
ucv_object_add(proto, list[len].name,
ucv_cfunction_new(list[len].name, list[len].func));
- return ucv_ressource_type_add(name, proto, freefn);
+ return ucv_ressource_type_add(vm, name, proto, freefn);
}
-#define uc_declare_type(name, functions, freefn) \
- _uc_declare_type(name, functions, ARRAY_SIZE(functions), freefn)
+#define uc_declare_type(vm, name, functions, freefn) \
+ _uc_declare_type(vm, name, functions, ARRAY_SIZE(functions), freefn)
/* prototype helper */
diff --git a/lib/fs.c b/lib/fs.c
index 4f96a6c..0c37aab 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -904,13 +904,13 @@ static void close_dir(void *ud)
closedir(dp);
}
-void uc_module_init(uc_value_t *scope)
+void uc_module_init(uc_vm *vm, uc_value_t *scope)
{
uc_add_proto_functions(scope, global_fns);
- proc_type = uc_declare_type("fs.proc", proc_fns, close_proc);
- file_type = uc_declare_type("fs.file", file_fns, close_file);
- dir_type = uc_declare_type("fs.dir", dir_fns, close_dir);
+ proc_type = uc_declare_type(vm, "fs.proc", proc_fns, close_proc);
+ file_type = uc_declare_type(vm, "fs.file", file_fns, close_file);
+ dir_type = uc_declare_type(vm, "fs.dir", dir_fns, close_dir);
ucv_object_add(scope, "stdin", uc_alloc_ressource(file_type, stdin));
ucv_object_add(scope, "stdout", uc_alloc_ressource(file_type, stdout));
diff --git a/lib/math.c b/lib/math.c
index 8f8466e..0adfaf8 100644
--- a/lib/math.c
+++ b/lib/math.c
@@ -158,7 +158,7 @@ static const uc_cfunction_list math_fns[] = {
{ "srand", uc_srand },
};
-void uc_module_init(uc_value_t *scope)
+void uc_module_init(uc_vm *vm, uc_value_t *scope)
{
uc_add_proto_functions(scope, math_fns);
}
diff --git a/lib/ubus.c b/lib/ubus.c
index 4d74710..fb7600a 100644
--- a/lib/ubus.c
+++ b/lib/ubus.c
@@ -320,9 +320,9 @@ static void close_connection(void *ud) {
free(conn);
}
-void uc_module_init(uc_value_t *scope)
+void uc_module_init(uc_vm *vm, uc_value_t *scope)
{
uc_add_proto_functions(scope, global_fns);
- conn_type = uc_declare_type("ubus.connection", conn_fns, close_connection);
+ conn_type = uc_declare_type(vm, "ubus.connection", conn_fns, close_connection);
}
diff --git a/lib/uci.c b/lib/uci.c
index 00a451c..d9a9ea6 100644
--- a/lib/uci.c
+++ b/lib/uci.c
@@ -1005,9 +1005,9 @@ static void close_uci(void *ud) {
uci_free_context((struct uci_context *)ud);
}
-void uc_module_init(uc_value_t *scope)
+void uc_module_init(uc_vm *vm, uc_value_t *scope)
{
uc_add_proto_functions(scope, global_fns);
- cursor_type = uc_declare_type("uci.cursor", cursor_fns, close_uci);
+ cursor_type = uc_declare_type(vm, "uci.cursor", cursor_fns, close_uci);
}
diff --git a/module.h b/module.h
index aa72074..b951e09 100644
--- a/module.h
+++ b/module.h
@@ -41,13 +41,13 @@
#define register_ressource(scope, key, res) \
json_object_object_add((scope)->header.jso, key, (res)->header.jso)
-void uc_module_init(uc_value_t *scope) __attribute__((weak));
+void uc_module_init(uc_vm *vm, uc_value_t *scope) __attribute__((weak));
-void uc_module_entry(uc_value_t *scope);
-void uc_module_entry(uc_value_t *scope)
+void uc_module_entry(uc_vm *vm, uc_value_t *scope);
+void uc_module_entry(uc_vm *vm, uc_value_t *scope)
{
if (uc_module_init)
- uc_module_init(scope);
+ uc_module_init(vm, scope);
}
#endif /* __MODULE_H_ */
diff --git a/types.c b/types.c
index d0f23f9..706ffd1 100644
--- a/types.c
+++ b/types.c
@@ -58,9 +58,6 @@ ucv_typename(uc_value_t *uv)
return "unknown";
}
-static uc_ressource_type_t *
-ucv_ressource_type_get(size_t type);
-
static void
ucv_unref(uc_weakref_t *ref)
{
@@ -248,7 +245,7 @@ ucv_free(uc_value_t *uv, bool retain)
case UC_RESSOURCE:
ressource = (uc_ressource_t *)uv;
- restype = ucv_ressource_type_get(ressource->type);
+ restype = ressource->type;
if (restype && restype->free)
restype->free(ressource->data);
@@ -945,44 +942,38 @@ ucv_closure_new(uc_vm *vm, uc_function_t *function, bool arrow_fn)
}
-static uc_ressource_types_t res_types;
-
uc_ressource_type_t *
-ucv_ressource_type_add(const char *name, uc_value_t *proto, void (*freefn)(void *))
+ucv_ressource_type_add(uc_vm *vm, const char *name, uc_value_t *proto, void (*freefn)(void *))
{
- uc_ressource_type_t *existing;
+ uc_ressource_type_t *type;
- existing = ucv_ressource_type_lookup(name);
+ type = ucv_ressource_type_lookup(vm, name);
- if (existing) {
+ if (type) {
ucv_put(proto);
- return existing;
+ return type;
}
- uc_vector_grow(&res_types);
+ type = xalloc(sizeof(*type));
+ type->name = name;
+ type->proto = proto;
+ type->free = freefn;
- res_types.entries[res_types.count].name = name;
- res_types.entries[res_types.count].proto = proto;
- res_types.entries[res_types.count].free = freefn;
-
- return &res_types.entries[res_types.count++];
-}
+ uc_vector_grow(&vm->restypes);
+ vm->restypes.entries[vm->restypes.count++] = type;
-static uc_ressource_type_t *
-ucv_ressource_type_get(size_t type)
-{
- return (type > 0 && type <= res_types.count) ? &res_types.entries[type - 1] : NULL;
+ return type;
}
uc_ressource_type_t *
-ucv_ressource_type_lookup(const char *name)
+ucv_ressource_type_lookup(uc_vm *vm, const char *name)
{
size_t i;
- for (i = 0; i < res_types.count; i++)
- if (!strcmp(res_types.entries[i].name, name))
- return &res_types.entries[i];
+ for (i = 0; i < vm->restypes.count; i++)
+ if (!strcmp(vm->restypes.entries[i]->name, name))
+ return vm->restypes.entries[i];
return NULL;
}
@@ -996,7 +987,7 @@ ucv_ressource_new(uc_ressource_type_t *type, void *data)
res = xalloc(sizeof(*res));
res->header.type = UC_RESSOURCE;
res->header.refcount = 1;
- res->type = type ? (type - res_types.entries) + 1 : 0;
+ res->type = type;
res->data = data;
return &res->header;
@@ -1006,15 +997,12 @@ void **
ucv_ressource_dataptr(uc_value_t *uv, const char *name)
{
uc_ressource_t *res = (uc_ressource_t *)uv;
- uc_ressource_type_t *type;
if (ucv_type(uv) != UC_RESSOURCE)
return NULL;
if (name) {
- type = ucv_ressource_type_lookup(name);
-
- if (!type || type != ucv_ressource_type_get(res->type))
+ if (!res->type || strcmp(res->type->name, name))
return NULL;
}
@@ -1104,7 +1092,7 @@ ucv_prototype_get(uc_value_t *uv)
case UC_RESSOURCE:
ressource = (uc_ressource_t *)uv;
- restype = ucv_ressource_type_get(ressource->type);
+ restype = ressource->type;
return restype ? restype->proto : NULL;
@@ -1628,7 +1616,7 @@ ucv_to_stringbuf_formatted(uc_vm *vm, uc_stringbuf_t *pb, uc_value_t *uv, size_t
case UC_RESSOURCE:
ressource = (uc_ressource_t *)uv;
- restype = ucv_ressource_type_get(ressource->type);
+ restype = ressource->type;
ucv_stringbuf_printf(pb, "%s<%s %p>%s",
json ? "\"" : "",
@@ -1813,19 +1801,3 @@ ucv_gc(uc_vm *vm, bool final)
}
}
}
-
-
-#ifdef __GNUC__
-
-__attribute__((destructor))
-static void ucv_ressource_types_free(void)
-{
- size_t i;
-
- for (i = 0; i < res_types.count; i++)
- ucv_put(res_types.entries[i].proto);
-
- uc_vector_clear(&res_types);
-}
-
-#endif
diff --git a/types.h b/types.h
index a4377ad..710f6fc 100644
--- a/types.h
+++ b/types.h
@@ -185,18 +185,18 @@ typedef struct {
} uc_cfunction_t;
typedef struct {
- uc_value_t header;
- size_t type;
- void *data;
-} uc_ressource_t;
-
-typedef struct {
const char *name;
uc_value_t *proto;
void (*free)(void *);
} uc_ressource_type_t;
-uc_declare_vector(uc_ressource_types_t, uc_ressource_type_t);
+typedef struct {
+ uc_value_t header;
+ uc_ressource_type_t *type;
+ void *data;
+} uc_ressource_t;
+
+uc_declare_vector(uc_ressource_types_t, uc_ressource_type_t *);
/* Parser definitions */
@@ -249,6 +249,7 @@ struct uc_vm {
uc_value_t *globals;
uc_source *sources;
uc_weakref_t values;
+ uc_ressource_types_t restypes;
union {
uint32_t u32;
int32_t s32;
@@ -339,8 +340,8 @@ uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t);
uc_value_t *ucv_closure_new(uc_vm *, uc_function_t *, bool);
-uc_ressource_type_t *ucv_ressource_type_add(const char *, uc_value_t *, void (*)(void *));
-uc_ressource_type_t *ucv_ressource_type_lookup(const char *);
+uc_ressource_type_t *ucv_ressource_type_add(uc_vm *, const char *, uc_value_t *, void (*)(void *));
+uc_ressource_type_t *ucv_ressource_type_lookup(uc_vm *, const char *);
uc_value_t *ucv_ressource_new(uc_ressource_type_t *, void *);
void **ucv_ressource_dataptr(uc_value_t *, const char *);
diff --git a/vm.c b/vm.c
index 083c418..abea567 100644
--- a/vm.c
+++ b/vm.c
@@ -126,6 +126,7 @@ void uc_vm_init(uc_vm *vm, uc_parse_config *config)
void uc_vm_free(uc_vm *vm)
{
uc_upvalref_t *ref;
+ size_t i;
ucv_put(vm->exception.stacktrace);
free(vm->exception.message);
@@ -136,6 +137,9 @@ void uc_vm_free(uc_vm *vm)
vm->open_upvals = ref;
}
+ for (i = 0; i < vm->restypes.count; i++)
+ ucv_put(vm->restypes.entries[i]->proto);
+
uc_vm_reset_callframes(vm);
uc_vm_reset_stack(vm);
uc_vector_clear(&vm->stack);
@@ -144,6 +148,11 @@ void uc_vm_free(uc_vm *vm)
printbuf_free(vm->strbuf);
ucv_gc(vm, true);
+
+ for (i = 0; i < vm->restypes.count; i++)
+ free(vm->restypes.entries[i]);
+
+ uc_vector_clear(&vm->restypes);
}
static uc_chunk *