summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2024-01-19 10:19:58 +0100
committerFabrice Bellard <fabrice@bellard.org>2024-01-19 10:19:58 +0100
commit84058766e9f247cac7b00543feeb10f3bba8120a (patch)
tree980e5fa5ef9d18be4acddc1733a997f064ac416b
parentd6c7d169de6fb2c90cd2bd2226ba9dafdef883ce (diff)
downloadquickjs-84058766e9f247cac7b00543feeb10f3bba8120a.tar.gz
quickjs-84058766e9f247cac7b00543feeb10f3bba8120a.zip
added js_std_await() and use it to wait for the evaluation of a module (github issue #219)
-rw-r--r--qjs.c1
-rw-r--r--quickjs-libc.c52
-rw-r--r--quickjs-libc.h1
3 files changed, 47 insertions, 7 deletions
diff --git a/qjs.c b/qjs.c
index 77b5cfb..22d5f32 100644
--- a/qjs.c
+++ b/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-libc.c b/quickjs-libc.c
index d4f4d67..aa9e861 100644
--- a/quickjs-libc.c
+++ b/quickjs-libc.c
@@ -3339,7 +3339,7 @@ static void *worker_func(void *opaque)
JSRuntime *rt;
JSThreadState *ts;
JSContext *ctx;
- JSValue promise;
+ JSValue val;
rt = JS_NewRuntime();
if (rt == NULL) {
@@ -3366,14 +3366,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);
@@ -3969,6 +3969,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)
{
@@ -3987,8 +4022,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-libc.h b/quickjs-libc.h
index fbbe5b0..1dfdf53 100644
--- a/quickjs-libc.h
+++ b/quickjs-libc.h
@@ -37,6 +37,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);