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/+/2065343
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66413}
This commit is contained in:
Shu-yu Guo 2020-02-20 14:12:12 -08:00 committed by Commit Bot
parent 1161fe868d
commit 5594158c90
3 changed files with 69 additions and 43 deletions

View File

@ -1788,6 +1788,11 @@ void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
statements.Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
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
// will create it.

View File

@ -14,7 +14,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 147
bytecode array length: 144
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(1),
@ -34,9 +34,12 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(53),
B(Ldar), R(5),
B(Jump), U8(36),
B(Jump), U8(50),
B(LdaUndefined),
B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(3),
B(Star), R(4),
@ -52,10 +55,6 @@ bytecodes: [
B(Star), R(2),
B(LdaSmi), I8(2),
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(Star), R(2),
B(LdaZero),
@ -92,8 +91,8 @@ constant pool: [
Smi [23],
]
handlers: [
[19, 93, 101],
[22, 55, 59],
[19, 98, 98],
[22, 64, 64],
]
---
@ -103,7 +102,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 192
bytecode array length: 189
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(1),
@ -123,7 +122,7 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(98),
B(Jump), U8(95),
/* 22 S> */ B(LdaSmi), I8(42),
B(Star), R(6),
B(LdaFalse),
@ -140,9 +139,12 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(53),
B(Ldar), R(5),
B(Jump), U8(36),
B(Jump), U8(50),
B(LdaUndefined),
B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(6),
B(Star), R(4),
@ -158,10 +160,6 @@ bytecodes: [
B(Star), R(2),
B(LdaSmi), I8(2),
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(Star), R(2),
B(LdaZero),
@ -201,8 +199,8 @@ constant pool: [
Smi [23],
]
handlers: [
[19, 138, 146],
[22, 100, 104],
[19, 143, 143],
[22, 109, 109],
]
---
@ -212,7 +210,7 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 363
bytecode array length: 362
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4),
@ -322,8 +320,12 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(4),
B(Mov), R(12), R(5),
B(Jump), U8(51),
B(Jump), U8(36),
B(Jump), U8(50),
B(LdaUndefined),
B(Star), R(5),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Jump), U8(41),
B(Star), R(8),
B(CreateCatchContext), R(8), U8(14),
B(Star), R(7),
@ -339,10 +341,6 @@ bytecodes: [
B(Star), R(5),
B(LdaSmi), I8(2),
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(Star), R(5),
B(LdaZero),
@ -385,14 +383,14 @@ constant pool: [
Smi [6],
Smi [9],
SCOPE_INFO_TYPE,
Smi [269],
Smi [268],
Smi [6],
Smi [9],
Smi [23],
]
handlers: [
[19, 309, 317],
[22, 273, 275],
[19, 316, 316],
[22, 282, 282],
[86, 173, 181],
[205, 238, 240],
]
@ -405,7 +403,7 @@ snippet: "
"
frame size: 17
parameter count: 1
bytecode array length: 466
bytecode array length: 463
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(5),
B(Mov), R(closure), R(1),
@ -473,7 +471,7 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(10), R(2),
B(Jump), U8(241),
B(Jump), U8(238),
B(LdaNamedProperty), R(7), U8(14), U8(20),
B(JumpIfUndefinedOrNull), U8(11),
B(Star), R(12),
@ -541,9 +539,12 @@ bytecodes: [
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(7), R(2),
B(Jump), U8(53),
B(Ldar), R(7),
B(Jump), U8(36),
B(Jump), U8(50),
B(LdaUndefined),
B(Star), R(2),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Jump), U8(41),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(17),
B(Star), R(4),
@ -559,10 +560,6 @@ bytecodes: [
B(Star), R(2),
B(LdaSmi), I8(2),
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(Star), R(2),
B(LdaZero),
@ -608,13 +605,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
Smi [372],
Smi [369],
Smi [6],
Smi [9],
Smi [23],
]
handlers: [
[19, 412, 420],
[22, 374, 378],
[19, 417, 417],
[22, 383, 383],
]

View File

@ -0,0 +1,24 @@
// 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);
})();