[mw-devel] [Git][arthur/mw][master] 4 commits: Implement load_jsfile() for duktape
Andrew Price
welshbyte at sucs.org
Mon Jul 10 11:53:25 BST 2017
Andrew Price pushed to branch master at Justin Mitchell / mw
Commits:
046b2a2a by Andrew Price at 2017-07-09T20:46:42+01:00
Implement load_jsfile() for duktape
- - - - -
91c9c0c7 by Andrew Price at 2017-07-10T11:34:15+01:00
Implement js_bind() and js_exec() with duktape
- - - - -
7273bb23 by Andrew Price at 2017-07-10T11:36:02+01:00
duktape: define 'whoami'
- - - - -
e2de6c24 by Andrew Price at 2017-07-10T11:36:43+01:00
Build duktape with debugging symbols
- - - - -
4 changed files:
- duktape/Makefile
- src/client/js-duk.c
- src/client/js-moz.c
- src/client/js.h
Changes:
=====================================
duktape/Makefile
=====================================
--- a/duktape/Makefile
+++ b/duktape/Makefile
@@ -5,7 +5,7 @@ include $(DEPTH)Makefile.common
build: duktape.o
duktape.o: duktape.c duktape.h duk_config.h
- $(CC) -std=c99 $(CCSEC) duktape.c -c
+ $(CC) -std=c99 -g $(CCSEC) duktape.c -c
clean:
-rm -f *.o .*.d *.d
=====================================
src/client/js-duk.c
=====================================
--- a/src/client/js-duk.c
+++ b/src/client/js-duk.c
@@ -1,26 +1,174 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <stdio.h>
+#include <errno.h>
#include <duktape.h>
#include "js.h"
+#include "alias.h"
+#include "user.h"
+
+extern struct user * const user;
+
+duk_context *ctx;
+
+struct binding {
+ int type;
+ int name_required;
+ alias **list;
+ const char *name;
+};
+
+const struct binding bindings[] = {
+ { K_BIND, 1, &bind_list, "Bind" },
+ { K_BIND_ALIAS, 1, &alias_list, "Alias" },
+ { K_BIND_RPC, 1, &rpc_list, "RPC bind" },
+ { K_BIND_EVENT, 0, &event_list, "Event bind" },
+ { K_BIND_ONOFF, 0, &onoff_list, "Check on/off bind" },
+ { K_BIND_IPC, 0, &ipc_list, "IPC bind" },
+ { K_BIND_FORCE, 0, &force_list, "Force bind" },
+ { K_BIND_SHUTDOWN, 0, &shutdown_list, "Shutdown bind" },
+ { K_BIND_INPUT, 0, &eventin_list, "Input event bind" },
+ { 0, 0, NULL, NULL }
+};
+
+static duk_ret_t js_bind(duk_context *cx)
+{
+ const char *bind_name = NULL;
+ const char *func_name = NULL;
+ const struct binding *bind;
+ int bind_type = -1;
+
+ if (duk_is_undefined(cx, -2) ||
+ duk_is_undefined(cx, -3)) {
+ fprintf(stderr, "mwjs error: bind() expects 2 or 3 arguments\n");
+ return DUK_RET_SYNTAX_ERROR;
+ }
+ if (duk_is_string(cx, -3)) {
+ bind_name = duk_get_string(cx, -3);
+ bind_type = K_BIND;
+ if (!duk_is_undefined(cx, -1)) {
+ fprintf(stderr, "mwjs error: bind(str, str) expects 2 arguments\n");
+ return DUK_RET_SYNTAX_ERROR;
+ }
+ duk_pop(cx);
+ } else if (duk_is_number(cx, -3)) {
+ bind_type = duk_get_int_default(cx, -3, -1);
+ if (bind_type == K_BIND ||
+ bind_type == K_BIND_ALIAS ||
+ bind_type == K_BIND_RPC) {
+ bind_name = duk_get_string(cx, -2);
+ } else {
+ duk_pop(cx);
+ }
+ } else {
+ fprintf(stderr, "mwjs error: first argument to bind() must be a "
+ "string or bind id\n");
+ return DUK_RET_SYNTAX_ERROR;
+ }
+
+ func_name = duk_get_string(cx, -1);
+ if (func_name == NULL) {
+ fprintf(stderr, "mwjs error: bind(): invalid function name\n");
+ return DUK_RET_SYNTAX_ERROR;
+ }
+
+ for (bind = &bindings[0]; bind->list != NULL && bind->type != bind_type; bind++);
+
+ if (bind->list == NULL) {
+ fprintf(stderr, "Bind type %d not recognised\n", bind_type);
+ return DUK_RET_ERROR;
+ }
+ if (bind->name_required) {
+ if (bind_name == NULL || bind_name[0] == '\0') {
+ fprintf(stderr, "Bind name is empty\n");
+ return DUK_RET_ERROR;
+ }
+ } else {
+ bind_name = func_name;
+ func_name = "";
+ }
+ if (AddLink(bind->list, bind_name, func_name)) {
+ fprintf(stderr, "Warning: %s %s already exists.\n",
+ bind->name, bind_name);
+ }
+ return 0;
+}
int js_isrunning(void)
{
return 0;
}
-int js_exec(char *name, int argc, const char **argvc)
+int js_exec(char *name, int argc, const char **argv)
{
+ int i;
+
+ if (duk_get_global_string(ctx, name) && duk_is_function(ctx, -1)) {
+ for (i = 0; i < argc; i++)
+ duk_push_string(ctx, argv[i]);
+ if (duk_pcall(ctx, argc) != DUK_EXEC_SUCCESS) {
+ if (duk_is_error(ctx, -1)) {
+ duk_get_prop_string(ctx, -1, "stack");
+ fprintf(stderr, "mwjs error: %s\n", duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ } else {
+ fprintf(stderr, "mwjs error: %s\n", duk_safe_to_string(ctx, -1));
+ }
+ }
+ }
+ duk_pop(ctx);
return 0;
}
+/* This limit is fairly arbitrary but a limit is needed and 256K
+ seems a reasonable file and (temporary) buffer size */
+#define MWJS_FILE_MAX_SIZE (256*1024)
+
int load_jsfile(FILE *f, const char *filename)
{
+ char buf[MWJS_FILE_MAX_SIZE + 1];
+ int fd = fileno(f);
+ struct stat st;
+ size_t ret;
+
+ if (fd == -1) {
+ fprintf(stderr, "Failed to open '%s': %s\n", filename, strerror(errno));
+ return 1;
+ }
+ if (fstat(fd, &st) != 0) {
+ fprintf(stderr, "Failed to stat '%s': %s\n", filename, strerror(errno));
+ return 1;
+ }
+ errno = EFBIG;
+ if (st.st_size > MWJS_FILE_MAX_SIZE) {
+ fprintf(stderr, "Failed to load '%s': %s\n", filename, strerror(errno));
+ return 1;
+ }
+ ret = fread(buf, sizeof(char), st.st_size, f);
+ if (ret != st.st_size) {
+ fprintf(stderr, "Failed to read '%s': %llu bytes read\n",
+ filename, (unsigned long long)ret);
+ return 1;
+ }
+ buf[MWJS_FILE_MAX_SIZE] = '\0';
+ if (duk_peval_string(ctx, buf) != 0) {
+ printf("Failed to execute '%s': %s\n", filename, duk_safe_to_string(ctx, -1));
+ }
+ duk_pop(ctx);
return 0;
}
int is_js(char *name)
{
- return 0;
+ int ret = 0;
+
+ if (duk_get_global_string(ctx, name) && duk_is_function(ctx, -1))
+ ret = 1;
+
+ duk_pop(ctx);
+ return ret;
}
void js_stop_execution(void)
@@ -29,11 +177,59 @@ void js_stop_execution(void)
int stop_js(void)
{
+ duk_destroy_heap(ctx);
return 0;
}
+/* The owning object must be at the top of the stack when calling this */
+static void define_func(const char *name, duk_c_function func, int nargs)
+{
+ duk_push_string(ctx, name);
+ duk_push_c_function(ctx, func, nargs);
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
+}
+
+/* The owning object must be at the top of the stack when calling this */
+static void define_number(const char *name, duk_double_t num)
+{
+ duk_push_string(ctx, name);
+ duk_push_number(ctx, num);
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
+}
+
+/* The owning object must be at the top of the stack when calling this */
+static void define_string(const char *name, const char *value)
+{
+ duk_push_string(ctx, name);
+ duk_push_string(ctx, value);
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
+}
+
+/* The owning object must be at the top of the stack when calling this */
+static void define_constants(void)
+{
+ define_number("K_BIND_EVENT", (duk_double_t)K_BIND_EVENT);
+ define_number("K_BIND_IPC", (duk_double_t)K_BIND_IPC);
+ define_number("K_BIND_ONOFF", (duk_double_t)K_BIND_ONOFF);
+ define_number("K_BIND_FORCE", (duk_double_t)K_BIND_FORCE);
+ define_number("K_BIND_SHUTDOWN", (duk_double_t)K_BIND_SHUTDOWN);
+ define_number("K_BIND_RPC", (duk_double_t)K_BIND_RPC);
+ define_number("K_BIND_ALIAS", (duk_double_t)K_BIND_ALIAS);
+ define_number("K_BIND_INPUT", (duk_double_t)K_BIND_INPUT);
+ define_number("K_BROADCAST", (duk_double_t)K_BROADCAST);
+ define_string("whoami", user->record.name);
+}
+
int setup_js(void)
{
+ ctx = duk_create_heap_default();
+ if (ctx == NULL)
+ return -1;
+
+ duk_push_global_object(ctx);
+ define_constants();
+ define_func("bind", js_bind, 3);
+ duk_pop(ctx);
return 0;
}
=====================================
src/client/js-moz.c
=====================================
--- a/src/client/js-moz.c
+++ b/src/client/js-moz.c
@@ -48,9 +48,6 @@ static JSObject *jsroot = NULL;
int js_interrupted=1;
struct alarm *js_timeout_event=NULL;
-enum bindtype { K_BIND=0, K_BIND_EVENT, K_BIND_ONOFF, K_BIND_IPC, K_BIND_FORCE, K_BIND_SHUTDOWN, K_BIND_ALIAS, K_BIND_RPC, K_BIND_INPUT };
-#define K_BROADCAST 1
-
JSClass globclass = {
"milliways", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_StrictPropertyStub,
=====================================
src/client/js.h
=====================================
--- a/src/client/js.h
+++ b/src/client/js.h
@@ -13,4 +13,17 @@ int setup_js(void);
size_t urldata(void *ptr, size_t size, size_t nmemb, void *stream);
size_t headlimit(void *ptr, size_t size, size_t nmemb, void *stream);
+enum bindtype {
+ K_BIND = 0,
+ K_BIND_EVENT,
+ K_BIND_ONOFF,
+ K_BIND_IPC,
+ K_BIND_FORCE,
+ K_BIND_SHUTDOWN,
+ K_BIND_ALIAS,
+ K_BIND_RPC,
+ K_BIND_INPUT
+};
+#define K_BROADCAST 1
+
#endif /* JS_H */
View it on GitLab: https://projects.sucs.org/arthur/mw/compare/feb65f5be90bf3f51f64245cd2c0fd45f805ecc8...e2de6c248043c9120d92512c94a199294ae136e3
---
View it on GitLab: https://projects.sucs.org/arthur/mw/compare/feb65f5be90bf3f51f64245cd2c0fd45f805ecc8...e2de6c248043c9120d92512c94a199294ae136e3
You're receiving this email because of your account on projects.sucs.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20170710/474a69a3/attachment-0001.html>
More information about the mw-devel
mailing list