[interpreter] Don't assume generator functions do an initial yield.
Async functions are implemented via special generator functions; special in the sense that they generally do not immediately yield. However, our generators implementation still assumed that every generator function initially yields (concretely: before doing the state dispatch in a loop header). This CL fixes that. R=littledan@chromium.org, rmcilroy@chromium.org BUG=chromium:638019 Review-Url: https://codereview.chromium.org/2253033002 Cr-Commit-Position: refs/heads/master@{#38684}
This commit is contained in:
parent
1031a79f60
commit
7fe4d930c9
@ -876,7 +876,10 @@ void BytecodeGenerator::VisitGeneratorPrologue() {
|
||||
BuildIndexedJump(generator_state_, 0, generator_resume_points_.size(),
|
||||
generator_resume_points_);
|
||||
|
||||
builder()->Bind(®ular_call);
|
||||
builder()
|
||||
->Bind(®ular_call)
|
||||
.LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
|
||||
.StoreAccumulatorInRegister(generator_state_);
|
||||
// This is a regular call. Fall through to the ordinary function prologue,
|
||||
// after which we will run into the generator object creation and other extra
|
||||
// code inserted by the parser.
|
||||
|
@ -15,7 +15,7 @@ snippet: "
|
||||
"
|
||||
frame size: 11
|
||||
parameter count: 1
|
||||
bytecode array length: 197
|
||||
bytecode array length: 201
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(20),
|
||||
@ -23,10 +23,12 @@ bytecodes: [
|
||||
B(Star), R(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(JumpIfTrue), U8(53),
|
||||
B(JumpIfTrue), U8(57),
|
||||
B(LdaSmi), U8(76),
|
||||
B(Star), R(2),
|
||||
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(1),
|
||||
B(CreateFunctionContext), U8(2),
|
||||
B(PushContext), R(0),
|
||||
B(Ldar), R(this),
|
||||
@ -108,7 +110,7 @@ bytecodes: [
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
[35, 134, 140],
|
||||
[39, 138, 144],
|
||||
]
|
||||
|
||||
---
|
||||
@ -118,7 +120,7 @@ snippet: "
|
||||
"
|
||||
frame size: 11
|
||||
parameter count: 1
|
||||
bytecode array length: 290
|
||||
bytecode array length: 294
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(26),
|
||||
@ -126,13 +128,15 @@ bytecodes: [
|
||||
B(Star), R(1),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(JumpIfTrue), U8(59),
|
||||
B(JumpIfTrue), U8(63),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(1),
|
||||
B(JumpIfTrueConstant), U8(0),
|
||||
B(LdaSmi), U8(76),
|
||||
B(Star), R(2),
|
||||
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(1),
|
||||
B(CreateFunctionContext), U8(2),
|
||||
B(PushContext), R(0),
|
||||
B(Ldar), R(this),
|
||||
@ -254,7 +258,7 @@ constant pool: [
|
||||
kInstanceTypeDontCare,
|
||||
]
|
||||
handlers: [
|
||||
[41, 218, 224],
|
||||
[45, 222, 228],
|
||||
]
|
||||
|
||||
---
|
||||
@ -264,7 +268,7 @@ snippet: "
|
||||
"
|
||||
frame size: 18
|
||||
parameter count: 1
|
||||
bytecode array length: 752
|
||||
bytecode array length: 756
|
||||
bytecodes: [
|
||||
B(Ldar), R(new_target),
|
||||
B(JumpIfUndefined), U8(26),
|
||||
@ -272,13 +276,15 @@ bytecodes: [
|
||||
B(Star), R(4),
|
||||
B(LdaZero),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrue), U8(59),
|
||||
B(JumpIfTrue), U8(63),
|
||||
B(LdaSmi), U8(1),
|
||||
B(TestEqualStrict), R(4),
|
||||
B(JumpIfTrueConstant), U8(3),
|
||||
B(LdaSmi), U8(76),
|
||||
B(Star), R(5),
|
||||
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
|
||||
B(LdaSmi), U8(-2),
|
||||
B(Star), R(4),
|
||||
B(CreateFunctionContext), U8(9),
|
||||
B(PushContext), R(0),
|
||||
B(Ldar), R(this),
|
||||
@ -594,9 +600,9 @@ constant pool: [
|
||||
kInstanceTypeDontCare,
|
||||
]
|
||||
handlers: [
|
||||
[41, 671, 677],
|
||||
[139, 426, 432],
|
||||
[142, 380, 382],
|
||||
[528, 540, 542],
|
||||
[45, 675, 681],
|
||||
[143, 430, 436],
|
||||
[146, 384, 386],
|
||||
[532, 544, 546],
|
||||
]
|
||||
|
||||
|
@ -369,3 +369,10 @@ assertEqualsAsync(
|
||||
"20", () => (async(foo, { a = "0" }) => foo + a)("2", { a: undefined }));
|
||||
assertThrows(() => eval("async({ foo = 1 })"), SyntaxError);
|
||||
assertThrows(() => eval("async(a, { foo = 1 })"), SyntaxError);
|
||||
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=628984
|
||||
async function gaga() {
|
||||
let i = 1;
|
||||
while (i-- > 0) { await 42 }
|
||||
}
|
||||
assertDoesNotThrow(gaga);
|
||||
|
Loading…
Reference in New Issue
Block a user