diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-12-23 20:54:05 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-02-17 14:10:51 +0100 |
commit | 3756806674da909ec6dc10ad25862b592792604e (patch) | |
tree | f2af7e47f8444caaff0a5a33599f381889db24e3 /lib | |
parent | 77580a893283f2bde7ab46496bd3a3d7b2fc6784 (diff) |
treewide: rewrite ucode interpreter
Replace the former AST walking interpreter implementation with a single pass
bytecode compiler and a corresponding virtual machine.
The rewrite lays the groundwork for a couple of improvements with will be
subsequently implemented:
- Ability to precompile ucode sources into binary byte code
- Strippable debug information
- Reduced runtime memory usage
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs.c | 286 | ||||
-rw-r--r-- | lib/math.c | 155 | ||||
-rw-r--r-- | lib/ubus.c | 101 | ||||
-rw-r--r-- | lib/uci.c | 282 |
4 files changed, 376 insertions, 448 deletions
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Jo-Philipp Wich <jo@mein.io> + * Copyright (C) 2020-2021 Jo-Philipp Wich <jo@mein.io> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,8 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "../module.h" - #include <stdio.h> #include <errno.h> #include <string.h> @@ -25,16 +23,19 @@ #include <sys/types.h> #include <sys/sysmacros.h> +#include "../module.h" + #define err_return(err) do { last_error = err; return NULL; } while(0) -static const struct uc_ops *ops; +//static const uc_ops *ops; +static uc_ressource_type *file_type, *proc_type, *dir_type; static int last_error = 0; -static struct json_object * -uc_fs_error(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_error(uc_vm *vm, size_t nargs) { - struct json_object *errmsg; + json_object *errmsg; if (last_error == 0) return NULL; @@ -45,17 +46,17 @@ uc_fs_error(struct uc_state *s, uint32_t off, struct json_object *args) return errmsg; } -static struct json_object * -uc_fs_read_common(struct uc_state *s, uint32_t off, struct json_object *args, const char *type) +static json_object * +uc_fs_read_common(uc_vm *vm, size_t nargs, const char *type) { - struct json_object *limit = json_object_array_get_idx(args, 0); - struct json_object *rv = NULL; + json_object *limit = uc_get_arg(0); + json_object *rv = NULL; char buf[128], *p = NULL, *tmp; size_t rlen, len = 0; const char *lstr; int64_t lsize; - FILE **fp = (FILE **)ops->get_type(s->ctx, type); + FILE **fp = uc_get_self(type); if (!fp || !*fp) err_return(EBADF); @@ -137,14 +138,14 @@ uc_fs_read_common(struct uc_state *s, uint32_t off, struct json_object *args, co return rv; } -static struct json_object * -uc_fs_write_common(struct uc_state *s, uint32_t off, struct json_object *args, const char *type) +static json_object * +uc_fs_write_common(uc_vm *vm, size_t nargs, const char *type) { - struct json_object *data = json_object_array_get_idx(args, 0); + json_object *data = uc_get_arg(0); size_t len, wsize; const char *str; - FILE **fp = (FILE **)ops->get_type(s->ctx, type); + FILE **fp = uc_get_self(type); if (!fp || !*fp) err_return(EBADF); @@ -167,10 +168,10 @@ uc_fs_write_common(struct uc_state *s, uint32_t off, struct json_object *args, c } -static struct json_object * -uc_fs_pclose(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_pclose(uc_vm *vm, size_t nargs) { - FILE **fp = (FILE **)ops->get_type(s->ctx, "fs.proc"); + FILE **fp = uc_get_self("fs.proc"); int rc; if (!fp || !*fp) @@ -191,24 +192,23 @@ uc_fs_pclose(struct uc_state *s, uint32_t off, struct json_object *args) return xjs_new_int64(0); } -static struct json_object * -uc_fs_pread(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_pread(uc_vm *vm, size_t nargs) { - return uc_fs_read_common(s, off, args, "fs.proc"); + return uc_fs_read_common(vm, nargs, "fs.proc"); } -static struct json_object * -uc_fs_pwrite(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_pwrite(uc_vm *vm, size_t nargs) { - return uc_fs_write_common(s, off, args, "fs.proc"); + return uc_fs_write_common(vm, nargs, "fs.proc"); } -static struct json_object * -uc_fs_popen(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_popen(uc_vm *vm, size_t nargs) { - struct json_object *comm = json_object_array_get_idx(args, 0); - struct json_object *mode = json_object_array_get_idx(args, 1); - struct json_object *fo; + json_object *comm = uc_get_arg(0); + json_object *mode = uc_get_arg(1); FILE *fp; if (!json_object_is_type(comm, json_type_string)) @@ -220,21 +220,14 @@ uc_fs_popen(struct uc_state *s, uint32_t off, struct json_object *args) if (!fp) err_return(errno); - fo = json_object_new_object(); - - if (!fo) { - pclose(fp); - err_return(ENOMEM); - } - - return ops->set_type(fo, "fs.proc", fp); + return uc_alloc_ressource(proc_type, fp); } -static struct json_object * -uc_fs_close(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_close(uc_vm *vm, size_t nargs) { - FILE **fp = (FILE **)ops->get_type(s->ctx, "fs.file"); + FILE **fp = uc_get_self("fs.file"); if (!fp || !*fp) err_return(EBADF); @@ -245,27 +238,27 @@ uc_fs_close(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_read(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_read(uc_vm *vm, size_t nargs) { - return uc_fs_read_common(s, off, args, "fs.file"); + return uc_fs_read_common(vm, nargs, "fs.file"); } -static struct json_object * -uc_fs_write(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_write(uc_vm *vm, size_t nargs) { - return uc_fs_write_common(s, off, args, "fs.file"); + return uc_fs_write_common(vm, nargs, "fs.file"); } -static struct json_object * -uc_fs_seek(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_seek(uc_vm *vm, size_t nargs) { - struct json_object *ofs = json_object_array_get_idx(args, 0); - struct json_object *how = json_object_array_get_idx(args, 1); + json_object *ofs = uc_get_arg(0); + json_object *how = uc_get_arg(1); int whence, res; long offset; - FILE **fp = (FILE **)ops->get_type(s->ctx, "fs.file"); + FILE **fp = uc_get_self("fs.file"); if (!fp || !*fp) err_return(EBADF); @@ -292,12 +285,12 @@ uc_fs_seek(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_tell(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_tell(uc_vm *vm, size_t nargs) { long offset; - FILE **fp = (FILE **)ops->get_type(s->ctx, "fs.file"); + FILE **fp = uc_get_self("fs.file"); if (!fp || !*fp) err_return(EBADF); @@ -310,12 +303,11 @@ uc_fs_tell(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_int64(offset); } -static struct json_object * -uc_fs_open(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_open(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); - struct json_object *mode = json_object_array_get_idx(args, 1); - struct json_object *fo; + json_object *path = uc_get_arg(0); + json_object *mode = uc_get_arg(1); FILE *fp; if (!json_object_is_type(path, json_type_string)) @@ -327,21 +319,14 @@ uc_fs_open(struct uc_state *s, uint32_t off, struct json_object *args) if (!fp) err_return(errno); - fo = json_object_new_object(); - - if (!fo) { - fclose(fp); - err_return(ENOMEM); - } - - return ops->set_type(fo, "fs.file", fp); + return uc_alloc_ressource(file_type, fp); } -static struct json_object * -uc_fs_readdir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_readdir(uc_vm *vm, size_t nargs) { - DIR **dp = (DIR **)ops->get_type(s->ctx, "fs.dir"); + DIR **dp = uc_get_self("fs.dir"); struct dirent *e; if (!dp || !*dp) @@ -356,10 +341,10 @@ uc_fs_readdir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_string(e->d_name); } -static struct json_object * -uc_fs_telldir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_telldir(uc_vm *vm, size_t nargs) { - DIR **dp = (DIR **)ops->get_type(s->ctx, "fs.dir"); + DIR **dp = uc_get_self("fs.dir"); long position; if (!dp || !*dp) @@ -373,11 +358,11 @@ uc_fs_telldir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_int64((int64_t)position); } -static struct json_object * -uc_fs_seekdir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_seekdir(uc_vm *vm, size_t nargs) { - struct json_object *ofs = json_object_array_get_idx(args, 0); - DIR **dp = (DIR **)ops->get_type(s->ctx, "fs.dir"); + json_object *ofs = uc_get_arg(0); + DIR **dp = uc_get_self("fs.dir"); long position; if (!json_object_is_type(ofs, json_type_int)) @@ -393,10 +378,10 @@ uc_fs_seekdir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_closedir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_closedir(uc_vm *vm, size_t nargs) { - DIR **dp = (DIR **)ops->get_type(s->ctx, "fs.dir"); + DIR **dp = uc_get_self("fs.dir"); if (!dp || !*dp) err_return(EBADF); @@ -407,11 +392,10 @@ uc_fs_closedir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_opendir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_opendir(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); - struct json_object *diro; + json_object *path = uc_get_arg(0); DIR *dp; if (!json_object_is_type(path, json_type_string)) @@ -422,21 +406,14 @@ uc_fs_opendir(struct uc_state *s, uint32_t off, struct json_object *args) if (!dp) err_return(errno); - diro = json_object_new_object(); - - if (!diro) { - closedir(dp); - err_return(ENOMEM); - } - - return ops->set_type(diro, "fs.dir", dp); + return uc_alloc_ressource(dir_type, dp); } -static struct json_object * -uc_fs_readlink(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_readlink(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); - struct json_object *res; + json_object *path = uc_get_arg(0); + json_object *res; ssize_t buflen = 0, rv; char *buf = NULL, *tmp; @@ -472,11 +449,11 @@ uc_fs_readlink(struct uc_state *s, uint32_t off, struct json_object *args) return res; } -static struct json_object * -uc_fs_stat_common(struct uc_state *s, uint32_t off, struct json_object *args, bool use_lstat) +static json_object * +uc_fs_stat_common(uc_vm *vm, size_t nargs, bool use_lstat) { - struct json_object *path = json_object_array_get_idx(args, 0); - struct json_object *res, *o; + json_object *path = uc_get_arg(0); + json_object *res, *o; struct stat st; int rv; @@ -556,23 +533,23 @@ uc_fs_stat_common(struct uc_state *s, uint32_t off, struct json_object *args, bo return res; } -static struct json_object * -uc_fs_stat(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_stat(uc_vm *vm, size_t nargs) { - return uc_fs_stat_common(s, off, args, false); + return uc_fs_stat_common(vm, nargs, false); } -static struct json_object * -uc_fs_lstat(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_lstat(uc_vm *vm, size_t nargs) { - return uc_fs_stat_common(s, off, args, true); + return uc_fs_stat_common(vm, nargs, true); } -static struct json_object * -uc_fs_mkdir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_mkdir(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); - struct json_object *mode = json_object_array_get_idx(args, 1); + json_object *path = uc_get_arg(0); + json_object *mode = uc_get_arg(1); if (!json_object_is_type(path, json_type_string) || (mode && !json_object_is_type(mode, json_type_int))) @@ -584,10 +561,10 @@ uc_fs_mkdir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_rmdir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_rmdir(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); + json_object *path = uc_get_arg(0); if (!json_object_is_type(path, json_type_string)) err_return(EINVAL); @@ -598,11 +575,11 @@ uc_fs_rmdir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_symlink(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_symlink(uc_vm *vm, size_t nargs) { - struct json_object *dest = json_object_array_get_idx(args, 0); - struct json_object *path = json_object_array_get_idx(args, 1); + json_object *dest = uc_get_arg(0); + json_object *path = uc_get_arg(1); if (!json_object_is_type(dest, json_type_string) || !json_object_is_type(path, json_type_string)) @@ -614,10 +591,10 @@ uc_fs_symlink(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_unlink(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_unlink(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); + json_object *path = uc_get_arg(0); if (!json_object_is_type(path, json_type_string)) err_return(EINVAL); @@ -628,10 +605,10 @@ uc_fs_unlink(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_fs_getcwd(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_getcwd(uc_vm *vm, size_t nargs) { - struct json_object *res; + json_object *res; char *buf = NULL, *tmp; size_t buflen = 0; @@ -663,10 +640,10 @@ uc_fs_getcwd(struct uc_state *s, uint32_t off, struct json_object *args) return res; } -static struct json_object * -uc_fs_chdir(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_fs_chdir(uc_vm *vm, size_t nargs) { - struct json_object *path = json_object_array_get_idx(args, 0); + json_object *path = uc_get_arg(0); if (!json_object_is_type(path, json_type_string)) err_return(EINVAL); @@ -677,13 +654,13 @@ uc_fs_chdir(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static const struct { const char *name; uc_c_fn *func; } proc_fns[] = { +static const uc_cfunction_list proc_fns[] = { { "read", uc_fs_pread }, { "write", uc_fs_pwrite }, { "close", uc_fs_pclose }, }; -static const struct { const char *name; uc_c_fn *func; } file_fns[] = { +static const uc_cfunction_list file_fns[] = { { "read", uc_fs_read }, { "write", uc_fs_write }, { "seek", uc_fs_seek }, @@ -691,14 +668,14 @@ static const struct { const char *name; uc_c_fn *func; } file_fns[] = { { "close", uc_fs_close }, }; -static const struct { const char *name; uc_c_fn *func; } dir_fns[] = { +static const uc_cfunction_list dir_fns[] = { { "read", uc_fs_readdir }, { "seek", uc_fs_seekdir }, { "tell", uc_fs_telldir }, { "close", uc_fs_closedir }, }; -static const struct { const char *name; uc_c_fn *func; } global_fns[] = { +static const uc_cfunction_list global_fns[] = { { "error", uc_fs_error }, { "open", uc_fs_open }, { "opendir", uc_fs_opendir }, @@ -715,40 +692,39 @@ static const struct { const char *name; uc_c_fn *func; } global_fns[] = { }; -static void close_proc(void *ud) { - pclose((FILE *)ud); +static void close_proc(void *ud) +{ + FILE *fp = ud; + + if (fp) + pclose(fp); } -static void close_file(void *ud) { +static void close_file(void *ud) +{ FILE *fp = ud; - if (fp != stdin && fp != stdout && fp != stderr) + if (fp && fp != stdin && fp != stdout && fp != stderr) fclose(fp); } -static void close_dir(void *ud) { - closedir((DIR *)ud); -} - -void uc_module_init(const struct uc_ops *ut, struct uc_state *s, struct json_object *scope) +static void close_dir(void *ud) { - struct json_object *proc_proto, *file_proto, *dir_proto; + DIR *dp = ud; - ops = ut; - proc_proto = ops->new_object(NULL); - file_proto = ops->new_object(NULL); - dir_proto = ops->new_object(NULL); + if (dp) + closedir(dp); +} - register_functions(s, ops, global_fns, scope); - register_functions(s, ops, proc_fns, proc_proto); - register_functions(s, ops, file_fns, file_proto); - register_functions(s, ops, dir_fns, dir_proto); +void uc_module_init(uc_prototype *scope) +{ + uc_add_proto_functions(scope, global_fns); - ops->register_type("fs.proc", proc_proto, close_proc); - ops->register_type("fs.file", file_proto, close_file); - ops->register_type("fs.dir", dir_proto, close_dir); + 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); - json_object_object_add(scope, "stdin", ops->set_type(xjs_new_object(), "fs.file", stdin)); - json_object_object_add(scope, "stdout", ops->set_type(xjs_new_object(), "fs.file", stdout)); - json_object_object_add(scope, "stderr", ops->set_type(xjs_new_object(), "fs.file", stderr)); + uc_add_proto_val(scope, "stdin", uc_alloc_ressource(file_type, stdin)); + uc_add_proto_val(scope, "stdout", uc_alloc_ressource(file_type, stdout)); + uc_add_proto_val(scope, "stderr", uc_alloc_ressource(file_type, stderr)); } @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Jo-Philipp Wich <jo@mein.io> + * Copyright (C) 2020-2021 Jo-Philipp Wich <jo@mein.io> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,172 +14,151 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "../module.h" - #include <math.h> #include <sys/time.h> -static const struct uc_ops *ops; - -static double -to_double(struct json_object *v) -{ - int64_t n; - double d; - - return (ops->cast_number(v, &n, &d) == json_type_double) ? d : (double)n; -} - -static int64_t -to_int64(struct json_object *v) -{ - int64_t n; - double d; +#include "../module.h" - return (ops->cast_number(v, &n, &d) == json_type_double) ? (int64_t)d : n; -} +static bool srand_called = false; -static struct json_object * -uc_abs(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_abs(uc_vm *vm, size_t nargs) { - struct json_object *v = json_object_array_get_idx(args, 0); + json_object *v = uc_get_arg(0); enum json_type t; int64_t n; double d; if (json_object_is_type(v, json_type_null)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - t = ops->cast_number(v, &n, &d); + t = uc_to_number(v, &n, &d); if (t == json_type_double) - return (isnan(d) || d < 0) ? ops->new_double(-d) : json_object_get(v); + return (isnan(d) || d < 0) ? uc_alloc_double(-d) : json_object_get(v); return (n < 0) ? json_object_new_int64(-n) : json_object_get(v); } -static struct json_object * -uc_atan2(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_atan2(uc_vm *vm, size_t nargs) { - double d1 = to_double(json_object_array_get_idx(args, 0)); - double d2 = to_double(json_object_array_get_idx(args, 1)); + double d1 = uc_to_double(uc_get_arg(0)); + double d2 = uc_to_double(uc_get_arg(1)); if (isnan(d1) || isnan(d2)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(atan2(d1, d2)); + return uc_alloc_double(atan2(d1, d2)); } -static struct json_object * -uc_cos(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_cos(uc_vm *vm, size_t nargs) { - double d = to_double(json_object_array_get_idx(args, 0)); + double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(cos(d)); + return uc_alloc_double(cos(d)); } -static struct json_object * -uc_exp(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_exp(uc_vm *vm, size_t nargs) { - double d = to_double(json_object_array_get_idx(args, 0)); + double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(exp(d)); + return uc_alloc_double(exp(d)); } -static struct json_object * -uc_log(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_log(uc_vm *vm, size_t nargs) { - double d = to_double(json_object_array_get_idx(args, 0)); + double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(log(d)); + return uc_alloc_double(log(d)); } -static struct json_object * -uc_sin(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_sin(uc_vm *vm, size_t nargs) { - double d = to_double(json_object_array_get_idx(args, 0)); + double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(sin(d)); + return uc_alloc_double(sin(d)); } -static struct json_object * -uc_sqrt(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_sqrt(uc_vm *vm, size_t nargs) { - double d = to_double(json_object_array_get_idx(args, 0)); + double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(sqrt(d)); + return uc_alloc_double(sqrt(d)); } -static struct json_object * -uc_pow(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_pow(uc_vm *vm, size_t nargs) { - double x = to_double(json_object_array_get_idx(args, 0)); - double y = to_double(json_object_array_get_idx(args, 1)); + double x = uc_to_double(uc_get_arg(0)); + double y = uc_to_double(uc_get_arg(1)); if (isnan(x) || isnan(y)) - return ops->new_double(NAN); + return uc_alloc_double(NAN); - return ops->new_double(pow(x, y)); + return uc_alloc_double(pow(x, y)); } -static struct json_object * -uc_rand(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_rand(uc_vm *vm, size_t nargs) { struct timeval tv; - if (!s->srand_called) { + if (!srand_called) { gettimeofday(&tv, NULL); srand((tv.tv_sec * 1000) + (tv.tv_usec / 1000)); - s->srand_called = true; + srand_called = true; } return json_object_new_int64(rand()); } -static struct json_object * -uc_srand(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_srand(uc_vm *vm, size_t nargs) { - - int64_t n = to_int64(json_object_array_get_idx(args, 0)); + int64_t n = uc_to_int64(uc_get_arg(0)); srand((unsigned int)n); - s->srand_called = true; + srand_called = true; return NULL; } -static const struct { const char *name; uc_c_fn *func; } global_fns[] = { - { "abs", uc_abs }, - { "atan2", uc_atan2 }, - { "cos", uc_cos }, - { "exp", uc_exp }, - { "log", uc_log }, - { "sin", uc_sin }, - { "sqrt", uc_sqrt }, - { "pow", uc_pow }, - { "rand", uc_rand }, - { "srand", uc_srand }, +static const uc_cfunction_list math_fns[] = { + { "abs", uc_abs }, + { "atan2", uc_atan2 }, + { "cos", uc_cos }, + { "exp", uc_exp }, + { "log", uc_log }, + { "sin", uc_sin }, + { "sqrt", uc_sqrt }, + { "pow", uc_pow }, + { "rand", uc_rand }, + { "srand", uc_srand }, }; -void uc_module_init(const struct uc_ops *ut, struct uc_state *s, struct json_object *scope) +void uc_module_init(uc_prototype *scope) { - ops = ut; - - register_functions(s, ops, global_fns, scope); + uc_add_proto_functions(scope, math_fns); } @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Jo-Philipp Wich <jo@mein.io> + * Copyright (C) 2020-2021 Jo-Philipp Wich <jo@mein.io> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,29 +14,28 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "../module.h" - #include <unistd.h> #include <libubus.h> #include <libubox/blobmsg.h> #include <libubox/blobmsg_json.h> -#define err_return(err) do { last_error = err; return NULL; } while(0) +#include "../module.h" -static const struct uc_ops *ops; +#define err_return(err) do { last_error = err; return NULL; } while(0) static enum ubus_msg_status last_error = 0; +static uc_ressource_type *conn_type; -struct ubus_connection { +typedef struct { int timeout; struct blob_buf buf; struct ubus_context *ctx; -}; +} ubus_connection; -static struct json_object * -uc_ubus_error(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_ubus_error(uc_vm *vm, size_t nargs) { - struct json_object *errmsg; + json_object *errmsg; if (last_error == 0) return NULL; @@ -47,14 +46,14 @@ uc_ubus_error(struct uc_state *s, uint32_t off, struct json_object *args) return errmsg; } -static struct json_object * +static json_object * uc_blob_to_json(struct blob_attr *attr, bool table, const char **name); -static struct json_object * +static json_object * uc_blob_array_to_json(struct blob_attr *attr, size_t len, bool table) { - struct json_object *o = table ? json_object_new_object() : json_object_new_array(); - struct json_object *v; + json_object *o = table ? json_object_new_object() : json_object_new_array(); + json_object *v; struct blob_attr *pos; size_t rem = len; const char *name; @@ -77,7 +76,7 @@ uc_blob_array_to_json(struct blob_attr *attr, size_t len, bool table) return o; } -static struct json_object * +static json_object * uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) { void *data; @@ -131,13 +130,13 @@ uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) } -static struct json_object * -uc_ubus_connect(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_ubus_connect(uc_vm *vm, size_t nargs) { - struct json_object *socket = json_object_array_get_idx(args, 0); - struct json_object *timeout = json_object_array_get_idx(args, 1); - struct json_object *co; - struct ubus_connection *c; + json_object *socket = uc_get_arg(0); + json_object *timeout = uc_get_arg(1); + json_object *co; + ubus_connection *c; if ((socket && !json_object_is_type(socket, json_type_string)) || (timeout && !json_object_is_type(timeout, json_type_int))) @@ -169,14 +168,14 @@ uc_ubus_connect(struct uc_state *s, uint32_t off, struct json_object *args) ubus_add_uloop(c->ctx); - return ops->set_type(co, "ubus.connection", c); + return uc_alloc_ressource(conn_type, c); } static void uc_ubus_signatures_cb(struct ubus_context *c, struct ubus_object_data *o, void *p) { - struct json_object *arr = p; - struct json_object *sig; + json_object *arr = p; + json_object *sig; if (!o->signature) return; @@ -190,8 +189,8 @@ uc_ubus_signatures_cb(struct ubus_context *c, struct ubus_object_data *o, void * static void uc_ubus_objects_cb(struct ubus_context *c, struct ubus_object_data *o, void *p) { - struct json_object *arr = p; - struct json_object *obj; + json_object *arr = p; + json_object *obj; obj = json_object_new_string(o->path); @@ -199,12 +198,12 @@ uc_ubus_objects_cb(struct ubus_context *c, struct ubus_object_data *o, void *p) json_object_array_add(arr, obj); } -static struct json_object * -uc_ubus_list(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_ubus_list(uc_vm *vm, size_t nargs) { - struct ubus_connection **c = (struct ubus_connection **)ops->get_type(s->ctx, "ubus.connection"); - struct json_object *objname = json_object_array_get_idx(args, 0); - struct json_object *res = NULL; + ubus_connection **c = uc_get_self("ubus.connection"); + json_object *objname = uc_get_arg(0); + json_object *res = NULL; enum ubus_msg_status rv; if (!c || !*c || !(*c)->ctx) @@ -232,19 +231,19 @@ uc_ubus_list(struct uc_state *s, uint32_t off, struct json_object *args) static void uc_ubus_call_cb(struct ubus_request *req, int type, struct blob_attr *msg) { - struct json_object **res = (struct json_object **)req->priv; + json_object **res = (json_object **)req->priv; *res = msg ? uc_blob_array_to_json(blob_data(msg), blob_len(msg), true) : NULL; } -static struct json_object * -uc_ubus_call(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_ubus_call(uc_vm *vm, size_t nargs) { - struct ubus_connection **c = (struct ubus_connection **)ops->get_type(s->ctx, "ubus.connection"); - struct json_object *objname = json_object_array_get_idx(args, 0); - struct json_object *funname = json_object_array_get_idx(args, 1); - struct json_object *funargs = json_object_array_get_idx(args, 2); - struct json_object *res = NULL; + ubus_connection **c = uc_get_self("ubus.connection"); + json_object *objname = uc_get_arg(0); + json_object *funname = uc_get_arg(1); + json_object *funargs = uc_get_arg(2); + json_object *res = NULL; enum ubus_msg_status rv; uint32_t id; @@ -275,10 +274,10 @@ uc_ubus_call(struct uc_state *s, uint32_t off, struct json_object *args) return res; } -static struct json_object * -uc_ubus_disconnect(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_ubus_disconnect(uc_vm *vm, size_t nargs) { - struct ubus_connection **c = (struct ubus_connection **)ops->get_type(s->ctx, "ubus.connection"); + ubus_connection **c = uc_get_self("ubus.connection"); if (!c || !*c || !(*c)->ctx) err_return(UBUS_STATUS_CONNECTION_FAILED); @@ -290,12 +289,12 @@ uc_ubus_disconnect(struct uc_state *s, uint32_t off, struct json_object *args) } -static const struct { const char *name; uc_c_fn *func; } global_fns[] = { +static const uc_cfunction_list global_fns[] = { { "error", uc_ubus_error }, { "connect", uc_ubus_connect }, }; -static const struct { const char *name; uc_c_fn *func; } conn_fns[] = { +static const uc_cfunction_list conn_fns[] = { { "list", uc_ubus_list }, { "call", uc_ubus_call }, { "disconnect", uc_ubus_disconnect }, @@ -303,7 +302,7 @@ static const struct { const char *name; uc_c_fn *func; } conn_fns[] = { static void close_connection(void *ud) { - struct ubus_connection *conn = ud; + ubus_connection *conn = ud; blob_buf_free(&conn->buf); @@ -313,15 +312,9 @@ static void close_connection(void *ud) { free(conn); } -void uc_module_init(const struct uc_ops *ut, struct uc_state *s, struct json_object *scope) +void uc_module_init(uc_prototype *scope) { - struct json_object *conn_proto; - - ops = ut; - conn_proto = ops->new_object(NULL); - - register_functions(s, ops, global_fns, scope); - register_functions(s, ops, conn_fns, conn_proto); + uc_add_proto_functions(scope, global_fns); - ops->register_type("ubus.connection", conn_proto, close_connection); + conn_type = uc_declare_type("ubus.connection", conn_fns, close_connection); } @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Jo-Philipp Wich <jo@mein.io> + * Copyright (C) 2020-2021 Jo-Philipp Wich <jo@mein.io> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,16 +14,15 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "../module.h" - #include <string.h> #include <uci.h> -#define err_return(err) do { last_error = err; return NULL; } while(0) +#include "../module.h" -static const struct uc_ops *ops; +#define err_return(err) do { last_error = err; return NULL; } while(0) static int last_error = 0; +static uc_ressource_type *cursor_type; enum pkg_cmd { CMD_SAVE, @@ -31,11 +30,11 @@ enum pkg_cmd { CMD_REVERT }; -static struct json_object * -uc_uci_error(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_error(uc_vm *vm, size_t nargs) { char buf[sizeof("Unknown error: -9223372036854775808")]; - struct json_object *errmsg; + json_object *errmsg; const char *errstr[] = { [UCI_ERR_MEM] = "Out of memory", @@ -64,12 +63,11 @@ uc_uci_error(struct uc_state *s, uint32_t off, struct json_object *args) } -static struct json_object * -uc_uci_cursor(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_cursor(uc_vm *vm, size_t nargs) { - struct json_object *cdir = json_object_array_get_idx(args, 0); - struct json_object *sdir = json_object_array_get_idx(args, 1); - struct json_object *co; + json_object *cdir = uc_get_arg(0); + json_object *sdir = uc_get_arg(1); struct uci_context *c; int rv; @@ -96,22 +94,15 @@ uc_uci_cursor(struct uc_state *s, uint32_t off, struct json_object *args) err_return(rv); } - co = json_object_new_object(); - - if (!co) { - uci_free_context(c); - err_return(UCI_ERR_MEM); - } - - return ops->set_type(co, "uci.cursor", c); + return uc_alloc_ressource(cursor_type, c); } -static struct json_object * -uc_uci_load(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_load(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); struct uci_element *e; if (!c || !*c) @@ -133,11 +124,11 @@ uc_uci_load(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_uci_unload(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_unload(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); struct uci_element *e; if (!c || !*c) @@ -186,10 +177,10 @@ lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, bool extended) return uci_lookup_ptr(ctx, ptr, NULL, extended); } -static struct json_object * +static json_object * option_to_json(struct uci_option *o) { - struct json_object *arr; + json_object *arr; struct uci_element *e; switch (o->type) { @@ -210,10 +201,10 @@ option_to_json(struct uci_option *o) } } -static struct json_object * +static json_object * section_to_json(struct uci_section *s, int index) { - struct json_object *so = json_object_new_object(); + json_object *so = json_object_new_object(); struct uci_element *e; struct uci_option *o; @@ -235,11 +226,11 @@ section_to_json(struct uci_section *s, int index) return so; } -static struct json_object * +static json_object * package_to_json(struct uci_package *p) { - struct json_object *po = json_object_new_object(); - struct json_object *so; + json_object *po = json_object_new_object(); + json_object *so; struct uci_element *e; int i = 0; @@ -254,13 +245,13 @@ package_to_json(struct uci_package *p) return po; } -static struct json_object * -uc_uci_get_any(struct uc_state *s, uint32_t off, struct json_object *args, bool all) +static json_object * +uc_uci_get_any(uc_vm *vm, size_t nargs, bool all) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *sect = json_object_array_get_idx(args, 1); - struct json_object *opt = json_object_array_get_idx(args, 2); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *sect = uc_get_arg(1); + json_object *opt = uc_get_arg(2); struct uci_ptr ptr = {}; int rv; @@ -314,25 +305,25 @@ uc_uci_get_any(struct uc_state *s, uint32_t off, struct json_object *args, bool return json_object_new_string(ptr.s->type); } -static struct json_object * -uc_uci_get(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_get(uc_vm *vm, size_t nargs) { - return uc_uci_get_any(s, off, args, false); + return uc_uci_get_any(vm, nargs, false); } -static struct json_object * -uc_uci_get_all(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_get_all(uc_vm *vm, size_t nargs) { - return uc_uci_get_any(s, off, args, true); + return uc_uci_get_any(vm, nargs, true); } -static struct json_object * -uc_uci_get_first(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_get_first(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *type = json_object_array_get_idx(args, 1); - struct json_object *opt = json_object_array_get_idx(args, 2); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *type = uc_get_arg(1); + json_object *opt = uc_get_arg(2); struct uci_package *p = NULL; struct uci_section *sc; struct uci_element *e; @@ -384,12 +375,12 @@ uc_uci_get_first(struct uc_state *s, uint32_t off, struct json_object *args) err_return(UCI_ERR_NOTFOUND); } -static struct json_object * -uc_uci_add(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_add(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *type = json_object_array_get_idx(args, 1); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *type = uc_get_arg(1); struct uci_element *e = NULL; struct uci_package *p = NULL; struct uci_section *sc = NULL; @@ -420,9 +411,9 @@ uc_uci_add(struct uc_state *s, uint32_t off, struct json_object *args) } static bool -json_to_value(struct json_object *val, const char **p, bool *is_list) +json_to_value(json_object *val, const char **p, bool *is_list) { - struct json_object *item; + json_object *item; *p = NULL; @@ -463,13 +454,13 @@ json_to_value(struct json_object *val, const char **p, bool *is_list) } } -static struct json_object * -uc_uci_set(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_set(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *sect = json_object_array_get_idx(args, 1); - struct json_object *opt = NULL, *val = NULL; + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *sect = uc_get_arg(1); + json_object *opt = NULL, *val = NULL; struct uci_ptr ptr = {}; bool is_list = false; int rv, i; @@ -478,11 +469,11 @@ uc_uci_set(struct uc_state *s, uint32_t off, struct json_object *args) !json_object_is_type(sect, json_type_string)) err_return(UCI_ERR_INVAL); - switch (json_object_array_length(args)) { + switch (nargs) { /* conf, sect, opt, val */ case 4: - opt = json_object_array_get_idx(args, 2); - val = json_object_array_get_idx(args, 3); + opt = uc_get_arg(2); + val = uc_get_arg(3); if (!json_object_is_type(opt, json_type_string)) err_return(UCI_ERR_INVAL); @@ -491,7 +482,7 @@ uc_uci_set(struct uc_state *s, uint32_t off, struct json_object *args) /* conf, sect, type */ case 3: - val = json_object_array_get_idx(args, 2); + val = uc_get_arg(2); if (!json_object_is_type(val, json_type_string)) err_return(UCI_ERR_INVAL); @@ -563,13 +554,13 @@ uc_uci_set(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_uci_delete(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_delete(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *sect = json_object_array_get_idx(args, 1); - struct json_object *opt = json_object_array_get_idx(args, 2); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *sect = uc_get_arg(1); + json_object *opt = uc_get_arg(2); struct uci_ptr ptr = {}; int rv; @@ -598,13 +589,13 @@ uc_uci_delete(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_uci_rename(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_rename(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *sect = json_object_array_get_idx(args, 1); - struct json_object *opt = NULL, *val = NULL; + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *sect = uc_get_arg(1); + json_object *opt = NULL, *val = NULL; struct uci_ptr ptr = {}; int rv; @@ -612,11 +603,11 @@ uc_uci_rename(struct uc_state *s, uint32_t off, struct json_object *args) !json_object_is_type(sect, json_type_string)) err_return(UCI_ERR_INVAL); - switch (json_object_array_length(args)) { + switch (nargs) { /* conf, sect, opt, val */ case 4: - opt = json_object_array_get_idx(args, 2); - val = json_object_array_get_idx(args, 3); + opt = uc_get_arg(2); + val = uc_get_arg(3); if (!json_object_is_type(opt, json_type_string) || !json_object_is_type(val, json_type_string)) @@ -626,7 +617,7 @@ uc_uci_rename(struct uc_state *s, uint32_t off, struct json_object *args) /* conf, sect, type */ case 3: - val = json_object_array_get_idx(args, 2); + val = uc_get_arg(2); if (!json_object_is_type(val, json_type_string)) err_return(UCI_ERR_INVAL); @@ -658,13 +649,13 @@ uc_uci_rename(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_uci_reorder(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_reorder(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *sect = json_object_array_get_idx(args, 1); - struct json_object *val = json_object_array_get_idx(args, 2); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *sect = uc_get_arg(1); + json_object *val = uc_get_arg(2); struct uci_ptr ptr = {}; int64_t n; int rv; @@ -698,11 +689,11 @@ uc_uci_reorder(struct uc_state *s, uint32_t off, struct json_object *args) return json_object_new_boolean(true); } -static struct json_object * -uc_uci_pkg_command(struct uc_state *s, uint32_t off, struct json_object *args, enum pkg_cmd cmd) +static json_object * +uc_uci_pkg_command(uc_vm *vm, size_t nargs, enum pkg_cmd cmd) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); struct uci_element *e, *tmp; struct uci_package *p; struct uci_ptr ptr = {}; @@ -748,25 +739,25 @@ uc_uci_pkg_command(struct uc_state *s, uint32_t off, struct json_object *args, e return json_object_new_boolean(true); } -static struct json_object * -uc_uci_save(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_save(uc_vm *vm, size_t nargs) { - return uc_uci_pkg_command(s, off, args, CMD_SAVE); + return uc_uci_pkg_command(vm, nargs, CMD_SAVE); } -static struct json_object * -uc_uci_commit(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_commit(uc_vm *vm, size_t nargs) { - return uc_uci_pkg_command(s, off, args, CMD_COMMIT); + return uc_uci_pkg_command(vm, nargs, CMD_COMMIT); } -static struct json_object * -uc_uci_revert(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_revert(uc_vm *vm, size_t nargs) { - return uc_uci_pkg_command(s, off, args, CMD_REVERT); + return uc_uci_pkg_command(vm, nargs, CMD_REVERT); } -static struct json_object * +static json_object * change_to_json(struct uci_delta *d) { const char *types[] = { @@ -779,7 +770,7 @@ change_to_json(struct uci_delta *d) [UCI_CMD_CHANGE] = "set", }; - struct json_object *a; + json_object *a; if (!d->section) return NULL; @@ -805,10 +796,10 @@ change_to_json(struct uci_delta *d) return a; } -static struct json_object * +static json_object * changes_to_json(struct uci_context *ctx, const char *package) { - struct json_object *a = NULL, *c; + json_object *a = NULL, *c; struct uci_package *p = NULL; struct uci_element *e; bool unload = false; @@ -855,12 +846,12 @@ changes_to_json(struct uci_context *ctx, const char *package) return a; } -static struct json_object * -uc_uci_changes(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_changes(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *res, *chg; + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *res, *chg; char **configs; int rv, i; @@ -894,17 +885,18 @@ uc_uci_changes(struct uc_state *s, uint32_t off, struct json_object *args) return res; } -static struct json_object * -uc_uci_foreach(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_foreach(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *conf = json_object_array_get_idx(args, 0); - struct json_object *type = json_object_array_get_idx(args, 1); - struct json_object *func = json_object_array_get_idx(args, 2); - struct json_object *fnargs, *rv = NULL; + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *conf = uc_get_arg(0); + json_object *type = uc_get_arg(1); + json_object *func = uc_get_arg(2); + json_object *rv = NULL; struct uci_package *p = NULL; struct uci_element *e, *tmp; struct uci_section *sc; + uc_exception_type_t ex; bool stop = false; bool ret = false; int i = 0; @@ -924,11 +916,6 @@ uc_uci_foreach(struct uc_state *s, uint32_t off, struct json_object *args) if (!p) err_return(UCI_ERR_NOTFOUND); - fnargs = json_object_new_array(); - - if (!fnargs) - err_return(UCI_ERR_MEM); - uci_foreach_element_safe(&p->sections, tmp, e) { sc = uci_to_section(e); i++; @@ -936,18 +923,17 @@ uc_uci_foreach(struct uc_state *s, uint32_t off, struct json_object *args) if (type && strcmp(sc->type, json_object_get_string(type))) continue; - json_object_array_put_idx(fnargs, 0, section_to_json(sc, i - 1)); - - rv = ops->invoke(s, off, NULL, func, fnargs); + uc_push_val(uc_value_get(func)); + uc_push_val(section_to_json(sc, i - 1)); - /* forward exceptions from callback function */ - if (uc_is_type(rv, T_EXCEPTION)) { - json_object_put(fnargs); + ex = uc_call(1); - return rv; - } + /* stop on exception in callback */ + if (ex) + break; ret = true; + rv = uc_pop_val(); stop = (json_object_is_type(rv, json_type_boolean) && !json_object_get_boolean(rv)); json_object_put(rv); @@ -956,16 +942,16 @@ uc_uci_foreach(struct uc_state *s, uint32_t off, struct json_object *args) break; } - json_object_put(fnargs); + /* XXX: rethrow */ return json_object_new_boolean(ret); } -static struct json_object * -uc_uci_configs(struct uc_state *s, uint32_t off, struct json_object *args) +static json_object * +uc_uci_configs(uc_vm *vm, size_t nargs) { - struct uci_context **c = (struct uci_context **)ops->get_type(s->ctx, "uci.cursor"); - struct json_object *a; + struct uci_context **c = uc_get_self("uci.cursor"); + json_object *a; char **configs; int i, rv; @@ -990,7 +976,7 @@ uc_uci_configs(struct uc_state *s, uint32_t off, struct json_object *args) } -static const struct { const char *name; uc_c_fn *func; } cursor_fns[] = { +static const uc_cfunction_list cursor_fns[] = { { "load", uc_uci_load }, { "unload", uc_uci_unload }, { "get", uc_uci_get }, @@ -1009,7 +995,7 @@ static const struct { const char *name; uc_c_fn *func; } cursor_fns[] = { { "configs", uc_uci_configs }, }; -static const struct { const char *name; uc_c_fn *func; } global_fns[] = { +static const uc_cfunction_list global_fns[] = { { "error", uc_uci_error }, { "cursor", uc_uci_cursor }, }; @@ -1019,15 +1005,9 @@ static void close_uci(void *ud) { uci_free_context((struct uci_context *)ud); } -void uc_module_init(const struct uc_ops *ut, struct uc_state *s, struct json_object *scope) +void uc_module_init(uc_prototype *scope) { - struct json_object *uci_proto; - - ops = ut; - uci_proto = ops->new_object(NULL); - - register_functions(s, ops, global_fns, scope); - register_functions(s, ops, cursor_fns, uci_proto); + uc_add_proto_functions(scope, global_fns); - ops->register_type("uci.cursor", uci_proto, close_uci); + cursor_type = uc_declare_type("uci.cursor", cursor_fns, close_uci); } |