a8176a530c
Nop bytecodes are required only for break locations in debugger. Since nop bytecode doesn't change program state we can remove all of them. There are at least two changes which this CL produce: - we don't provide break position when we load local variable (still provide when load variable from global), - we don't provide break position for statements without actual break positions (e.g. "a;") - these expressions should be super rare and user always can set breakpoint before or after this statement. More details in one pager: https://docs.google.com/a/google.com/document/d/1JXlQpfMa9vRojbE272b6GMBbrfh6m_00135iAUOJEz8/edit?usp=sharing Bug: v8:6425 Change-Id: I4aee73d497a84f7b5d89caa6dda6d3060567dfda Reviewed-on: https://chromium-review.googlesource.com/543161 Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org> Cr-Commit-Position: refs/heads/master@{#46742}
272 lines
4.8 KiB
Plaintext
272 lines
4.8 KiB
Plaintext
Checks Debugger.getPossibleBreakpoints
|
|
// Copyright 2017 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.
|
|
|
|
function testEval() {
|
|
|C|eval('// comment only');
|
|
|C|eval('// comment only\n');
|
|
|R|}
|
|
|
|
// function without return
|
|
function procedure() {
|
|
var a = |_|1;
|
|
var b = |_|2;
|
|
|R|}
|
|
|
|
function testProcedure() {
|
|
|C|procedure();
|
|
|R|}
|
|
|
|
function returnTrue() {
|
|
|_|return true;|R|
|
|
}
|
|
|
|
function testIf() {
|
|
var a;
|
|
if (true) |_|a = true;
|
|
|_|if (!a) {
|
|
|_|a = true;
|
|
} else {
|
|
|_|a = false;
|
|
}
|
|
|_|if (|C|returnTrue()) {
|
|
|_|a = false;
|
|
} else {
|
|
|_|a = true;
|
|
}
|
|
|R|}
|
|
|
|
function emptyFunction() {|R|}
|
|
|
|
function testEmptyFunction() {
|
|
|C|emptyFunction();
|
|
|R|}
|
|
|
|
function twoArguments(a1, a2) {
|
|
|R|}
|
|
|
|
function testCallArguments() {
|
|
|C|twoArguments(|C|emptyFunction(), |C|emptyFunction());
|
|
|R|}
|
|
|
|
function testNested() {
|
|
function nested1() {
|
|
function nested2() {
|
|
function nested3() {
|
|
|R|}
|
|
|C|nested3();
|
|
|_|return;|R|
|
|
}
|
|
return |C|nested2();|R|
|
|
}
|
|
|C|nested1();
|
|
|R|}
|
|
|
|
function return42() {
|
|
|_|return 42;|R|
|
|
}
|
|
|
|
function returnCall() {
|
|
|_|return |C|return42();|R|
|
|
}
|
|
|
|
function testCallAtReturn() {
|
|
|_|return |C|returnCall();|R|
|
|
}
|
|
|
|
function returnObject() {
|
|
|_|return ({ foo: () => |_|42|R| });|R|
|
|
}
|
|
|
|
function testWith() {
|
|
|_|with (|C|returnObject()) {
|
|
|C|foo();
|
|
}
|
|
|_|with({}) {
|
|
|_|return;|R|
|
|
}
|
|
}
|
|
|
|
function testForLoop() {
|
|
for (var i = |_|0; i |_|< 1; ++|_|i) {}
|
|
for (var i = |_|0; i |_|< 1; ++|_|i) i;
|
|
for (var i = |_|0; i |_|< 0; ++|_|i) {}
|
|
|R|}
|
|
|
|
function testForOfLoop() {
|
|
for (var |_|k of |_|[]) {}
|
|
for (var |_|k of |_|[1]) |_|k;
|
|
var a = |_|[];
|
|
for (var |_|k of |_|a) {}
|
|
|R|}
|
|
|
|
function testForInLoop() {
|
|
var o = |_|{};
|
|
for (var |_|k in |_|o) {}
|
|
for (var |_|k in |_|o) |_|k;
|
|
for (var |_|k in |_|{ a:1 }) {}
|
|
for (var |_|k in |_|{ a:1 }) |_|k;
|
|
|R|}
|
|
|
|
function testSimpleExpressions() {
|
|
1 + 2 + 3;
|
|
var a = |_|1;
|
|
|_|++a;
|
|
|_|a--;
|
|
|R|}
|
|
|
|
Object.defineProperty(this, 'getterFoo', {
|
|
get: () => |_|return42|R|
|
|
});
|
|
|
|
function testGetter() {
|
|
|C|getterFoo();
|
|
|R|}
|
|
|
|
var obj = {
|
|
foo: () => (|_|{
|
|
boo: () => |_|return42|R|
|
|
})|R|
|
|
};
|
|
|
|
function testChainedCalls() {
|
|
|_|obj.|C|foo().|C|boo()|C|();
|
|
|R|}
|
|
|
|
function testChainedWithNative() {
|
|
|_|Array.|C|from([1]).|C|concat([2]).|C|map(v => v |_|* 2|R|);
|
|
|R|}
|
|
|
|
function testPromiseThen() {
|
|
|_|return Promise.|C|resolve().|C|then(v => v |_|* 2|R|).|C|then(v => v |_|* 2|R|);|R|
|
|
}
|
|
|
|
function testSwitch() {
|
|
for (var i = |_|0; i |_|< 3; ++|_|i) {
|
|
|_|switch(i) {
|
|
case 0: |_|continue;
|
|
case 1: |C|return42(); |_|break;
|
|
default: |_|return;|R|
|
|
}
|
|
}
|
|
|R|}
|
|
|
|
function* idMaker() {
|
|
|_|yield 1;
|
|
|_|yield 2;
|
|
|_|yield 3;
|
|
|R|}
|
|
|
|
function testGenerator() {
|
|
var gen = |C|idMaker();
|
|
|C|return42();
|
|
gen.|C|next().value;
|
|
|D|debugger;
|
|
gen.|C|next().value;
|
|
|C|return42();
|
|
gen.|C|next().value;
|
|
|C|return42();
|
|
gen.|C|next().value;
|
|
|R|}
|
|
|
|
function throwException() {
|
|
|_|throw |C|new Error();
|
|
}
|
|
|
|
function testCaughtException() {
|
|
try {
|
|
|C|throwException()
|
|
} catch (e) {
|
|
|_|return;|R|
|
|
}
|
|
|R|}
|
|
|
|
function testClasses() {
|
|
class Cat {
|
|
constructor(name) {
|
|
|_|this.name = name;
|
|
|R|}
|
|
|
|
speak() {
|
|
|R|}
|
|
}
|
|
class Lion extends Cat {
|
|
constructor(name) {
|
|
|C|super(name);
|
|
|R|}
|
|
|
|
speak() {
|
|
|_|super.|C|speak();
|
|
|R|}
|
|
}
|
|
|C|new Lion().|C|speak();
|
|
|R|}
|
|
|
|
async function asyncFoo() {
|
|
|_|await Promise.|C|resolve().|C|then(v => v |_|* 2|R|);
|
|
|C|return42();
|
|
|_|await |C|asyncBoo();
|
|
|R|}
|
|
|
|
async function asyncBoo() {
|
|
|_|await Promise.|C|resolve();
|
|
|R|}
|
|
|
|
async function testAsyncAwait() {
|
|
|_|await |C|asyncFoo();
|
|
|_|await |C|awaitBoo();
|
|
|R|}
|
|
|
|
// TODO(kozyatinskiy): fix this.
|
|
async function testPromiseAsyncWithCode() {
|
|
var nextTest;
|
|
var testPromise = |C|new Promise(resolve => nextTest |_|= resolve|R|);
|
|
async function main() {
|
|
async function foo() {
|
|
var resolveNested;
|
|
var p = |C|new Promise(resolve => resolveNested |_|= resolve|R|);
|
|
|C|setTimeout(resolveNested, 0);
|
|
|_|await p;
|
|
|R|}
|
|
|C|setTimeout(returnCall, 0);
|
|
await |C|foo();
|
|
await |C|foo();
|
|
|C|nextTest();
|
|
|R|}
|
|
|C|main();
|
|
|_|return testPromise;
|
|
|R|}
|
|
|
|
function returnFunction() {
|
|
|_|return returnObject;|R|
|
|
}
|
|
|
|
async function testPromiseComplex() {
|
|
var nextTest;
|
|
var testPromise = |C|new Promise(resolve => nextTest |_|= resolve|R|);
|
|
async function main() {
|
|
async function foo() {
|
|
|_|await Promise.|C|resolve();
|
|
|_|return 42;
|
|
|R|}
|
|
var x = |_|1;
|
|
var y = |_|2;
|
|
|C|returnFunction(|C|emptyFunction(), x++, --y, x => 2 |_|* x|R|, |C|returnCall())|C|().a = await |C|foo((a => 2 |_|*a|R|)|C|(5));
|
|
|C|nextTest();
|
|
|R|}
|
|
|C|main();
|
|
|_|return testPromise;
|
|
|R|}
|
|
|
|
function twiceDefined() {
|
|
return a + b;
|
|
}
|
|
|
|
function twiceDefined() {
|
|
|_|return a + b;|R|
|
|
}
|
|
|
|
|
|
|