]> git.kaiwu.me - quickjs.git/commitdiff
added js_std_await() and use it to wait for the evaluation of a module (github issue...
authorFabrice Bellard <fabrice@bellard.org>
Fri, 19 Jan 2024 09:19:58 +0000 (10:19 +0100)
committerFabrice Bellard <fabrice@bellard.org>
Fri, 19 Jan 2024 09:19:58 +0000 (10:19 +0100)
qjs.c
quickjs-libc.c
quickjs-libc.h

diff --git a/qjs.c b/qjs.c
index 77b5cfbc13a3793c8db6d67d4e933992d513a321..22d5f3207c15379f36c9ef9c43e53138ac94a2f6 100644 (file)
--- 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);
     }
index d4f4d671165e400b4b7216fc97f5c76fb41d1695..aa9e861818deb5c82427898bf8ad5d2148b90564 100644 (file)
@@ -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);
index fbbe5b0166eb1a1f2875dccd5d06d1d401a5d53b..1dfdf53b23c7cf8d001266e518648888805ab915 100644 (file)
@@ -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);