summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-12-23 20:54:05 +0100
committerJo-Philipp Wich <jo@mein.io>2021-02-17 14:10:51 +0100
commit3756806674da909ec6dc10ad25862b592792604e (patch)
treef2af7e47f8444caaff0a5a33599f381889db24e3 /lib
parent77580a893283f2bde7ab46496bd3a3d7b2fc6784 (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.c286
-rw-r--r--lib/math.c155
-rw-r--r--lib/ubus.c101
-rw-r--r--lib/uci.c282
4 files changed, 376 insertions, 448 deletions
diff --git a/lib/fs.c b/lib/fs.c
index 1e148c3..c6066cc 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -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));
}
diff --git a/lib/math.c b/lib/math.c
index 6dbca08..99f3fbc 100644
--- a/lib/math.c
+++ b/lib/math.c
@@ -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);
}
diff --git a/lib/ubus.c b/lib/ubus.c
index a11b014..b965bbe 100644
--- a/lib/ubus.c
+++ b/lib/ubus.c
@@ -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);
}
diff --git a/lib/uci.c b/lib/uci.c
index 1b4c5db..e00f77e 100644
--- a/lib/uci.c
+++ b/lib/uci.c
@@ -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);
}