diff options
author | Fabrice Bellard <fabrice@bellard.org> | 2023-12-13 19:01:59 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-12-14 11:24:33 +0100 |
commit | 8f2f06255105f68bf81c064be4982961102128a6 (patch) | |
tree | f90692a61656e2b061ebec6a09a2b73658dc7809 /lib/quickjs/quickjs.c | |
parent | 24565a7a34dcaf4efd960640369095587e786ad5 (diff) | |
download | chawan-8f2f06255105f68bf81c064be4982961102128a6.tar.gz |
fixed async generator in case of exception in the implicit await in the 'return' statement
Diffstat (limited to 'lib/quickjs/quickjs.c')
-rw-r--r-- | lib/quickjs/quickjs.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/lib/quickjs/quickjs.c b/lib/quickjs/quickjs.c index ccc8cf2f..a737ea66 100644 --- a/lib/quickjs/quickjs.c +++ b/lib/quickjs/quickjs.c @@ -19317,7 +19317,7 @@ static int js_async_generator_completed_return(JSContext *ctx, // exception should be delivered to the catch handler. if (JS_IsException(promise)) { JSValue err = JS_GetException(ctx); - promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, &err, + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&err, /*is_reject*/1); JS_FreeValue(ctx, err); if (JS_IsException(promise)) @@ -19370,7 +19370,6 @@ static void js_async_generator_resume_next(JSContext *ctx, } else if (next->completion_type == GEN_MAGIC_RETURN) { s->state = JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN; js_async_generator_completed_return(ctx, s, next->result); - goto done; } else { js_async_generator_reject(ctx, s, next->result); } @@ -19401,7 +19400,7 @@ static void js_async_generator_resume_next(JSContext *ctx, js_async_generator_reject(ctx, s, value); JS_FreeValue(ctx, value); } else if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) { - int func_ret_code; + int func_ret_code, ret; value = s->func_state.frame.cur_sp[-1]; s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; func_ret_code = JS_VALUE_GET_INT(func_ret); @@ -19416,8 +19415,13 @@ static void js_async_generator_resume_next(JSContext *ctx, JS_FreeValue(ctx, value); break; case FUNC_RET_AWAIT: - js_async_generator_await(ctx, s, value); + ret = js_async_generator_await(ctx, s, value); JS_FreeValue(ctx, value); + if (ret < 0) { + /* exception: throw it */ + s->func_state.throw_flag = TRUE; + goto resume_exec; + } goto done; default: abort(); @@ -25571,6 +25575,18 @@ static void emit_return(JSParseState *s, BOOL hasval) BlockEnv *top; int drop_count; + if (s->cur_func->func_kind != JS_FUNC_NORMAL) { + if (!hasval) { + /* no value: direct return in case of async generator */ + emit_op(s, OP_undefined); + hasval = TRUE; + } else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { + /* the await must be done before handling the "finally" in + case it raises an exception */ + emit_op(s, OP_await); + } + } + drop_count = 0; top = s->cur_func->top_break; while (top != NULL) { @@ -25649,11 +25665,6 @@ static void emit_return(JSParseState *s, BOOL hasval) emit_label(s, label_return); emit_op(s, OP_return); } else if (s->cur_func->func_kind != JS_FUNC_NORMAL) { - if (!hasval) { - emit_op(s, OP_undefined); - } else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { - emit_op(s, OP_await); - } emit_op(s, OP_return_async); } else { emit_op(s, hasval ? OP_return : OP_return_undef); |