2018-05-30 14:21:39 +00:00
|
|
|
// Copyright 2018 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('stepOut async function');
|
|
|
|
|
|
|
|
session.setupScriptMap();
|
|
|
|
|
2018-05-30 23:16:08 +00:00
|
|
|
Protocol.Runtime.enable();
|
2018-05-30 14:21:39 +00:00
|
|
|
|
2018-05-30 23:16:08 +00:00
|
|
|
InspectorTest.runAsyncTestSuite([
|
|
|
|
async function testTrivial() {
|
|
|
|
InspectorTest.log('Check that we have proper async stack at return');
|
|
|
|
contextGroup.addInlineScript(`
|
|
|
|
async function test() {
|
|
|
|
await Promise.resolve();
|
|
|
|
await foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function foo() {
|
|
|
|
await Promise.resolve();
|
|
|
|
await bar();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function bar() {
|
|
|
|
await Promise.resolve();
|
|
|
|
debugger;
|
|
|
|
}`, 'testTrivial.js');
|
|
|
|
await runTestAndStepAction('stepOut');
|
|
|
|
},
|
|
|
|
|
|
|
|
async function testStepOutPrecision() {
|
|
|
|
InspectorTest.log('Check that stepOut go to resumed outer generator');
|
|
|
|
contextGroup.addInlineScript(`
|
|
|
|
function wait() {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
|
|
}
|
|
|
|
function floodWithTimeouts(a) {
|
|
|
|
if (!a.stop)
|
|
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function test() {
|
|
|
|
let a = {};
|
|
|
|
floodWithTimeouts(a)
|
|
|
|
await wait();
|
|
|
|
await foo();
|
|
|
|
await wait();
|
|
|
|
a.stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function foo() {
|
|
|
|
await Promise.resolve();
|
|
|
|
await bar();
|
|
|
|
await wait();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function bar() {
|
|
|
|
await Promise.resolve();
|
|
|
|
debugger;
|
|
|
|
await wait();
|
|
|
|
}`, 'testStepOutPrecision.js');
|
|
|
|
await runTestAndStepAction('stepOut');
|
|
|
|
},
|
|
|
|
|
|
|
|
async function testStepIntoAtReturn() {
|
|
|
|
InspectorTest.log('Check that stepInto at return go to resumed outer generator');
|
|
|
|
contextGroup.addInlineScript(`
|
|
|
|
function wait() {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
|
|
}
|
|
|
|
function floodWithTimeouts(a) {
|
|
|
|
if (!a.stop)
|
|
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function test() {
|
|
|
|
let a = {};
|
|
|
|
floodWithTimeouts(a)
|
|
|
|
await wait();
|
|
|
|
await foo();
|
|
|
|
a.stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function foo() {
|
|
|
|
await Promise.resolve();
|
|
|
|
await bar();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function bar() {
|
|
|
|
await Promise.resolve();
|
|
|
|
debugger;
|
|
|
|
}`, 'testStepIntoAtReturn.js');
|
|
|
|
await runTestAndStepAction('stepInto');
|
|
|
|
},
|
2018-05-30 14:21:39 +00:00
|
|
|
|
2018-05-30 23:16:08 +00:00
|
|
|
async function testStepOverAtReturn() {
|
|
|
|
InspectorTest.log('Check that stepOver at return go to resumed outer generator');
|
|
|
|
contextGroup.addInlineScript(`
|
|
|
|
function wait() {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
|
|
}
|
|
|
|
function floodWithTimeouts(a) {
|
|
|
|
if (!a.stop)
|
|
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function test() {
|
|
|
|
let a = {};
|
|
|
|
floodWithTimeouts(a)
|
|
|
|
await wait();
|
|
|
|
await foo();
|
|
|
|
a.stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function foo() {
|
|
|
|
await Promise.resolve();
|
|
|
|
await bar();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function bar() {
|
|
|
|
await Promise.resolve();
|
|
|
|
debugger;
|
|
|
|
}`, 'testStepIntoAtReturn.js');
|
|
|
|
await runTestAndStepAction('stepOver');
|
|
|
|
},
|
|
|
|
|
|
|
|
async function testStepOutFromNotAwaitedCall() {
|
|
|
|
InspectorTest.log('Checks stepOut from not awaited call');
|
|
|
|
contextGroup.addInlineScript(`
|
|
|
|
function wait() {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
|
|
}
|
|
|
|
function floodWithTimeouts(a) {
|
|
|
|
if (!a.stop)
|
|
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function test() {
|
|
|
|
let a = {};
|
|
|
|
floodWithTimeouts(a)
|
|
|
|
await wait();
|
|
|
|
await foo();
|
|
|
|
a.stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function foo() {
|
|
|
|
let a = {};
|
|
|
|
floodWithTimeouts(a);
|
|
|
|
await Promise.resolve();
|
|
|
|
bar();
|
|
|
|
a.stop = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function bar() {
|
|
|
|
await Promise.resolve();
|
|
|
|
debugger;
|
|
|
|
}`, 'testStepIntoAtReturn.js');
|
|
|
|
await runTestAndStepAction('stepOut');
|
|
|
|
}
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
async function runTestAndStepAction(action) {
|
2018-05-30 14:21:39 +00:00
|
|
|
Protocol.Debugger.enable();
|
|
|
|
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
|
|
|
|
let finished =
|
|
|
|
Protocol.Runtime.evaluate({expression: 'test()', awaitPromise: true})
|
|
|
|
.then(() => false);
|
|
|
|
while (true) {
|
|
|
|
const r = await Promise.race([finished, waitPauseAndDumpStack()]);
|
|
|
|
if (!r) break;
|
2018-05-30 23:16:08 +00:00
|
|
|
Protocol.Debugger[action]();
|
2018-05-30 14:21:39 +00:00
|
|
|
}
|
2018-05-30 23:16:08 +00:00
|
|
|
await Protocol.Debugger.disable();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function waitPauseAndDumpStack() {
|
|
|
|
const {params} = await Protocol.Debugger.oncePaused();
|
|
|
|
session.logCallFrames(params.callFrames);
|
|
|
|
session.logAsyncStackTrace(params.asyncStackTrace);
|
|
|
|
InspectorTest.log('');
|
|
|
|
return true;
|
|
|
|
}
|