Commit 5594158c authored by Shu-yu Guo's avatar Shu-yu Guo Committed by Commit Bot

Add a synthetic return for async generator functions

Currently implicit returns do not correctly resolve the async generator
objects. This is observable via AsyncGenerator#throw as the implicit
return won't override the rejection.

Bug: v8:10238
Change-Id: I012fc3507d1e4106e7f35b21275be180a6e274c3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2065343Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66413}
parent 1161fe86
...@@ -1788,6 +1788,11 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody( ...@@ -1788,6 +1788,11 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
statements.Add( statements.Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
ParseStatementList(&statements, Token::RBRACE); ParseStatementList(&statements, Token::RBRACE);
// Since the whole body is wrapped in a try-catch, make the implicit
// end-of-function return explicit to ensure BytecodeGenerator's special
// handling for ReturnStatements in async generators applies.
statements.Add(factory()->NewSyntheticAsyncReturnStatement(
factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition));
// Don't create iterator result for async generators, as the resume methods // Don't create iterator result for async generators, as the resume methods
// will create it. // will create it.
......
...@@ -14,7 +14,7 @@ snippet: " ...@@ -14,7 +14,7 @@ snippet: "
" "
frame size: 8 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 147 bytecode array length: 144
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -34,9 +34,12 @@ bytecodes: [ ...@@ -34,9 +34,12 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(53), B(Jump), U8(50),
B(Ldar), R(5), B(LdaUndefined),
B(Jump), U8(36), B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(3), B(CreateCatchContext), R(5), U8(3),
B(Star), R(4), B(Star), R(4),
...@@ -52,10 +55,6 @@ bytecodes: [ ...@@ -52,10 +55,6 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaZero), B(LdaZero),
...@@ -92,8 +91,8 @@ constant pool: [ ...@@ -92,8 +91,8 @@ constant pool: [
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[19, 93, 101], [19, 98, 98],
[22, 55, 59], [22, 64, 64],
] ]
--- ---
...@@ -103,7 +102,7 @@ snippet: " ...@@ -103,7 +102,7 @@ snippet: "
" "
frame size: 8 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 192 bytecode array length: 189
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -123,7 +122,7 @@ bytecodes: [ ...@@ -123,7 +122,7 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(98), B(Jump), U8(95),
/* 22 S> */ B(LdaSmi), I8(42), /* 22 S> */ B(LdaSmi), I8(42),
B(Star), R(6), B(Star), R(6),
B(LdaFalse), B(LdaFalse),
...@@ -140,9 +139,12 @@ bytecodes: [ ...@@ -140,9 +139,12 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(53), B(Jump), U8(50),
B(Ldar), R(5), B(LdaUndefined),
B(Jump), U8(36), B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(6), B(CreateCatchContext), R(5), U8(6),
B(Star), R(4), B(Star), R(4),
...@@ -158,10 +160,6 @@ bytecodes: [ ...@@ -158,10 +160,6 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaZero), B(LdaZero),
...@@ -201,8 +199,8 @@ constant pool: [ ...@@ -201,8 +199,8 @@ constant pool: [
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[19, 138, 146], [19, 143, 143],
[22, 100, 104], [22, 109, 109],
] ]
--- ---
...@@ -212,7 +210,7 @@ snippet: " ...@@ -212,7 +210,7 @@ snippet: "
" "
frame size: 19 frame size: 19
parameter count: 1 parameter count: 1
bytecode array length: 363 bytecode array length: 362
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4), B(Mov), R(closure), R(4),
...@@ -322,8 +320,12 @@ bytecodes: [ ...@@ -322,8 +320,12 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(4), B(Star), R(4),
B(Mov), R(12), R(5), B(Mov), R(12), R(5),
B(Jump), U8(51), B(Jump), U8(50),
B(Jump), U8(36), B(LdaUndefined),
B(Star), R(5),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Jump), U8(41),
B(Star), R(8), B(Star), R(8),
B(CreateCatchContext), R(8), U8(14), B(CreateCatchContext), R(8), U8(14),
B(Star), R(7), B(Star), R(7),
...@@ -339,10 +341,6 @@ bytecodes: [ ...@@ -339,10 +341,6 @@ bytecodes: [
B(Star), R(5), B(Star), R(5),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
B(Star), R(4), B(Star), R(4),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(5),
B(Star), R(4),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(5), B(Star), R(5),
B(LdaZero), B(LdaZero),
...@@ -385,14 +383,14 @@ constant pool: [ ...@@ -385,14 +383,14 @@ constant pool: [
Smi [6], Smi [6],
Smi [9], Smi [9],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [269], Smi [268],
Smi [6], Smi [6],
Smi [9], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[19, 309, 317], [19, 316, 316],
[22, 273, 275], [22, 282, 282],
[86, 173, 181], [86, 173, 181],
[205, 238, 240], [205, 238, 240],
] ]
...@@ -405,7 +403,7 @@ snippet: " ...@@ -405,7 +403,7 @@ snippet: "
" "
frame size: 17 frame size: 17
parameter count: 1 parameter count: 1
bytecode array length: 466 bytecode array length: 463
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(5), B(SwitchOnGeneratorState), R(0), U8(0), U8(5),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -473,7 +471,7 @@ bytecodes: [ ...@@ -473,7 +471,7 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(10), R(2), B(Mov), R(10), R(2),
B(Jump), U8(241), B(Jump), U8(238),
B(LdaNamedProperty), R(7), U8(14), U8(20), B(LdaNamedProperty), R(7), U8(14), U8(20),
B(JumpIfUndefinedOrNull), U8(11), B(JumpIfUndefinedOrNull), U8(11),
B(Star), R(12), B(Star), R(12),
...@@ -541,9 +539,12 @@ bytecodes: [ ...@@ -541,9 +539,12 @@ bytecodes: [
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(7), R(2), B(Mov), R(7), R(2),
B(Jump), U8(53), B(Jump), U8(50),
B(Ldar), R(7), B(LdaUndefined),
B(Jump), U8(36), B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(17), B(CreateCatchContext), R(5), U8(17),
B(Star), R(4), B(Star), R(4),
...@@ -559,10 +560,6 @@ bytecodes: [ ...@@ -559,10 +560,6 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaZero), B(LdaZero),
...@@ -608,13 +605,13 @@ constant pool: [ ...@@ -608,13 +605,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [372], Smi [369],
Smi [6], Smi [6],
Smi [9], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[19, 412, 420], [19, 417, 417],
[22, 374, 378], [22, 383, 383],
] ]
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let caught_in_gen = false;
async function* catch_gen() {
try {
yield 42;
} catch (e) {
caught_in_gen = true;
}
}
(async () => {
const g = catch_gen();
await g.next();
try {
await g.throw(new Error()); // Should be caught in catch_gen, then catch_gen
// completes normally.
} catch (e) {
assertUnreachable();
}
assertTrue(caught_in_gen);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment