v8/test/mjsunit/code-coverage-block.js
Sigurd Schneider 0d7889d0b1 [coverage] Correctly report coverage for inline scripts
This fixes a bug where coverage for the inline script
  <script>function foo() {}<script>
started to get deterministically reported as covered
after crrev.com/c/1771776, while before it, we most of
the time reported it as uncovered (depending on heap
order of SFIs). The correct result is to report `foo`
as uncovered as it is never called.

The problem arose from the fact that v8:9212 needed to
handle extra-wrappers around scripts correctly. Those
wrappers have the same source range as the wrapped
script and a call count of zero even if the wrapped
script is executed. To filter them out, we previously
determined nesting for identical source ranges by
ascending call count. However, in the script case above,
the script has call count one, while `foo` (which has
the same source range) has call count zero. In this
case, nesting is decreasing order of call counts.

This CL is a minimal change that sorts SFIs which are
top-level to the front, only then considers call counts
in descending order. This preserves the behavior that
node's extra wrappers are sorted to the front (and
then filtered out by existing logic), but also ensures
that for the example above, we report the script's
coverage before the coverage for `foo`.


Bug: v8:9857, v9:9212
Change-Id: Id224b0d8f12028b1f586ee5039e126bb5b8d8d36
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863197
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64307}
2019-10-16 08:23:55 +00:00

1087 lines
38 KiB
JavaScript

// 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.
// Flags: --allow-natives-syntax --no-always-opt --no-stress-flush-bytecode
// Files: test/mjsunit/code-coverage-utils.js
%DebugToggleBlockCoverage(true);
TestCoverage(
"call an IIFE",
`
(function f() {})();
`,
[{"start":0,"end":20,"count":1},{"start":1,"end":16,"count":1}]
);
TestCoverage(
"call locally allocated function",
`let f = () => 1; f();`,
[{"start":0,"end":21,"count":1},{"start":8,"end":15,"count":1}]
);
TestCoverage(
"if statements",
`
function g() {} // 0000
function f(x) { // 0050
if (x == 42) { // 0100
if (x == 43) g(); else g(); // 0150
} // 0200
if (x == 42) { g(); } else { g(); } // 0250
if (x == 42) g(); else g(); // 0300
if (false) g(); else g(); // 0350
if (false) g(); // 0400
if (true) g(); else g(); // 0450
if (true) g(); // 0500
} // 0550
f(42); // 0600
f(43); // 0650
if (true) { // 0700
const foo = 'bar'; // 0750
} else { // 0800
const bar = 'foo'; // 0850
} // 0900
`,
[{"start":0,"end":949,"count":1},
{"start":801,"end":901,"count":0},
{"start":0,"end":15,"count":11},
{"start":50,"end":551,"count":2},
{"start":115,"end":203,"count":1},
{"start":167,"end":171,"count":0},
{"start":265,"end":287,"count":1},
{"start":315,"end":329,"count":1},
{"start":363,"end":367,"count":0},
{"start":413,"end":417,"count":0},
{"start":466,"end":476,"count":0}]
);
TestCoverage(
"if statement (early return)",
`
!function() { // 0000
if (true) { // 0050
nop(); // 0100
return; // 0150
nop(); // 0200
} // 0250
nop(); // 0300
}() // 0350
`,
[{"start":0,"end":399,"count":1},
{"start":1,"end":351,"count":1},
{"start":161,"end":350,"count":0}]
);
TestCoverage(
"if statement (no semi-colon)",
`
!function() { // 0000
if (true) nop() // 0050
if (true) nop(); else nop() // 0100
nop(); // 0150
}() // 0200
`,
[{"start":0,"end":249,"count":1},
{"start":1,"end":201,"count":1},
{"start":118,"end":129,"count":0}]
);
TestCoverage(
"for statements",
`
function g() {} // 0000
!function() { // 0050
for (var i = 0; i < 12; i++) g(); // 0100
for (var i = 0; i < 12; i++) { // 0150
g(); // 0200
} // 0250
for (var i = 0; false; i++) g(); // 0300
for (var i = 0; true; i++) break; // 0350
for (var i = 0; i < 12; i++) { // 0400
if (i % 3 == 0) g(); else g(); // 0450
} // 0500
}(); // 0550
`,
[{"start":0,"end":599,"count":1},
{"start":0,"end":15,"count":36},
{"start":51,"end":551,"count":1},
{"start":131,"end":135,"count":12},
{"start":181,"end":253,"count":12},
{"start":330,"end":334,"count":0},
{"start":431,"end":503,"count":12},
{"start":470,"end":474,"count":4},
{"start":474,"end":484,"count":8}]
);
TestCoverage(
"for statements pt. 2",
`
function g() {} // 0000
!function() { // 0050
let j = 0; // 0100
for (let i = 0; i < 12; i++) g(); // 0150
for (const i = 0; j < 12; j++) g(); // 0200
for (j = 0; j < 12; j++) g(); // 0250
for (;;) break; // 0300
}(); // 0350
`,
[{"start":0,"end":399,"count":1},
{"start":0,"end":15,"count":36},
{"start":51,"end":351,"count":1},
{"start":181,"end":185,"count":12},
{"start":233,"end":237,"count":12},
{"start":277,"end":281,"count":12}]
);
TestCoverage(
"for statements (no semicolon)",
`
function g() {} // 0000
!function() { // 0050
for (let i = 0; i < 12; i++) g() // 0100
for (let i = 0; i < 12; i++) break // 0150
for (let i = 0; i < 12; i++) break; g() // 0200
}(); // 0250
`,
[{"start":0,"end":299,"count":1},
{"start":0,"end":15,"count":13},
{"start":51,"end":251,"count":1},
{"start":131,"end":134,"count":12}]
);
TestCoverage(
"for statement (early return)",
`
!function() { // 0000
for (var i = 0; i < 10; i++) { // 0050
nop(); // 0100
continue; // 0150
nop(); // 0200
} // 0250
nop(); // 0300
for (;;) { // 0350
nop(); // 0400
break; // 0450
nop(); // 0500
} // 0550
nop(); // 0600
for (;;) { // 0650
nop(); // 0700
return; // 0750
nop(); // 0800
} // 0850
nop(); // 0900
}() // 0950
`,
[{"start":0,"end":999,"count":1},
{"start":1,"end":951,"count":1},
{"start":81,"end":253,"count":10},
{"start":163,"end":253,"count":0},
{"start":460,"end":553,"count":0},
{"start":761,"end":950,"count":0}]
);
TestCoverage(
"for-of and for-in statements",
`
!function() { // 0000
var i; // 0050
for (i of [0,1,2,3]) { nop(); } // 0100
for (let j of [0,1,2,3]) { nop(); } // 0150
for (i in [0,1,2,3]) { nop(); } // 0200
for (let j in [0,1,2,3]) { nop(); } // 0250
var xs = [{a:0, b:1}, {a:1,b:0}]; // 0300
for (var {a: x, b: y} of xs) { nop(); } // 0350
}(); // 0400
`,
[{"start":0,"end":449,"count":1},
{"start":1,"end":401,"count":1},
{"start":123,"end":133,"count":4},
{"start":177,"end":187,"count":4},
{"start":223,"end":233,"count":4},
{"start":277,"end":287,"count":4},
{"start":381,"end":391,"count":2}]
);
TestCoverage(
"while and do-while statements",
`
function g() {} // 0000
!function() { // 0050
var i; // 0100
i = 0; while (i < 12) i++; // 0150
i = 0; while (i < 12) { g(); i++; } // 0200
i = 0; while (false) g(); // 0250
i = 0; while (true) break; // 0300
// 0350
i = 0; do i++; while (i < 12); // 0400
i = 0; do { g(); i++; } // 0450
while (i < 12); // 0500
i = 0; do { g(); } while (false); // 0550
i = 0; do { break; } while (true); // 0600
}(); // 0650
`,
[{"start":0,"end":699,"count":1},
{"start":0,"end":15,"count":25},
{"start":51,"end":651,"count":1},
{"start":174,"end":178,"count":12},
{"start":224,"end":237,"count":12},
{"start":273,"end":277,"count":0},
{"start":412,"end":416,"count":12},
{"start":462,"end":475,"count":12}]
);
TestCoverage(
"while statement (early return)",
`
!function() { // 0000
let i = 0; // 0050
while (i < 10) { // 0100
i++; // 0150
continue; // 0200
nop(); // 0250
} // 0300
nop(); // 0350
while (true) { // 0400
nop(); // 0450
break; // 0500
nop(); // 0550
} // 0600
nop(); // 0650
while (true) { // 0700
nop(); // 0750
return; // 0800
nop(); // 0850
} // 0900
nop(); // 0950
}() // 1000
`,
[{"start":0,"end":1049,"count":1},
{"start":1,"end":1001,"count":1},
{"start":117,"end":303,"count":10},
{"start":213,"end":303,"count":0},
{"start":510,"end":603,"count":0},
{"start":811,"end":1000,"count":0}]
);
TestCoverage(
"do-while statement (early return)",
`
!function() { // 0000
let i = 0; // 0050
do { // 0100
i++; // 0150
continue; // 0200
nop(); // 0250
} while (i < 10); // 0300
nop(); // 0350
do { // 0400
nop(); // 0450
break; // 0500
nop(); // 0550
} while (true); // 0600
nop(); // 0650
do { // 0700
nop(); // 0750
return; // 0800
nop(); // 0850
} while (true); // 0900
nop(); // 0950
}() // 1000
`,
[{"start":0,"end":1049,"count":1},
{"start":1,"end":1001,"count":1},
{"start":105,"end":303,"count":10},
{"start":213,"end":303,"count":0},
{"start":510,"end":603,"count":0},
{"start":811,"end":1000,"count":0}]
);
TestCoverage(
"return statements",
`
!function() { nop(); return; nop(); }(); // 0000
!function() { nop(); return 42; // 0050
nop(); }(); // 0100
`,
[{"start":0,"end":149,"count":1},
{"start":1,"end":37,"count":1},
{"start":28,"end":36,"count":0},
{"start":51,"end":122,"count":1},
{"start":81,"end":121,"count":0}]
);
TestCoverage(
"try/catch/finally statements",
`
!function() { // 0000
try { nop(); } catch (e) { nop(); } // 0050
try { nop(); } finally { nop(); } // 0100
try { // 0150
try { throw 42; } catch (e) { nop(); }// 0200
} catch (e) { nop(); } // 0250
try { // 0300
try { throw 42; } finally { nop(); } // 0350
} catch (e) { nop(); } // 0400
try { // 0450
throw 42; // 0500
} catch (e) { // 0550
nop(); // 0600
} finally { // 0650
nop(); // 0700
} // 0750
}(); // 0800
`,
[{"start":0,"end":849,"count":1},
{"start":1,"end":801,"count":1},
{"start":67,"end":87,"count":0},
{"start":221,"end":222,"count":0},
{"start":254,"end":274,"count":0},
{"start":371,"end":372,"count":0},
{"start":403,"end":404,"count":0},
{"start":553,"end":554,"count":0}]
);
TestCoverage("try/catch/finally statements with early return",
`
!function() { // 0000
try { throw 42; } catch (e) { return; } // 0050
nop(); // 0100
}(); // 0150
!function() { // 0200
try { throw 42; } catch (e) {} // 0250
finally { return; } // 0300
nop(); // 0350
}(); // 0400
`,
[{"start":0,"end":449,"count":1},
{"start":1,"end":151,"count":1},
{"start":69,"end":70,"count":0},
{"start":91,"end":150,"count":0},
{"start":201,"end":401,"count":1},
{"start":269,"end":270,"count":0},
{"start":321,"end":400,"count":0}]
);
TestCoverage(
"early return in blocks",
`
!function() { // 0000
try { throw 42; } catch (e) { return; } // 0050
nop(); // 0100
}(); // 0150
!function() { // 0200
try { nop(); } finally { return; } // 0250
nop(); // 0300
}(); // 0350
!function() { // 0400
{ // 0450
let x = 42; // 0500
return () => x; // 0550
} // 0600
nop(); // 0650
}(); // 0700
!function() { // 0750
try { throw 42; } catch (e) { // 0800
return; // 0850
nop(); // 0900
} // 0950
nop(); // 1000
}(); // 1050
`,
[{"start":0,"end":1099,"count":1},
{"start":1,"end":151,"count":1},
{"start":69,"end":70,"count":0},
{"start":91,"end":150,"count":0},
{"start":201,"end":351,"count":1},
{"start":286,"end":350,"count":0},
{"start":401,"end":701,"count":1},
{"start":603,"end":700,"count":0},
{"start":561,"end":568,"count":0},
{"start":751,"end":1051,"count":1},
{"start":819,"end":820,"count":0},
{"start":861,"end":1050,"count":0}]
);
TestCoverage(
"switch statements",
`
!function() { // 0000
var x = 42; // 0050
switch (x) { // 0100
case 41: nop(); break; // 0150
case 42: nop(); break; // 0200
default: nop(); break; // 0250
} // 0300
}(); // 0350
`,
[{"start":0,"end":399,"count":1},
{"start":1,"end":351,"count":1},
{"start":154,"end":176,"count":0},
{"start":254,"end":276,"count":0}]
);
TestCoverage(
"labeled break statements",
`
!function() { // 0000
var x = 42; // 0050
l0: switch (x) { // 0100
case 41: return; // 0150
case 42: // 0200
switch (x) { case 42: break l0; } // 0250
break; // 0300
} // 0350
l1: for (;;) { // 0400
for (;;) break l1; // 0450
} // 0500
l2: while (true) { // 0550
while (true) break l2; // 0600
} // 0650
l3: do { // 0700
do { break l3; } while (true); // 0750
} while (true); // 0800
l4: { break l4; } // 0850
l5: for (;;) for (;;) break l5; // 0900
}(); // 0950
`,
[{"start":0,"end":999,"count":1},
{"start":1,"end":951,"count":1},
{"start":152,"end":168,"count":0},
{"start":287,"end":310,"count":0}]
);
TestCoverage(
"labeled continue statements",
`
!function() { // 0000
l0: for (var i0 = 0; i0 < 2; i0++) { // 0050
for (;;) continue l0; // 0100
} // 0150
var i1 = 0; // 0200
l1: while (i1 < 2) { // 0250
i1++; // 0300
while (true) continue l1; // 0350
} // 0400
var i2 = 0; // 0450
l2: do { // 0500
i2++; // 0550
do { continue l2; } while (true); // 0600
} while (i2 < 2); // 0650
}(); // 0700
`,
[{"start":0,"end":749,"count":1},
{"start":1,"end":701,"count":1},
{"start":87,"end":153,"count":2},
{"start":271,"end":403,"count":2},
{"start":509,"end":653,"count":2}]
);
TestCoverage(
"conditional expressions",
`
var TRUE = true; // 0000
var FALSE = false; // 0050
!function() { // 0100
TRUE ? nop() : nop(); // 0150
true ? nop() : nop(); // 0200
false ? nop() : nop(); // 0250
FALSE ? TRUE ? nop() // 0300
: nop() // 0350
: nop(); // 0400
TRUE ? FALSE ? nop() // 0450
: nop() // 0500
: nop(); // 0550
TRUE ? nop() : FALSE ? nop() // 0600
: nop(); // 0650
FALSE ? nop() : TRUE ? nop() // 0700
: nop(); // 0750
}(); // 0800
`,
[{"start":0,"end":849,"count":1},
{"start":101,"end":801,"count":1},
{"start":165,"end":172,"count":0},
{"start":215,"end":222,"count":0},
{"start":258,"end":265,"count":0},
{"start":308,"end":372,"count":0},
{"start":465,"end":472,"count":0},
{"start":557,"end":564,"count":0},
{"start":615,"end":680,"count":0},
{"start":708,"end":715,"count":0},
{"start":773,"end":780,"count":0}]
);
TestCoverage(
"yield expressions",
`
const it = function*() { // 0000
yield nop(); // 0050
yield nop() ? nop() : nop() // 0100
return nop(); // 0150
}(); // 0200
it.next(); it.next(); // 0250
`,
[{"start":0,"end":299,"count":1},
{"start":11,"end":201,"count":1},
{"start":114,"end":121,"count":0},
{"start":129,"end":200,"count":0}]
);
TestCoverage(
"yield expressions twice",
`
function* gen() { // 0000
yield nop(); // 0050
yield nop() ? nop() : nop() // 0100
return nop(); // 0150
}; // 0200
{const it = gen(); it.next(); it.next();} // 0250
{const it = gen(); it.next(); it.next();} // 0300
`,
[{"start":0,"end":349,"count":1},
{"start":0,"end":201,"count":2},
{"start":114,"end":121,"count":0},
{"start":129,"end":200,"count":0}]
);
TestCoverage(
"yield expressions (.return and .throw)",
`
const it0 = function*() { // 0000
yield 1; yield 2; yield 3; // 0050
}(); // 0100
it0.next(); it0.return(); // 0150
try { // 0200
const it1 = function*() { // 0250
yield 1; yield 2; yield 3; // 0300
}(); // 0350
it1.next(); it1.throw(); // 0400
} catch (e) {} // 0450
`,
[{"start":0,"end":499,"count":1},
{"start":451,"end":452,"count":0},
{"start":12,"end":101,"count":1},
{"start":60,"end":100,"count":0},
{"start":264,"end":353,"count":1},
{"start":312,"end":352,"count":0}]
);
TestCoverage("yield expressions (.return and try/catch/finally)",
`
const it = function*() { // 0000
try { // 0050
yield 1; yield 2; yield 3; // 0100
} catch (e) { // 0150
nop(); // 0200
} finally { nop(); } // 0250
yield 4; // 0300
}(); // 0350
it.next(); it.return(); // 0450
`,
[{"start":0,"end":449,"count":1},
{"start":11,"end":351,"count":1},
{"start":112,"end":254,"count":0},
{"start":272,"end":350,"count":0}]
);
TestCoverage("yield expressions (.throw and try/catch/finally)",
`
const it = function*() { // 0000
try { // 0050
yield 1; yield 2; yield 3; // 0100
} catch (e) { // 0150
nop(); // 0200
} finally { nop(); } // 0250
yield 4; // 0300
}(); // 0350
it.next(); it.throw(42); // 0550
`,
[{"start":0,"end":449,"count":1},
{"start":11,"end":351,"count":1},
{"start":112,"end":154,"count":0},
{"start":310,"end":350,"count":0}]
);
TestCoverage(
"yield* expressions",
`
const it = function*() { // 0000
yield* gen(); // 0050
yield* nop() ? gen() : gen() // 0100
return gen(); // 0150
}(); // 0200
it.next(); it.next(); it.next(); // 0250
it.next(); it.next(); it.next(); // 0300
`,
[{"start":0,"end":349,"count":1},
{"start":11,"end":201,"count":1},
{"start":115,"end":122,"count":0},
{"start":130,"end":200,"count":0}]
);
TestCoverage(
"yield* expressions (.return and .throw)",
`
const it0 = function*() { // 0000
yield* gen(); yield* gen(); yield 3; // 0050
}(); // 0100
it0.next(); it0.return(); // 0150
try { // 0200
const it1 = function*() { // 0250
yield* gen(); yield* gen(); yield 3; // 0300
}(); // 0350
it1.next(); it1.throw(); // 0400
} catch (e) {} // 0450
`,
[{"start":0,"end":499,"count":1},
{"start":451,"end":452,"count":0},
{"start":12,"end":101,"count":1},
{"start":65,"end":100,"count":0},
{"start":264,"end":353,"count":1},
{"start":317,"end":352,"count":0}]
);
TestCoverage(
"LogicalOrExpression assignment",
`
const a = true || 99 // 0000
function b () { // 0050
const b = a || 2 // 0100
} // 0150
b() // 0200
b() // 0250
`,
[{"start":0,"end":299,"count":1},
{"start":15,"end":20,"count":0},
{"start":50,"end":151,"count":2},
{"start":114,"end":118,"count":0}]
);
TestCoverage(
"LogicalOrExpression IsTest()",
`
true || false // 0000
const a = 99 // 0050
a || 50 // 0100
const b = false // 0150
if (b || true) {} // 0200
`,
[{"start":0,"end":249,"count":1},
{"start":5,"end":13,"count":0},
{"start":102,"end":107,"count":0}]);
TestCoverage(
"LogicalAndExpression assignment",
`
const a = false && 99 // 0000
function b () { // 0050
const b = a && 2 // 0100
} // 0150
b() // 0200
b() // 0250
const c = true && 50 // 0300
`,
[{"start":0,"end":349,"count":1},
{"start":16,"end":21,"count":0},
{"start":50,"end":151,"count":2},
{"start":114,"end":118,"count":0}]
);
TestCoverage(
"LogicalAndExpression IsTest()",
`
false && true // 0000
const a = 0 // 0050
a && 50 // 0100
const b = true // 0150
if (b && true) {} // 0200
true && true // 0250
`,
[{"start":0,"end":299,"count":1},
{"start":6,"end":13,"count":0},
{"start":102,"end":107,"count":0}]);
TestCoverage(
"NaryLogicalOr assignment",
`
const a = true // 0000
const b = false // 0050
const c = false || false || 99 // 0100
const d = false || true || 99 // 0150
const e = true || true || 99 // 0200
const f = b || b || 99 // 0250
const g = b || a || 99 // 0300
const h = a || a || 99 // 0350
const i = a || (b || c) || d // 0400
`,
[{"start":0,"end":449,"count":1},
{"start":174,"end":179,"count":0},
{"start":215,"end":222,"count":0},
{"start":223,"end":228,"count":0},
{"start":317,"end":322,"count":0},
{"start":362,"end":366,"count":0},
{"start":367,"end":372,"count":0},
{"start":412,"end":423,"count":0},
{"start":424,"end":428,"count":0}]);
TestCoverage(
"NaryLogicalOr IsTest()",
`
const a = true // 0000
const b = false // 0050
false || false || 99 // 0100
false || true || 99 // 0150
true || true || 99 // 0200
b || b || 99 // 0250
b || a || 99 // 0300
a || a || 99 // 0350
`,
[{"start":0,"end":399,"count":1},
{"start":164,"end":169,"count":0},
{"start":205,"end":212,"count":0},
{"start":213,"end":218,"count":0},
{"start":307,"end":312,"count":0},
{"start":352,"end":356,"count":0},
{"start":357,"end":362,"count":0}]);
TestCoverage(
"NaryLogicalAnd assignment",
`
const a = true // 0000
const b = false // 0050
const c = false && false && 99 // 0100
const d = false && true && 99 // 0150
const e = true && true && 99 // 0200
const f = true && false || true // 0250
const g = true || false && true // 0300
`,
[{"start":0,"end":349,"count":1},
{"start":116,"end":124,"count":0},
{"start":125,"end":130,"count":0},
{"start":166,"end":173,"count":0},
{"start":174,"end":179,"count":0},
{"start":315,"end":331,"count":0}
]);
TestCoverage(
"NaryLogicalAnd IsTest()",
`
const a = true // 0000
const b = false // 0050
false && false && 99 // 0100
false && true && 99 // 0150
true && true && 99 // 0200
true && false || true // 0250
true || false && true // 0300
false || false || 99 || 55 // 0350
`,
[{"start":0,"end":399,"count":1},
{"start":106,"end":114,"count":0},
{"start":115,"end":120,"count":0},
{"start":156,"end":163,"count":0},
{"start":164,"end":169,"count":0},
{"start":305,"end":321,"count":0},
{"start":371,"end":376,"count":0}]);
// see regression: https://bugs.chromium.org/p/chromium/issues/detail?id=785778
TestCoverage(
"logical expressions + conditional expressions",
`
const a = true // 0000
const b = 99 // 0050
const c = false // 0100
const d = '' // 0150
const e = a && (b ? 'left' : 'right') // 0200
const f = a || (b ? 'left' : 'right') // 0250
const g = c || d ? 'left' : 'right' // 0300
const h = a && b && (b ? 'left' : 'right')// 0350
const i = d || c || (c ? 'left' : 'right')// 0400
`,
[{"start":0,"end":449,"count":1},
{"start":227,"end":236,"count":0},
{"start":262,"end":287,"count":0},
{"start":317,"end":325,"count":0},
{"start":382,"end":391,"count":0},
{"start":423,"end":431,"count":0}
]);
TestCoverage(
"https://crbug.com/827530",
`
Util = {}; // 0000
Util.escape = function UtilEscape(str) { // 0050
if (!str) { // 0100
return 'if'; // 0150
} else { // 0200
return 'else'; // 0250
} // 0300
}; // 0350
Util.escape("foo.bar"); // 0400
`,
[{"start":0,"end":449,"count":1},
{"start":64,"end":351,"count":1},
{"start":112,"end":203,"count":0}]
);
TestCoverage(
"https://crbug.com/v8/8237",
`
!function() { // 0000
if (true) // 0050
while (false) return; else nop(); // 0100
}(); // 0150
!function() { // 0200
if (true) l0: { break l0; } else // 0250
if (nop()) { } // 0300
}(); // 0350
!function() { // 0400
if (true) { if (false) { return; } // 0450
} else if (nop()) { } }(); // 0500
!function(){ // 0550
if(true)while(false)return;else nop() // 0600
}(); // 0650
!function(){ // 0700
if(true) l0:{break l0}else if (nop()){} // 0750
}(); // 0800
!function(){ // 0850
if(true){if(false){return}}else // 0900
if(nop()){} // 0950
}(); // 1000
`,
[{"start":0,"end":1049,"count":1},
{"start":1,"end":151,"count":1},
{"start":118,"end":137,"count":0},
{"start":201,"end":351,"count":1},
{"start":279,"end":318,"count":0},
{"start":401,"end":525,"count":1},
{"start":475,"end":486,"count":0},
{"start":503,"end":523,"count":0},
{"start":551,"end":651,"count":1},
{"start":622,"end":639,"count":0},
{"start":701,"end":801,"count":1},
{"start":774,"end":791,"count":0},
{"start":851,"end":1001,"count":1},
{"start":920,"end":928,"count":0},
{"start":929,"end":965,"count":0}]
);
TestCoverage(
"terminal break statement",
`
while (true) { // 0000
const b = false // 0050
break // 0100
} // 0150
let stop = false // 0200
while (true) { // 0250
if (stop) { // 0300
break // 0350
} // 0400
stop = true // 0450
} // 0500
`,
[{"start":0,"end":549,"count":1},
{"start":263,"end":501,"count":2},
{"start":312,"end":501,"count":1}]
);
TestCoverage(
"terminal return statement",
`
function a () { // 0000
const b = false // 0050
return 1 // 0100
} // 0150
const b = (early) => { // 0200
if (early) { // 0250
return 2 // 0300
} // 0350
return 3 // 0400
} // 0450
const c = () => { // 0500
if (true) { // 0550
return // 0600
} // 0650
} // 0700
a(); b(false); b(true); c() // 0750
`,
[{"start":0,"end":799,"count":1},
{"start":0,"end":151,"count":1},
{"start":210,"end":451,"count":2},
{"start":263,"end":450,"count":1},
{"start":510,"end":701,"count":1}]
);
TestCoverage(
"terminal blocks",
`
function a () { // 0000
{ // 0050
return 'a' // 0100
} // 0150
} // 0200
function b () { // 0250
{ // 0300
{ // 0350
return 'b' // 0400
} // 0450
} // 0500
} // 0550
a(); b() // 0600
`,
[{"start":0,"end":649,"count":1},
{"start":0,"end":201,"count":1},
{"start":250,"end":551,"count":1}]
);
TestCoverage(
"terminal if statements",
`
function a (branch) { // 0000
if (branch) { // 0050
return 'a' // 0100
} else { // 0150
return 'b' // 0200
} // 0250
} // 0300
function b (branch) { // 0350
if (branch) { // 0400
if (branch) { // 0450
return 'c' // 0500
} // 0550
} // 0600
} // 0650
function c (branch) { // 0700
if (branch) { // 0750
return 'c' // 0800
} else { // 0850
return 'd' // 0900
} // 0950
} // 1000
function d (branch) { // 1050
if (branch) { // 1100
if (!branch) { // 1150
return 'e' // 1200
} else { // 1250
return 'f' // 1300
} // 1350
} else { // 1400
// noop // 1450
} // 1500
} // 1550
a(true); a(false); b(true); b(false) // 1600
c(true); d(true); // 1650
`,
[{"start":0,"end":1699,"count":1},
{"start":0,"end":301,"count":2},
{"start":64,"end":253,"count":1},
{"start":350,"end":651,"count":2},
{"start":414,"end":603,"count":1},
{"start":700,"end":1001,"count":1},
{"start":853,"end":953,"count":0},
{"start":1050,"end":1551,"count":1},
{"start":1167,"end":1255,"count":0},
{"start":1403,"end":1503,"count":0}]
);
TestCoverage(
"https://crbug.com/927464",
`
!function f() { // 0000
function unused() { nop(); } // 0050
nop(); // 0100
}(); // 0150
`,
[{"start":0,"end":199,"count":1},
{"start":1,"end":151,"count":1},
{"start":52,"end":80,"count":0}]
);
TestCoverage(
"https://crbug.com/v8/8691",
`
function f(shouldThrow) { // 0000
if (shouldThrow) { // 0050
throw Error('threw') // 0100
} // 0150
} // 0200
try { // 0250
f(true) // 0300
} catch (err) { // 0350
// 0400
} // 0450
try { // 0500
f(false) // 0550
} catch (err) {} // 0600
`,
[{"start":0,"end":649,"count":1},
{"start":351,"end":352,"count":0},
{"start":602,"end":616,"count":0},
{"start":0,"end":201,"count":2},
{"start":69,"end":153,"count":1}]
);
TestCoverage(
"https://crbug.com/v8/9705",
`
function f(x) { // 0000
switch (x) { // 0050
case 40: nop(); // 0100
case 41: nop(); return 1; // 0150
case 42: nop(); break; // 0200
} // 0250
return 3; // 0300
}; // 0350
f(40); // 0400
f(41); // 0450
f(42); // 0500
f(43); // 0550
`,
[{"start":0,"end":599,"count":1},
{"start":0,"end":351,"count":4},
{"start":104,"end":119,"count":1},
{"start":154,"end":179,"count":2},
{"start":204,"end":226,"count":1},
{"start":253,"end":350,"count":2}]
);
TestCoverage(
"https://crbug.com/v8/9705",
`
function f(x) { // 0000
switch (x) { // 0050
case 40: nop(); // 0100
case 41: nop(); return 1; // 0150
case 42: nop(); break; // 0200
} // 0250
return 3; // 0300
}; // 0350
f(42); // 0400
f(43); // 0450
`,
[{"start":0,"end":499,"count":1},
{"start":0,"end":351,"count":2},
{"start":104,"end":119,"count":0},
{"start":154,"end":179,"count":0},
{"start":204,"end":226,"count":1}]
);
TestCoverage(
"https://crbug.com/v8/9857",
`function foo() {}`,
[{"start":0,"end":17,"count":1},
{"start":0,"end":17,"count":0}]
);
TestCoverage(
"https://crbug.com/v8/9857",
`function foo() {function bar() {}}; foo()`,
[{"start":0,"end":41,"count":1},
{"start":0,"end":34,"count":1},
{"start":16,"end":33,"count":0}]
);
%DebugToggleBlockCoverage(false);