Skip to content

Commit 39901e2

Browse files
committed
Fix async generator in case of exception in implicit await in the 'return' statement
Ref: bellard/quickjs@57105c7
1 parent 864a664 commit 39901e2

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

quickjs.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17733,7 +17733,6 @@ static void js_async_generator_resume_next(JSContext *ctx,
1773317733
} else if (next->completion_type == GEN_MAGIC_RETURN) {
1773417734
s->state = JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN;
1773517735
js_async_generator_completed_return(ctx, s, next->result);
17736-
goto done;
1773717736
} else {
1773817737
js_async_generator_reject(ctx, s, next->result);
1773917738
}
@@ -17764,7 +17763,7 @@ static void js_async_generator_resume_next(JSContext *ctx,
1776417763
js_async_generator_reject(ctx, s, value);
1776517764
JS_FreeValue(ctx, value);
1776617765
} else if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) {
17767-
int func_ret_code;
17766+
int func_ret_code, ret;
1776817767
value = s->func_state.frame.cur_sp[-1];
1776917768
s->func_state.frame.cur_sp[-1] = JS_UNDEFINED;
1777017769
func_ret_code = JS_VALUE_GET_INT(func_ret);
@@ -17779,8 +17778,13 @@ static void js_async_generator_resume_next(JSContext *ctx,
1777917778
JS_FreeValue(ctx, value);
1778017779
break;
1778117780
case FUNC_RET_AWAIT:
17782-
js_async_generator_await(ctx, s, value);
17781+
ret = js_async_generator_await(ctx, s, value);
1778317782
JS_FreeValue(ctx, value);
17783+
if (ret < 0) {
17784+
/* exception: throw it */
17785+
s->func_state.throw_flag = TRUE;
17786+
goto resume_exec;
17787+
}
1778417788
goto done;
1778517789
default:
1778617790
abort();
@@ -23874,6 +23878,18 @@ static void emit_return(JSParseState *s, BOOL hasval)
2387423878
BlockEnv *top;
2387523879
int drop_count;
2387623880

23881+
if (s->cur_func->func_kind != JS_FUNC_NORMAL) {
23882+
if (!hasval) {
23883+
/* no value: direct return in case of async generator */
23884+
emit_op(s, OP_undefined);
23885+
hasval = TRUE;
23886+
} else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) {
23887+
/* the await must be done before handling the "finally" in
23888+
case it raises an exception */
23889+
emit_op(s, OP_await);
23890+
}
23891+
}
23892+
2387723893
drop_count = 0;
2387823894
top = s->cur_func->top_break;
2387923895
while (top != NULL) {
@@ -23953,11 +23969,6 @@ static void emit_return(JSParseState *s, BOOL hasval)
2395323969
emit_label(s, label_return);
2395423970
emit_op(s, OP_return);
2395523971
} else if (s->cur_func->func_kind != JS_FUNC_NORMAL) {
23956-
if (!hasval) {
23957-
emit_op(s, OP_undefined);
23958-
} else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) {
23959-
emit_op(s, OP_await);
23960-
}
2396123972
emit_op(s, OP_return_async);
2396223973
} else {
2396323974
emit_op(s, hasval ? OP_return : OP_return_undef);

test262_errors.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
test262/test/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
2-
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-broken-promise-try-catch.js:39: TypeError: $DONE() not called
3-
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-broken-promise-try-catch.js:39: strict mode: TypeError: $DONE() not called
42
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
53
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: strict mode: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
64
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/detached-buffer.js:46: Test262Error: (Testing with BigInt64Array.)

0 commit comments

Comments
 (0)