887bacacb0
This change addresses inconsistencies wrt. to stepping into generator functions and breaking on the implicit initial yield. The new behavior is the following: 1. Stepping into a generator function doesn't trigger "generator stepping", but rather pauses right before the initial yield (assuming there a no non-simple parameters in between). 2. When paused on the initial yield and stepping into or over, we also don't turn on "generator stepping" immediately, but rather return to the caller and only enter "generator stepping" on SuspendGenerator bytecodes that correspond to `yield`s or `await`s in the source code. This matches the stepping behavior of regular functions more closely and seems like a good compromise. Fixed: chromium:901814 Change-Id: Ifc6c174011df1afea183e2c6ec21de27d72b17a7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2949099 Commit-Queue: Yang Guo <yangguo@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#75066}
88 lines
3.3 KiB
JavaScript
88 lines
3.3 KiB
JavaScript
// Copyright 2021 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 {session, contextGroup, Protocol} = InspectorTest.start('Async generator stepping');
|
|
|
|
const url = 'stepping-async-generator.js';
|
|
contextGroup.addScript(`
|
|
async function* generator() {
|
|
var a = 42;
|
|
yield a;
|
|
}
|
|
function callGenerator() {
|
|
return generator();
|
|
}
|
|
`, 0, 0, url);
|
|
|
|
session.setupScriptMap();
|
|
|
|
InspectorTest.runAsyncTestSuite([
|
|
async function testStepOverFromInitialYield() {
|
|
await Promise.all([Protocol.Debugger.enable(), Protocol.Runtime.enable()]);
|
|
InspectorTest.log(`Setting breakpoint on implicit initial yield`);
|
|
const {result: {breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
|
|
url,
|
|
lineNumber: 1,
|
|
columnNumber: 0,
|
|
})
|
|
InspectorTest.log(`Calling callGenerator()`);
|
|
const pausedPromise = Protocol.Debugger.oncePaused();
|
|
const evalPromise = Protocol.Runtime.evaluate({expression: 'callGenerator()'});
|
|
const {method, params} = await Promise.race([pausedPromise, evalPromise]);
|
|
if (method === 'Debugger.paused') {
|
|
await session.logSourceLocation(params.callFrames[0].location);
|
|
|
|
InspectorTest.log('Stepping over while paused on the initial yield');
|
|
const [{params: {callFrames:[{location}]}}] = await Promise.all([
|
|
Protocol.Debugger.oncePaused(),
|
|
Protocol.Debugger.stepOver(),
|
|
]);
|
|
await session.logSourceLocation(location);
|
|
|
|
await Promise.all([Protocol.Debugger.resume(), evalPromise]);
|
|
} else {
|
|
InspectorTest.log('Did not pause');
|
|
}
|
|
await Protocol.Debugger.removeBreakpoint({breakpointId});
|
|
await Promise.all([Protocol.Debugger.disable(), Protocol.Runtime.disable()]);
|
|
},
|
|
|
|
async function testStepIntoInitialYield() {
|
|
await Promise.all([Protocol.Debugger.enable(), Protocol.Runtime.enable()]);
|
|
InspectorTest.log(`Setting breakpoint on call to generator()`);
|
|
const {result: {breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
|
|
url,
|
|
lineNumber: 5,
|
|
columnNumber: 0,
|
|
})
|
|
InspectorTest.log(`Calling callGenerator()`);
|
|
const pausedPromise = Protocol.Debugger.oncePaused();
|
|
const evalPromise = Protocol.Runtime.evaluate({expression: 'callGenerator()'});
|
|
const {method, params} = await Promise.race([pausedPromise, evalPromise]);
|
|
if (method === 'Debugger.paused') {
|
|
await session.logSourceLocation(params.callFrames[0].location);
|
|
|
|
InspectorTest.log('Stepping into the generator()');
|
|
let [{params: {callFrames:[{location}]}}] = await Promise.all([
|
|
Protocol.Debugger.oncePaused(),
|
|
Protocol.Debugger.stepInto(),
|
|
]);
|
|
await session.logSourceLocation(location);
|
|
|
|
InspectorTest.log('Stepping into while paused on the initial yield');
|
|
([{params: {callFrames:[{location}]}}] = await Promise.all([
|
|
Protocol.Debugger.oncePaused(),
|
|
Protocol.Debugger.stepInto(),
|
|
]));
|
|
await session.logSourceLocation(location);
|
|
|
|
await Promise.all([Protocol.Debugger.resume(), evalPromise]);
|
|
} else {
|
|
InspectorTest.log('Did not pause');
|
|
}
|
|
await Protocol.Debugger.removeBreakpoint({breakpointId});
|
|
await Promise.all([Protocol.Debugger.disable(), Protocol.Runtime.disable()]);
|
|
}
|
|
]);
|