commit 768581e2b9e1a0ecba783ca9988d28029b299584
parent a9d2a10f9dfc2cacf17e574928e6b851e084beef
Author: Florian Dold <florian@dold.me>
Date: Tue, 3 Jan 2023 00:18:26 +0100
wip
Diffstat:
4 files changed, 92 insertions(+), 24 deletions(-)
diff --git a/quickjs/quickjs-libc.c b/quickjs/quickjs-libc.c
@@ -39,6 +39,7 @@
#include <limits.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#include <conio.h>
@@ -476,6 +477,55 @@ static JSValue js_std_loadFile(JSContext *ctx, JSValueConst this_val,
return ret;
}
+static JSValue js_std_writeFile(JSContext *ctx, JSValueConst this_val,
+ int argc, JSValueConst *argv)
+{
+ const char *filename_buf = NULL;
+ const char *data_buf = NULL;
+ size_t data_len;
+ FILE *file = NULL;
+ size_t bytes_written = 0;
+ JSValue ret = JS_UNDEFINED;
+
+ filename_buf = JS_ToCString(ctx, argv[0]);
+ if (!filename_buf) {
+ ret = JS_EXCEPTION;
+ goto done;
+ }
+
+ data_buf = JS_ToCStringLen(ctx, &data_len, argv[1]);
+ if (!data_buf) {
+ ret = JS_EXCEPTION;
+ goto done;
+ }
+ file = fopen(filename_buf, "w");
+ if (!file) {
+ ret = JS_ThrowReferenceError(ctx, "could not open '%s'", filename_buf);
+ goto done;
+ }
+
+ while (bytes_written < data_len) {
+ size_t sret;
+ sret = fwrite(data_buf + bytes_written, data_len - bytes_written, 1, file);
+ if (0 == sret) {
+ break;
+ }
+ bytes_written += sret;
+ }
+
+ if (bytes_written != data_len) {
+ JS_ThrowReferenceError(ctx, "could not write all bytes");
+ goto done;
+ }
+done:
+ JS_FreeCString(ctx, filename_buf);
+ JS_FreeCString(ctx, data_buf);
+ if (file) {
+ fclose(file);
+ }
+ return ret;
+}
+
typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx,
const char *module_name);
@@ -1518,6 +1568,7 @@ static const JSCFunctionListEntry js_std_funcs[] = {
JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ),
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ),
+ JS_CFUNC_DEF("writeFile", 2, js_std_writeFile ),
JS_CFUNC_DEF("strerror", 1, js_std_strerror ),
JS_CFUNC_DEF("parseExtJSON", 1, js_std_parseExtJSON ),
@@ -2587,7 +2638,7 @@ static int js_os_poll(JSContext *ctx)
}
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->os_timers) &&
- list_empty(&ts->port_list))
+ list_empty(&ts->port_list) && JS_IsNull(ts->on_host_message_func))
return -1; /* no more events */
if (!list_empty(&ts->os_timers)) {
@@ -4405,8 +4456,10 @@ void js_std_loop(JSContext *ctx)
}
}
- if (!os_poll_func || os_poll_func(ctx))
+ if (!os_poll_func || os_poll_func(ctx)) {
+ fprintf(stderr, "nothing more to wait on\n");
break;
+ }
}
}
diff --git a/quickjs/quickjs.c b/quickjs/quickjs.c
@@ -33799,8 +33799,9 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
}
}
fd = js_new_function_def(ctx, NULL, TRUE, FALSE, filename, 1);
- if (!fd)
+ if (!fd) {
goto fail1;
+ }
s->cur_func = fd;
fd->eval_type = eval_type;
fd->has_this_binding = (eval_type != JS_EVAL_TYPE_DIRECT);
@@ -33819,8 +33820,10 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
fd->js_mode = js_mode;
fd->func_name = JS_DupAtom(ctx, JS_ATOM__eval_);
if (b) {
- if (add_closure_variables(ctx, fd, b, scope_idx))
+ if (add_closure_variables(ctx, fd, b, scope_idx)) {
+ fprintf(stderr, "unable to add closure variables\n");
goto fail;
+ }
}
fd->module = m;
s->is_module = (m != NULL);
@@ -33831,12 +33834,16 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
err = js_parse_program(s);
if (err) {
+ fprintf(stderr, "unable to parse program\n");
fail:
+ fprintf(stderr, "fail in internal eval\n");
free_token(s, &s->token);
js_free_function_def(ctx, fd);
goto fail1;
}
+ fprintf(stderr, "parsed program\n");
+
/* create the function object and all the enclosed functions */
fun_obj = js_create_function(ctx, fd);
if (JS_IsException(fun_obj))
diff --git a/taler_wallet_core_lib.c b/taler_wallet_core_lib.c
@@ -35,16 +35,18 @@ struct HostMessage {
char *data;
};
-struct TALER_WALLET_Handle {
- char *test;
+struct TALER_WALLET_Handle
+{
+ // Mutex that is locked while initializing the handle
+ pthread_mutex_t handle_mutex;
- JSRuntime *rt;
- JSContext *ctx;
+ JSRuntime *rt;
+ JSContext *ctx;
- pthread_t wallet_thread;
+ pthread_t wallet_thread;
- TALER_WALLET_MessageHandlerFn handler_f;
- void *handler_cls;
+ TALER_WALLET_MessageHandlerFn handler_f;
+ void *handler_cls;
};
static int eval_buf(JSContext *ctx, const char *codestr, const char *filename)
@@ -90,7 +92,10 @@ int
TALER_WALLET_send_message (struct TALER_WALLET_Handle *h,
const char *msg)
{
- return js_os_post_message_from_host(h->ctx, msg);
+ int ret;
+ pthread_mutex_lock(&h->handle_mutex);
+ pthread_mutex_unlock(&h->handle_mutex);
+ ret = js_os_post_message_from_host(h->ctx, msg);
}
static void
@@ -109,9 +114,9 @@ TALER_WALLET_create(void)
struct TALER_WALLET_Handle *wh;
wh = malloc(sizeof (*wh));
memset(wh, 0, sizeof *wh);
- wh->test = "foo";
-
- wh->rt = JS_NewRuntime();
+ if (0 != pthread_mutex_init(&wh->handle_mutex, NULL)) {
+ abort();
+ }
return wh;
}
@@ -121,7 +126,7 @@ run(void *cls)
{
struct TALER_WALLET_Handle *wh = cls;
- printf("TEST: %s\n", wh->test);
+ wh->rt = JS_NewRuntime();
js_std_init_handlers(wh->rt);
wh->ctx = JS_NewCustomContext(wh->rt);
@@ -129,10 +134,10 @@ run(void *cls)
if (!wh->ctx) {
fprintf(stderr, "qjs: cannot allocate JS context\n");
+ pthread_mutex_unlock(&wh->handle_mutex);
return NULL;
}
- eval_buf(wh->ctx, "console.log('hi');", "<talerwallet>");
JS_SetHostPromiseRejectionTracker(wh->rt, js_std_promise_rejection_tracker,
NULL);
@@ -144,12 +149,12 @@ run(void *cls)
js_os_set_host_message_handler(wh->ctx, wallet_host_message_handler, wh);
- printf("starting main loop\n");
+ pthread_mutex_unlock(&wh->handle_mutex);
- eval_buf(wh->ctx, "console.log('hi');", "<talerwallet>");
- eval_buf(wh->ctx, "console.log(typeof testWithLocal);", "<talerwallet>");
- eval_buf(wh->ctx, "console.log('hello, world, bla!');", "<talerwallet>");
- eval_buf(wh->ctx, "testWithLocal();", "<talerwallet>");
+ eval_buf(wh->ctx, "installNativeWalletListener()", "<talerwalletcore>");
+ //eval_buf(wh->ctx, "setTimeout(() => console.log('hehe'), 1000);", "<talerwalletcore>");
+
+ printf("starting main loop\n");
js_std_loop(wh->ctx);
@@ -163,7 +168,7 @@ TALER_WALLET_run (struct TALER_WALLET_Handle *wh)
char *line;
size_t line_sz;
- //run(wh);
+ pthread_mutex_lock(&wh->handle_mutex);
pthread_create(&wallet_thread, NULL, run, wh);
diff --git a/wallet-client-example.c b/wallet-client-example.c
@@ -38,7 +38,10 @@ int main(int argc, char **argv)
TALER_WALLET_run(wh);
- //TALER_WALLET_send_message(wh, "{}");
+ TALER_WALLET_send_message(wh, "{}");
+ // Wait for wallet thread to finish.
+ // If we don't call this, main() exits
+ // and the wallet thread is killed.
TALER_WALLET_join(wh);
}