quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit cb87d9eb44ed79e50f5226e8442ca01a47e0c16e
parent 30fda5ca4dae46c5f0cc4390287a31eda45272f4
Author: Fabrice Bellard <fabrice@bellard.org>
Date:   Fri, 19 Jan 2024 10:19:58 +0100

added js_std_await() and use it to wait for the evaluation of a module (github issue #219)

Diffstat:
Mquickjs/qjs.c | 1+
Mquickjs/quickjs-libc.c | 52+++++++++++++++++++++++++++++++++++++++++++++-------
Mquickjs/quickjs-libc.h | 1+
3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/quickjs/qjs.c b/quickjs/qjs.c @@ -64,6 +64,7 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len, js_module_set_import_meta(ctx, val, TRUE, TRUE); val = JS_EvalFunction(ctx, val); } + val = js_std_await(ctx, val); } else { val = JS_Eval(ctx, buf, buf_len, filename, eval_flags); } diff --git a/quickjs/quickjs-libc.c b/quickjs/quickjs-libc.c @@ -4138,7 +4138,7 @@ static void *worker_func(void *opaque) JSRuntime *rt; JSThreadState *ts; JSContext *ctx; - JSValue promise; + JSValue val; rt = JS_NewRuntime(); if (rt == NULL) { @@ -4166,14 +4166,14 @@ static void *worker_func(void *opaque) js_std_add_helpers(ctx, -1, NULL); - promise = JS_LoadModule(ctx, args->basename, args->filename); - if (JS_IsException(promise)) - js_std_dump_error(ctx); - /* XXX: check */ - JS_FreeValue(ctx, promise); + val = JS_LoadModule(ctx, args->basename, args->filename); free(args->filename); free(args->basename); free(args); + val = js_std_await(ctx, val); + if (JS_IsException(val)) + js_std_dump_error(ctx); + JS_FreeValue(ctx, val); js_std_loop(ctx); @@ -4906,6 +4906,41 @@ void js_std_loop(JSContext *ctx) } } +/* Wait for a promise and execute pending jobs while waiting for + it. Return the promise result or JS_EXCEPTION in case of promise + rejection. */ +JSValue js_std_await(JSContext *ctx, JSValue obj) +{ + JSValue ret; + int state; + + for(;;) { + state = JS_PromiseState(ctx, obj); + if (state == JS_PROMISE_FULFILLED) { + ret = JS_PromiseResult(ctx, obj); + JS_FreeValue(ctx, obj); + break; + } else if (state == JS_PROMISE_REJECTED) { + ret = JS_Throw(ctx, JS_PromiseResult(ctx, obj)); + JS_FreeValue(ctx, obj); + break; + } else if (state == JS_PROMISE_PENDING) { + JSContext *ctx1; + int err; + err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); + if (err < 0) { + js_std_dump_error(ctx1); + } + if (os_poll_func) + os_poll_func(ctx); + } else { + /* not a promise */ + ret = obj; + } + } + return ret; +} + void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, int load_only) { @@ -4924,8 +4959,11 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, goto exception; } js_module_set_import_meta(ctx, obj, FALSE, TRUE); + val = JS_EvalFunction(ctx, obj); + val = js_std_await(ctx, val); + } else { + val = JS_EvalFunction(ctx, obj); } - val = JS_EvalFunction(ctx, obj); if (JS_IsException(val)) { exception: js_std_dump_error(ctx); diff --git a/quickjs/quickjs-libc.h b/quickjs/quickjs-libc.h @@ -43,6 +43,7 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); void js_std_add_helpers(JSContext *ctx, int argc, char **argv); void js_std_loop(JSContext *ctx); +JSValue js_std_await(JSContext *ctx, JSValue obj); void js_std_init_handlers(JSRuntime *rt); void js_std_free_handlers(JSRuntime *rt); void js_std_dump_error(JSContext *ctx);