LCOV - code coverage report
Current view: top level - test/cctest/parsing - test-preparser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 163 163 100.0 %
Date: 2019-04-17 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/api-inl.h"
       6             : #include "src/ast/ast.h"
       7             : #include "src/compiler.h"
       8             : #include "src/objects-inl.h"
       9             : #include "src/parsing/parse-info.h"
      10             : #include "src/parsing/parsing.h"
      11             : #include "src/parsing/preparse-data-impl.h"
      12             : #include "src/parsing/preparse-data.h"
      13             : 
      14             : #include "test/cctest/cctest.h"
      15             : #include "test/cctest/scope-test-helper.h"
      16             : #include "test/cctest/unicode-helpers.h"
      17             : 
      18             : namespace {
      19             : 
      20             : enum SkipTests {
      21             :   DONT_SKIP = 0,
      22             :   // Skip if the test function declares itself strict, otherwise don't skip.
      23             :   SKIP_STRICT_FUNCTION = 1,
      24             :   // Skip if there's a "use strict" directive above the test.
      25             :   SKIP_STRICT_OUTER = 1 << 1,
      26             :   SKIP_ARROW = 1 << 2,
      27             :   SKIP_STRICT = SKIP_STRICT_FUNCTION | SKIP_STRICT_OUTER
      28             : };
      29             : 
      30             : enum class PreciseMaybeAssigned { YES, NO };
      31             : 
      32             : enum class Bailout { BAILOUT_IF_OUTER_SLOPPY, NO };
      33             : 
      34             : }  // namespace
      35             : 
      36       26644 : TEST(PreParserScopeAnalysis) {
      37             :   i::Isolate* isolate = CcTest::i_isolate();
      38             :   i::Factory* factory = isolate->factory();
      39           5 :   LocalContext env;
      40             : 
      41             :   struct Outer {
      42             :     const char* code;
      43             :     bool strict_outer;
      44             :     bool strict_test_function;
      45             :     bool arrow;
      46             :   } outers[] = {
      47             :       // Normal case (test function at the laziness boundary):
      48             :       {"function test(%s) { %s function skippable() { } } test;", false, false,
      49             :        false},
      50             : 
      51             :       {"var test2 = function test(%s) { %s function skippable() { } }; test2",
      52             :        false, false, false},
      53             : 
      54             :       // Arrow functions (they can never be at the laziness boundary):
      55             :       {"function test() { (%s) => { %s }; function skippable() { } } test;",
      56             :        false, false, true},
      57             : 
      58             :       // Repeat the above mentioned cases with global 'use strict'
      59             :       {"'use strict'; function test(%s) { %s function skippable() { } } test;",
      60             :        true, false, false},
      61             : 
      62             :       {"'use strict'; var test2 = function test(%s) { %s \n"
      63             :        "function skippable() { } }; test2",
      64             :        true, false, false},
      65             : 
      66             :       {"'use strict'; function test() { (%s) => { %s };\n"
      67             :        "function skippable() { } } test;",
      68             :        true, false, true},
      69             : 
      70             :       // ... and with the test function declaring itself strict:
      71             :       {"function test(%s) { 'use strict'; %s function skippable() { } } test;",
      72             :        false, true, false},
      73             : 
      74             :       {"var test2 = function test(%s) { 'use strict'; %s \n"
      75             :        "function skippable() { } }; test2",
      76             :        false, true, false},
      77             : 
      78             :       {"function test() { 'use strict'; (%s) => { %s };\n"
      79             :        "function skippable() { } } test;",
      80             :        false, true, true},
      81             : 
      82             :       // Methods containing skippable functions.
      83             :       {"function get_method() {\n"
      84             :        "  class MyClass { test_method(%s) { %s function skippable() { } } }\n"
      85             :        "  var o = new MyClass(); return o.test_method;\n"
      86             :        "}\n"
      87             :        "get_method();",
      88             :        true, true, false},
      89             : 
      90             :       // Corner case: function expression with name "arguments".
      91             :       {"var test = function arguments(%s) { %s function skippable() { } };\n"
      92             :        "test;\n",
      93             :        false, false, false}
      94             : 
      95             :       // FIXME(marja): Generators and async functions
      96           5 :   };
      97             : 
      98       83030 :   struct Inner {
      99        1210 :     Inner(const char* s) : source(s) {}  // NOLINT
     100         135 :     Inner(const char* s, SkipTests skip) : source(s), skip(skip) {}
     101             :     Inner(const char* s, SkipTests skip, PreciseMaybeAssigned precise)
     102          10 :         : source(s), skip(skip), precise_maybe_assigned(precise) {}
     103             : 
     104          85 :     Inner(const char* p, const char* s) : params(p), source(s) {}
     105             :     Inner(const char* p, const char* s, SkipTests skip)
     106         270 :         : params(p), source(s), skip(skip) {}
     107             :     Inner(const char* p, const char* s, SkipTests skip,
     108             :           PreciseMaybeAssigned precise)
     109          55 :         : params(p), source(s), skip(skip), precise_maybe_assigned(precise) {}
     110             :     Inner(const char* p, const char* s, SkipTests skip, Bailout bailout)
     111          15 :         : params(p), source(s), skip(skip), bailout(bailout) {}
     112             : 
     113          25 :     Inner(const char* s, std::function<void()> p, std::function<void()> e)
     114          50 :         : source(s), prologue(p), epilogue(e) {}
     115             : 
     116             :     const char* params = "";
     117             :     const char* source;
     118             :     SkipTests skip = DONT_SKIP;
     119             :     PreciseMaybeAssigned precise_maybe_assigned = PreciseMaybeAssigned::YES;
     120             :     Bailout bailout = Bailout::NO;
     121             :     std::function<void()> prologue = nullptr;
     122             :     std::function<void()> epilogue = nullptr;
     123             :   } inners[] = {
     124             :       // Simple cases
     125             :       {"var1;"},
     126             :       {"var1 = 5;"},
     127             :       {"if (true) {}"},
     128             :       {"function f1() {}"},
     129             :       {"test;"},
     130             :       {"test2;"},
     131             : 
     132             :       // Var declarations and assignments.
     133             :       {"var var1;"},
     134             :       {"var var1; var1 = 5;"},
     135             :       {"if (true) { var var1; }", DONT_SKIP, PreciseMaybeAssigned::NO},
     136             :       {"if (true) { var var1; var1 = 5; }"},
     137             :       {"var var1; function f() { var1; }"},
     138             :       {"var var1; var1 = 5; function f() { var1; }"},
     139             :       {"var var1; function f() { var1 = 5; }"},
     140             :       {"function f1() { f2(); } function f2() {}"},
     141             : 
     142             :       // Let declarations and assignments.
     143             :       {"let var1;"},
     144             :       {"let var1; var1 = 5;"},
     145             :       {"if (true) { let var1; }"},
     146             :       {"if (true) { let var1; var1 = 5; }"},
     147             :       {"let var1; function f() { var1; }"},
     148             :       {"let var1; var1 = 5; function f() { var1; }"},
     149             :       {"let var1; function f() { var1 = 5; }"},
     150             : 
     151             :       // Const declarations.
     152             :       {"const var1 = 5;"},
     153             :       {"if (true) { const var1 = 5; }"},
     154             :       {"const var1 = 5; function f() { var1; }"},
     155             : 
     156             :       // Functions.
     157             :       {"function f1() { let var2; }"},
     158             :       {"var var1 = function f1() { let var2; };"},
     159             :       {"let var1 = function f1() { let var2; };"},
     160             :       {"const var1 = function f1() { let var2; };"},
     161             :       {"var var1 = function() { let var2; };"},
     162             :       {"let var1 = function() { let var2; };"},
     163             :       {"const var1 = function() { let var2; };"},
     164             : 
     165             :       {"function *f1() { let var2; }"},
     166             :       {"let var1 = function *f1() { let var2; };"},
     167             :       {"let var1 = function*() { let var2; };"},
     168             : 
     169             :       {"async function f1() { let var2; }"},
     170             :       {"let var1 = async function f1() { let var2; };"},
     171             :       {"let var1 = async function() { let var2; };"},
     172             : 
     173             :       // Redeclarations.
     174             :       {"var var1; var var1;"},
     175             :       {"var var1; var var1; var1 = 5;"},
     176             :       {"var var1; if (true) { var var1; }"},
     177             :       {"if (true) { var var1; var var1; }"},
     178             :       {"var var1; if (true) { var var1; var1 = 5; }"},
     179             :       {"if (true) { var var1; var var1; var1 = 5; }"},
     180             :       {"var var1; var var1; function f() { var1; }"},
     181             :       {"var var1; var var1; function f() { var1 = 5; }"},
     182             : 
     183             :       // Shadowing declarations.
     184             :       {"var var1; if (true) { var var1; }"},
     185             :       {"var var1; if (true) { let var1; }"},
     186             :       {"let var1; if (true) { let var1; }"},
     187             : 
     188             :       {"var var1; if (true) { const var1 = 0; }"},
     189             :       {"const var1 = 0; if (true) { const var1 = 0; }"},
     190             : 
     191             :       // Variables deeper in the subscopes (scopes without variables inbetween).
     192             :       {"if (true) { if (true) { function f() { var var1 = 5; } } }"},
     193             : 
     194             :       // Arguments and this.
     195             :       {"arguments;"},
     196             :       {"arguments = 5;", SKIP_STRICT},
     197             :       {"if (true) { arguments; }"},
     198             :       {"if (true) { arguments = 5; }", SKIP_STRICT},
     199             :       {"() => { arguments; };"},
     200             :       {"var1, var2, var3", "arguments;"},
     201             :       {"var1, var2, var3", "arguments = 5;", SKIP_STRICT},
     202             :       {"var1, var2, var3", "() => { arguments; };"},
     203             :       {"var1, var2, var3", "() => { arguments = 5; };", SKIP_STRICT},
     204             : 
     205             :       {"this;"},
     206             :       {"if (true) { this; }"},
     207             :       {"() => { this; };"},
     208             : 
     209             :       // Variable called "arguments"
     210             :       {"var arguments;", SKIP_STRICT},
     211             :       {"var arguments; arguments = 5;", SKIP_STRICT},
     212             :       {"if (true) { var arguments; }", SKIP_STRICT, PreciseMaybeAssigned::NO},
     213             :       {"if (true) { var arguments; arguments = 5; }", SKIP_STRICT},
     214             :       {"var arguments; function f() { arguments; }", SKIP_STRICT},
     215             :       {"var arguments; arguments = 5; function f() { arguments; }",
     216             :        SKIP_STRICT},
     217             :       {"var arguments; function f() { arguments = 5; }", SKIP_STRICT},
     218             : 
     219             :       {"let arguments;", SKIP_STRICT},
     220             :       {"let arguments; arguments = 5;", SKIP_STRICT},
     221             :       {"if (true) { let arguments; }", SKIP_STRICT},
     222             :       {"if (true) { let arguments; arguments = 5; }", SKIP_STRICT},
     223             :       {"let arguments; function f() { arguments; }", SKIP_STRICT},
     224             :       {"let arguments; arguments = 5; function f() { arguments; }",
     225             :        SKIP_STRICT},
     226             :       {"let arguments; function f() { arguments = 5; }", SKIP_STRICT},
     227             : 
     228             :       {"const arguments = 5;", SKIP_STRICT},
     229             :       {"if (true) { const arguments = 5; }", SKIP_STRICT},
     230             :       {"const arguments = 5; function f() { arguments; }", SKIP_STRICT},
     231             : 
     232             :       // Destructuring declarations.
     233             :       {"var [var1, var2] = [1, 2];"},
     234             :       {"var [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
     235             :       {"var [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
     236             :       {"var [var1, ...var2] = [1, 2, 3];"},
     237             : 
     238             :       {"var {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
     239             :       {"var {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
     240             :       {"var {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
     241             : 
     242             :       {"let [var1, var2] = [1, 2];"},
     243             :       {"let [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
     244             :       {"let [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
     245             :       {"let [var1, ...var2] = [1, 2, 3];"},
     246             : 
     247             :       {"let {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
     248             :       {"let {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
     249             :       {"let {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
     250             : 
     251             :       {"const [var1, var2] = [1, 2];"},
     252             :       {"const [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
     253             :       {"const [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
     254             :       {"const [var1, ...var2] = [1, 2, 3];"},
     255             : 
     256             :       {"const {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
     257             :       {"const {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
     258             :       {"const {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
     259             : 
     260             :       // Referencing the function variable.
     261             :       {"test;"},
     262             :       {"function f1() { f1; }"},
     263             :       {"function f1() { function f2() { f1; } }"},
     264             :       {"function arguments() {}", SKIP_STRICT},
     265             :       {"function f1() {} function f1() {}", SKIP_STRICT},
     266             :       {"var f1; function f1() {}"},
     267             : 
     268             :       // Assigning to the function variable.
     269             :       {"test = 3;"},
     270             :       {"function f1() { f1 = 3; }"},
     271             :       {"function f1() { f1; } f1 = 3;"},
     272             :       {"function arguments() {} arguments = 8;", SKIP_STRICT},
     273             :       {"function f1() {} f1 = 3; function f1() {}", SKIP_STRICT},
     274             : 
     275             :       // Evals.
     276             :       {"var var1; eval('');"},
     277             :       {"var var1; function f1() { eval(''); }"},
     278             :       {"let var1; eval('');"},
     279             :       {"let var1; function f1() { eval(''); }"},
     280             :       {"const var1 = 10; eval('');"},
     281             :       {"const var1 = 10; function f1() { eval(''); }"},
     282             : 
     283             :       // Standard for loops.
     284             :       {"for (var var1 = 0; var1 < 10; ++var1) { }"},
     285             :       {"for (let var1 = 0; var1 < 10; ++var1) { }"},
     286             :       {"for (const var1 = 0; var1 < 10; ++var1) { }"},
     287             : 
     288             :       {"for (var var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
     289             :       {"for (let var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
     290             :       {"for (const var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
     291             : 
     292             :       // For of loops
     293             :       {"for (var1 of [1, 2]) { }"},
     294             :       {"for (var var1 of [1, 2]) { }"},
     295             :       {"for (let var1 of [1, 2]) { }"},
     296             :       {"for (const var1 of [1, 2]) { }"},
     297             : 
     298             :       {"for (var1 of [1, 2]) { var1; }"},
     299             :       {"for (var var1 of [1, 2]) { var1; }"},
     300             :       {"for (let var1 of [1, 2]) { var1; }"},
     301             :       {"for (const var1 of [1, 2]) { var1; }"},
     302             : 
     303             :       {"for (var1 of [1, 2]) { var1 = 0; }"},
     304             :       {"for (var var1 of [1, 2]) { var1 = 0; }"},
     305             :       {"for (let var1 of [1, 2]) { var1 = 0; }"},
     306             :       {"for (const var1 of [1, 2]) { var1 = 0; }"},
     307             : 
     308             :       {"for (var1 of [1, 2]) { function foo() { var1; } }"},
     309             :       {"for (var var1 of [1, 2]) { function foo() { var1; } }"},
     310             :       {"for (let var1 of [1, 2]) { function foo() { var1; } }"},
     311             :       {"for (const var1 of [1, 2]) { function foo() { var1; } }"},
     312             : 
     313             :       {"for (var1 of [1, 2]) { function foo() { var1 = 0; } }"},
     314             :       {"for (var var1 of [1, 2]) { function foo() { var1 = 0; } }"},
     315             :       {"for (let var1 of [1, 2]) { function foo() { var1 = 0; } }"},
     316             :       {"for (const var1 of [1, 2]) { function foo() { var1 = 0; } }"},
     317             : 
     318             :       // For in loops
     319             :       {"for (var1 in {a: 6}) { }"},
     320             :       {"for (var var1 in {a: 6}) { }"},
     321             :       {"for (let var1 in {a: 6}) { }"},
     322             :       {"for (const var1 in {a: 6}) { }"},
     323             : 
     324             :       {"for (var1 in {a: 6}) { var1; }"},
     325             :       {"for (var var1 in {a: 6}) { var1; }"},
     326             :       {"for (let var1 in {a: 6}) { var1; }"},
     327             :       {"for (const var1 in {a: 6}) { var1; }"},
     328             : 
     329             :       {"for (var1 in {a: 6}) { var1 = 0; }"},
     330             :       {"for (var var1 in {a: 6}) { var1 = 0; }"},
     331             :       {"for (let var1 in {a: 6}) { var1 = 0; }"},
     332             :       {"for (const var1 in {a: 6}) { var1 = 0; }"},
     333             : 
     334             :       {"for (var1 in {a: 6}) { function foo() { var1; } }"},
     335             :       {"for (var var1 in {a: 6}) { function foo() { var1; } }"},
     336             :       {"for (let var1 in {a: 6}) { function foo() { var1; } }"},
     337             :       {"for (const var1 in {a: 6}) { function foo() { var1; } }"},
     338             : 
     339             :       {"for (var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     340             :       {"for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     341             :       {"for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     342             :       {"for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     343             : 
     344             :       {"for (var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     345             :       {"for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     346             :       {"for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     347             :       {"for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"},
     348             : 
     349             :       // Destructuring loop variable
     350             :       {"for ([var1, var2] of [[1, 1], [2, 2]]) { }"},
     351             :       {"for (var [var1, var2] of [[1, 1], [2, 2]]) { }"},
     352             :       {"for (let [var1, var2] of [[1, 1], [2, 2]]) { }"},
     353             :       {"for (const [var1, var2] of [[1, 1], [2, 2]]) { }"},
     354             : 
     355             :       {"for ([var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
     356             :       {"for (var [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
     357             :       {"for (let [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
     358             :       {"for (const [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
     359             : 
     360             :       {"for ([var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
     361             :       {"for (var [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
     362             :       {"for (let [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
     363             :       {"for (const [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
     364             : 
     365             :       // Skippable function in loop header
     366             :       {"for (let [var1, var2 = function() { }] of [[1]]) { }"},
     367             :       {"for (let [var1, var2 = function() { var1; }] of [[1]]) { }"},
     368             :       {"for (let [var1, var2 = function() { var2; }] of [[1]]) { }"},
     369             :       {"for (let [var1, var2 = function() { var1; var2; }] of [[1]]) { }"},
     370             :       {"for (let [var1, var2 = function() { var1 = 0; }] of [[1]]) { }"},
     371             :       {"for (let [var1, var2 = function() { var2 = 0; }] of [[1]]) { }"},
     372             :       {"for (let [var1, var2 = function() { var1 = 0; var2 = 0; }] of [[1]]) { "
     373             :        "}"},
     374             : 
     375             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     376             :        "var1; } }"},
     377             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     378             :        "var2; } }"},
     379             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     380             :        "var1; var2; } }"},
     381             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     382             :        "var1 = 0; } }"},
     383             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     384             :        "var2 = 0; } }"},
     385             :       {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
     386             :        "var1 = 0; var2 = 0; } }"},
     387             :       {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
     388             :        "function f() { var1; } }"},
     389             :       {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
     390             :        "function f() { var2; } }"},
     391             :       {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
     392             :        "function f() { var1; var2; } }"},
     393             :       {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
     394             :        "function f() { var1; } }"},
     395             :       {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
     396             :        "function f() { var2; } }"},
     397             :       {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
     398             :        "function f() { var1; var2; } }"},
     399             : 
     400             :       // Loops without declarations
     401             :       {"var var1 = 0; for ( ; var1 < 2; ++var1) { }"},
     402             :       {"var var1 = 0; for ( ; var1 < 2; ++var1) { function foo() { var1; } }"},
     403             :       {"var var1 = 0; for ( ; var1 > 2; ) { }"},
     404             :       {"var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1; } }"},
     405             :       {"var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1 = 6; } }"},
     406             : 
     407             :       {"var var1 = 0; for(var1; var1 < 2; ++var1) { }"},
     408             :       {"var var1 = 0; for (var1; var1 < 2; ++var1) { function foo() { var1; } "
     409             :        "}"},
     410             :       {"var var1 = 0; for (var1; var1 > 2; ) { }"},
     411             :       {"var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1; } }"},
     412             :       {"var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1 = 6; } }"},
     413             : 
     414             :       // Block functions (potentially sloppy).
     415             :       {"if (true) { function f1() {} }"},
     416             :       {"if (true) { function f1() {} function f1() {} }", SKIP_STRICT},
     417             :       {"if (true) { if (true) { function f1() {} } }"},
     418             :       {"if (true) { if (true) { function f1() {} function f1() {} } }",
     419             :        SKIP_STRICT},
     420             :       {"if (true) { function f1() {} f1 = 3; }"},
     421             : 
     422             :       {"if (true) { function f1() {} function foo() { f1; } }"},
     423             :       {"if (true) { function f1() {} } function foo() { f1; }"},
     424             :       {"if (true) { function f1() {} function f1() {} function foo() { f1; } "
     425             :        "}",
     426             :        SKIP_STRICT},
     427             :       {"if (true) { function f1() {} function f1() {} } function foo() { f1; "
     428             :        "}",
     429             :        SKIP_STRICT},
     430             :       {"if (true) { if (true) { function f1() {} } function foo() { f1; } }"},
     431             :       {"if (true) { if (true) { function f1() {} function f1() {} } function "
     432             :        "foo() { f1; } }",
     433             :        SKIP_STRICT},
     434             :       {"if (true) { function f1() {} f1 = 3; function foo() { f1; } }"},
     435             :       {"if (true) { function f1() {} f1 = 3; } function foo() { f1; }"},
     436             : 
     437             :       {"var f1 = 1; if (true) { function f1() {} }"},
     438             :       {"var f1 = 1; if (true) { function f1() {} } function foo() { f1; }"},
     439             : 
     440             :       {"if (true) { function f1() {} function f2() { f1(); } }"},
     441             : 
     442             :       {"if (true) { function *f1() {} }"},
     443             :       {"if (true) { async function f1() {} }"},
     444             : 
     445             :       // (Potentially sloppy) block function shadowing a catch variable.
     446             :       {"try { } catch(var1) { if (true) { function var1() {} } }"},
     447             : 
     448             :       // Simple parameters.
     449             :       {"var1", ""},
     450             :       {"var1", "var1;"},
     451             :       {"var1", "var1 = 9;"},
     452             :       {"var1", "function f1() { var1; }"},
     453             :       {"var1", "function f1() { var1 = 9; }"},
     454             : 
     455             :       {"var1, var2", ""},
     456             :       {"var1, var2", "var2;"},
     457             :       {"var1, var2", "var2 = 9;"},
     458             :       {"var1, var2", "function f1() { var2; }"},
     459             :       {"var1, var2", "function f1() { var2 = 9; }"},
     460             :       {"var1, var2", "var1;"},
     461             :       {"var1, var2", "var1 = 9;"},
     462             :       {"var1, var2", "function f1() { var1; }"},
     463             :       {"var1, var2", "function f1() { var1 = 9; }"},
     464             : 
     465             :       // Duplicate parameters.
     466             :       {"var1, var1", "", SkipTests(SKIP_STRICT | SKIP_ARROW)},
     467             :       {"var1, var1", "var1;", SkipTests(SKIP_STRICT | SKIP_ARROW)},
     468             :       {"var1, var1", "var1 = 9;", SkipTests(SKIP_STRICT | SKIP_ARROW)},
     469             :       {"var1, var1", "function f1() { var1; }",
     470             :        SkipTests(SKIP_STRICT | SKIP_ARROW)},
     471             :       {"var1, var1", "function f1() { var1 = 9; }",
     472             :        SkipTests(SKIP_STRICT | SKIP_ARROW)},
     473             : 
     474             :       // If the function declares itself strict, non-simple parameters aren't
     475             :       // allowed.
     476             : 
     477             :       // Rest parameter.
     478             :       {"...var2", "", SKIP_STRICT_FUNCTION},
     479             :       {"...var2", "var2;", SKIP_STRICT_FUNCTION},
     480             :       {"...var2", "var2 = 9;", SKIP_STRICT_FUNCTION},
     481             :       {"...var2", "function f1() { var2; }", SKIP_STRICT_FUNCTION},
     482             :       {"...var2", "function f1() { var2 = 9; }", SKIP_STRICT_FUNCTION},
     483             : 
     484             :       {"var1, ...var2", "", SKIP_STRICT_FUNCTION},
     485             :       {"var1, ...var2", "var2;", SKIP_STRICT_FUNCTION},
     486             :       {"var1, ...var2", "var2 = 9;", SKIP_STRICT_FUNCTION},
     487             :       {"var1, ...var2", "function f1() { var2; }", SKIP_STRICT_FUNCTION},
     488             :       {"var1, ...var2", "function f1() { var2 = 9; }", SKIP_STRICT_FUNCTION},
     489             : 
     490             :       // Default parameters.
     491             :       {"var1 = 3", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
     492             :       {"var1, var2 = var1", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
     493             :       {"var1, var2 = 4, ...var3", "", SKIP_STRICT_FUNCTION,
     494             :        PreciseMaybeAssigned::NO},
     495             : 
     496             :       // Destructuring parameters. Because of the search space explosion, we
     497             :       // cannot test all interesting cases. Let's try to test a relevant subset.
     498             :       {"[]", "", SKIP_STRICT_FUNCTION},
     499             :       {"{}", "", SKIP_STRICT_FUNCTION},
     500             : 
     501             :       {"[var1]", "", SKIP_STRICT_FUNCTION},
     502             :       {"{name1: var1}", "", SKIP_STRICT_FUNCTION},
     503             :       {"{var1}", "", SKIP_STRICT_FUNCTION},
     504             : 
     505             :       {"[var1]", "var1;", SKIP_STRICT_FUNCTION},
     506             :       {"{name1: var1}", "var1;", SKIP_STRICT_FUNCTION},
     507             :       {"{name1: var1}", "name1;", SKIP_STRICT_FUNCTION},
     508             :       {"{var1}", "var1;", SKIP_STRICT_FUNCTION},
     509             : 
     510             :       {"[var1]", "var1 = 16;", SKIP_STRICT_FUNCTION},
     511             :       {"{name1: var1}", "var1 = 16;", SKIP_STRICT_FUNCTION},
     512             :       {"{name1: var1}", "name1 = 16;", SKIP_STRICT_FUNCTION},
     513             :       {"{var1}", "var1 = 16;", SKIP_STRICT_FUNCTION},
     514             : 
     515             :       {"[var1]", "() => { var1; };", SKIP_STRICT_FUNCTION},
     516             :       {"{name1: var1}", "() => { var1; };", SKIP_STRICT_FUNCTION},
     517             :       {"{name1: var1}", "() => { name1; };", SKIP_STRICT_FUNCTION},
     518             :       {"{var1}", "() => { var1; };", SKIP_STRICT_FUNCTION},
     519             : 
     520             :       {"[var1, var2, var3]", "", SKIP_STRICT_FUNCTION},
     521             :       {"{name1: var1, name2: var2, name3: var3}", "", SKIP_STRICT_FUNCTION},
     522             :       {"{var1, var2, var3}", "", SKIP_STRICT_FUNCTION},
     523             : 
     524             :       {"[var1, var2, var3]", "() => { var2 = 16;};", SKIP_STRICT_FUNCTION},
     525             :       {"{name1: var1, name2: var2, name3: var3}", "() => { var2 = 16;};",
     526             :        SKIP_STRICT_FUNCTION},
     527             :       {"{name1: var1, name2: var2, name3: var3}", "() => { name2 = 16;};",
     528             :        SKIP_STRICT_FUNCTION},
     529             :       {"{var1, var2, var3}", "() => { var2 = 16;};", SKIP_STRICT_FUNCTION},
     530             : 
     531             :       // Nesting destructuring.
     532             :       {"[var1, [var2, var3], {var4, name5: [var5, var6]}]", "",
     533             :        SKIP_STRICT_FUNCTION},
     534             : 
     535             :       // Complicated params.
     536             :       {"var1, [var2], var3 = 24, [var4, var5] = [2, 4], var6, {var7}, var8, "
     537             :        "{name9: var9, name10: var10}, ...var11",
     538             :        "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
     539             : 
     540             :       // Complicated cases from bugs.
     541             :       {"var1 = {} = {}", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
     542             : 
     543             :       // Destructuring rest. Because we can.
     544             :       {"var1, ...[var2]", "", SKIP_STRICT_FUNCTION},
     545             :       {"var1, ...[var2]", "() => { var2; };", SKIP_STRICT_FUNCTION},
     546             :       {"var1, ...{0: var2}", "", SKIP_STRICT_FUNCTION},
     547             :       {"var1, ...{0: var2}", "() => { var2; };", SKIP_STRICT_FUNCTION},
     548             :       {"var1, ...[]", "", SKIP_STRICT_FUNCTION},
     549             :       {"var1, ...{}", "", SKIP_STRICT_FUNCTION},
     550             :       {"var1, ...[var2, var3]", "", SKIP_STRICT_FUNCTION},
     551             :       {"var1, ...{0: var2, 1: var3}", "", SKIP_STRICT_FUNCTION},
     552             : 
     553             :       // Default parameters for destruring parameters.
     554             :       {"[var1, var2] = [2, 4]", "", SKIP_STRICT_FUNCTION,
     555             :        PreciseMaybeAssigned::NO},
     556             :       {"{var1, var2} = {var1: 3, var2: 3}", "", SKIP_STRICT_FUNCTION,
     557             :        PreciseMaybeAssigned::NO},
     558             : 
     559             :       // Default parameters inside destruring parameters.
     560             :       {"[var1 = 4, var2 = var1]", "", SKIP_STRICT_FUNCTION,
     561             :        PreciseMaybeAssigned::NO},
     562             :       {"{var1 = 4, var2 = var1}", "", SKIP_STRICT_FUNCTION,
     563             :        PreciseMaybeAssigned::NO},
     564             : 
     565             :       // Locals shadowing parameters.
     566             :       {"var1, var2", "var var1 = 16; () => { var1 = 17; };"},
     567             : 
     568             :       // Locals shadowing destructuring parameters and the rest parameter.
     569             :       {"[var1, var2]", "var var1 = 16; () => { var1 = 17; };",
     570             :        SKIP_STRICT_FUNCTION},
     571             :       {"{var1, var2}", "var var1 = 16; () => { var1 = 17; };",
     572             :        SKIP_STRICT_FUNCTION},
     573             :       {"var1, var2, ...var3", "var var3 = 16; () => { var3 = 17; };",
     574             :        SKIP_STRICT_FUNCTION},
     575             :       {"var1, var2 = var1", "var var1 = 16; () => { var1 = 17; };",
     576             :        SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
     577             : 
     578             :       // Hoisted sloppy block function shadowing a parameter.
     579             :       // FIXME(marja): why is maybe_assigned inaccurate?
     580             :       {"var1, var2", "for (;;) { function var1() { } }", DONT_SKIP,
     581             :        PreciseMaybeAssigned::NO},
     582             : 
     583             :       // Sloppy eval in default parameter.
     584             :       {"var1, var2 = eval(''), var3", "let var4 = 0;", SKIP_STRICT_FUNCTION,
     585             :        Bailout::BAILOUT_IF_OUTER_SLOPPY},
     586             :       {"var1, var2 = eval(''), var3 = eval('')", "let var4 = 0;",
     587             :        SKIP_STRICT_FUNCTION, Bailout::BAILOUT_IF_OUTER_SLOPPY},
     588             : 
     589             :       // Sloppy eval in arrow function parameter list which is inside another
     590             :       // arrow function parameter list.
     591             :       {"var1, var2 = (var3, var4 = eval(''), var5) => { let var6; }, var7",
     592             :        "let var8 = 0;", SKIP_STRICT_FUNCTION, Bailout::BAILOUT_IF_OUTER_SLOPPY},
     593             : 
     594             :       // Sloppy eval in a function body with non-simple parameters.
     595             :       {"var1 = 1, var2 = 2", "eval('');", SKIP_STRICT_FUNCTION},
     596             : 
     597             :       // Catch variable
     598             :       {"try { } catch(var1) { }"},
     599             :       {"try { } catch(var1) { var1; }"},
     600             :       {"try { } catch(var1) { var1 = 3; }"},
     601             :       {"try { } catch(var1) { function f() { var1; } }"},
     602             :       {"try { } catch(var1) { function f() { var1 = 3; } }"},
     603             : 
     604             :       {"try { } catch({var1, var2}) { function f() { var1 = 3; } }"},
     605             :       {"try { } catch([var1, var2]) { function f() { var1 = 3; } }"},
     606             :       {"try { } catch({}) { }"},
     607             :       {"try { } catch([]) { }"},
     608             : 
     609             :       // Shadowing the catch variable
     610             :       {"try { } catch(var1) { var var1 = 3; }"},
     611             :       {"try { } catch(var1) { var var1 = 3; function f() { var1 = 3; } }"},
     612             : 
     613             :       // Classes
     614             :       {"class MyClass {}"},
     615             :       {"var1 = class MyClass {};"},
     616             :       {"var var1 = class MyClass {};"},
     617             :       {"let var1 = class MyClass {};"},
     618             :       {"const var1 = class MyClass {};"},
     619             :       {"var var1 = class {};"},
     620             :       {"let var1 = class {};"},
     621             :       {"const var1 = class {};"},
     622             : 
     623             :       {"class MyClass { constructor() {} }"},
     624             :       {"class MyClass { constructor() { var var1; } }"},
     625             :       {"class MyClass { constructor() { var var1 = 11; } }"},
     626             :       {"class MyClass { constructor() { var var1; function foo() { var1 = 11; "
     627             :        "} } }"},
     628             : 
     629             :       {"class MyClass { m() {} }"},
     630             :       {"class MyClass { m() { var var1; } }"},
     631             :       {"class MyClass { m() { var var1 = 11; } }"},
     632             :       {"class MyClass { m() { var var1; function foo() { var1 = 11; } } }"},
     633             : 
     634             :       {"class MyClass { static m() {} }"},
     635             :       {"class MyClass { static m() { var var1; } }"},
     636             :       {"class MyClass { static m() { var var1 = 11; } }"},
     637             :       {"class MyClass { static m() { var var1; function foo() { var1 = 11; } } "
     638             :        "}"},
     639             : 
     640             :       {"class MyBase {} class MyClass extends MyBase {}"},
     641             :       {"class MyClass extends MyBase { constructor() {} }"},
     642             :       {"class MyClass extends MyBase { constructor() { super(); } }"},
     643             :       {"class MyClass extends MyBase { constructor() { var var1; } }"},
     644             :       {"class MyClass extends MyBase { constructor() { var var1 = 11; } }"},
     645             :       {"class MyClass extends MyBase { constructor() { var var1; function "
     646             :        "foo() { var1 = 11; } } }"},
     647             : 
     648             :       {"class MyClass extends MyBase { m() {} }"},
     649             :       {"class MyClass extends MyBase { m() { super.foo; } }"},
     650             :       {"class MyClass extends MyBase { m() { var var1; } }"},
     651             :       {"class MyClass extends MyBase { m() { var var1 = 11; } }"},
     652             :       {"class MyClass extends MyBase { m() { var var1; function foo() { var1 = "
     653             :        "11; } } }"},
     654             : 
     655             :       {"class MyClass extends MyBase { static m() {} }"},
     656             :       {"class MyClass extends MyBase { static m() { super.foo; } }"},
     657             :       {"class MyClass extends MyBase { static m() { var var1; } }"},
     658             :       {"class MyClass extends MyBase { static m() { var var1 = 11; } }"},
     659             :       {"class MyClass extends MyBase { static m() { var var1; function foo() { "
     660             :        "var1 = 11; } } }"},
     661             : 
     662             :       {"class X { ['bar'] = 1; }; new X;",
     663          55 :        [] { i::FLAG_harmony_public_fields = true; },
     664          55 :        [] { i::FLAG_harmony_public_fields = false; }},
     665             :       {"class X { static ['foo'] = 2; }; new X;",
     666             :        [] {
     667          55 :          i::FLAG_harmony_public_fields = true;
     668          55 :          i::FLAG_harmony_static_fields = true;
     669             :        },
     670             :        [] {
     671          55 :          i::FLAG_harmony_public_fields = false;
     672          55 :          i::FLAG_harmony_static_fields = false;
     673             :        }},
     674             :       {"class X { ['bar'] = 1; static ['foo'] = 2; }; new X;",
     675             :        [] {
     676          55 :          i::FLAG_harmony_public_fields = true;
     677          55 :          i::FLAG_harmony_static_fields = true;
     678             :        },
     679             :        [] {
     680          55 :          i::FLAG_harmony_public_fields = false;
     681          55 :          i::FLAG_harmony_static_fields = false;
     682             :        }},
     683             :       {"class X { #x = 1 }; new X;",
     684          55 :        [] { i::FLAG_harmony_private_fields = true; },
     685          55 :        [] { i::FLAG_harmony_private_fields = false; }},
     686             :       {"function t() { return class { #x = 1 }; } new t();",
     687          55 :        [] { i::FLAG_harmony_private_fields = true; },
     688          55 :        [] { i::FLAG_harmony_private_fields = false; }},
     689        1885 :   };
     690             : 
     691         115 :   for (unsigned i = 0; i < arraysize(outers); ++i) {
     692          55 :     struct Outer outer = outers[i];
     693       39765 :     for (unsigned j = 0; j < arraysize(inners); ++j) {
     694       37200 :       struct Inner inner = inners[j];
     695       22365 :       if (outer.strict_outer && (inner.skip & SKIP_STRICT_OUTER)) continue;
     696       19155 :       if (outer.strict_test_function && (inner.skip & SKIP_STRICT_FUNCTION)) {
     697             :         continue;
     698             :       }
     699       17430 :       if (outer.arrow && (inner.skip & SKIP_ARROW)) continue;
     700             : 
     701             :       const char* code = outer.code;
     702       17405 :       int code_len = Utf8LengthHelper(code);
     703             : 
     704       17405 :       int params_len = Utf8LengthHelper(inner.params);
     705       17405 :       int source_len = Utf8LengthHelper(inner.source);
     706       17405 :       int len = code_len + params_len + source_len;
     707             : 
     708       17405 :       if (inner.prologue != nullptr) inner.prologue();
     709             : 
     710       17405 :       i::ScopedVector<char> program(len + 1);
     711       17405 :       i::SNPrintF(program, code, inner.params, inner.source);
     712             : 
     713             :       i::HandleScope scope(isolate);
     714             : 
     715             :       i::Handle<i::String> source =
     716       17405 :           factory->InternalizeUtf8String(program.start());
     717       34810 :       source->PrintOn(stdout);
     718             :       printf("\n");
     719             : 
     720             :       // Compile and run the script to get a pointer to the lazy function.
     721             :       v8::Local<v8::Value> v = CompileRun(program.start());
     722             :       i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
     723             :       i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
     724             :       i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
     725             : 
     726       17405 :       if (inner.bailout == Bailout::BAILOUT_IF_OUTER_SLOPPY &&
     727             :           !outer.strict_outer) {
     728          60 :         CHECK(!shared->HasUncompiledDataWithPreparseData());
     729             :         continue;
     730             :       }
     731             : 
     732       17345 :       CHECK(shared->HasUncompiledDataWithPreparseData());
     733             :       i::Handle<i::PreparseData> produced_data_on_heap(
     734             :           shared->uncompiled_data_with_preparse_data()->preparse_data(),
     735             :           isolate);
     736             : 
     737             :       // Parse the lazy function using the scope data.
     738       34690 :       i::ParseInfo using_scope_data(isolate, shared);
     739             :       using_scope_data.set_lazy_compile();
     740             :       using_scope_data.set_consumed_preparse_data(
     741       34690 :           i::ConsumedPreparseData::For(isolate, produced_data_on_heap));
     742       17345 :       CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate));
     743             : 
     744             :       // Verify that we skipped at least one function inside that scope.
     745             :       i::DeclarationScope* scope_with_skipped_functions =
     746             :           using_scope_data.literal()->scope();
     747       17345 :       CHECK(i::ScopeTestHelper::HasSkippedFunctionInside(
     748             :           scope_with_skipped_functions));
     749             : 
     750             :       // Do scope allocation (based on the preparsed scope data).
     751       17345 :       CHECK(i::DeclarationScope::Analyze(&using_scope_data));
     752             : 
     753             :       // Parse the lazy function again eagerly to produce baseline data.
     754       34690 :       i::ParseInfo not_using_scope_data(isolate, shared);
     755             :       not_using_scope_data.set_lazy_compile();
     756       17345 :       CHECK(i::parsing::ParseFunction(&not_using_scope_data, shared, isolate));
     757             : 
     758             :       // Verify that we didn't skip anything (there's no preparsed scope data,
     759             :       // so we cannot skip).
     760             :       i::DeclarationScope* scope_without_skipped_functions =
     761             :           not_using_scope_data.literal()->scope();
     762       17345 :       CHECK(!i::ScopeTestHelper::HasSkippedFunctionInside(
     763             :           scope_without_skipped_functions));
     764             : 
     765             :       // Do normal scope allocation.
     766       17345 :       CHECK(i::DeclarationScope::Analyze(&not_using_scope_data));
     767             : 
     768             :       // Verify that scope allocation gave the same results when parsing w/ the
     769             :       // scope data (and skipping functions), and when parsing without.
     770       17345 :       i::ScopeTestHelper::CompareScopes(
     771             :           scope_without_skipped_functions, scope_with_skipped_functions,
     772       34690 :           inner.precise_maybe_assigned == PreciseMaybeAssigned::YES);
     773             : 
     774       17345 :       if (inner.epilogue != nullptr) inner.epilogue();
     775             :     }
     776             :   }
     777           5 : }
     778             : 
     779             : // Regression test for
     780             : // https://bugs.chromium.org/p/chromium/issues/detail?id=753896. Should not
     781             : // crash.
     782       26644 : TEST(Regress753896) {
     783             :   i::Isolate* isolate = CcTest::i_isolate();
     784             :   i::Factory* factory = isolate->factory();
     785             :   i::HandleScope scope(isolate);
     786           5 :   LocalContext env;
     787             : 
     788             :   i::Handle<i::String> source = factory->InternalizeUtf8String(
     789           5 :       "function lazy() { let v = 0; if (true) { var v = 0; } }");
     790           5 :   i::Handle<i::Script> script = factory->NewScript(source);
     791          10 :   i::ParseInfo info(isolate, script);
     792             : 
     793             :   // We don't assert that parsing succeeded or that it failed; currently the
     794             :   // error is not detected inside lazy functions, but it might be in the future.
     795           5 :   i::parsing::ParseProgram(&info, isolate);
     796           5 : }
     797             : 
     798       26644 : TEST(ProducingAndConsumingByteData) {
     799             :   i::Isolate* isolate = CcTest::i_isolate();
     800             :   i::HandleScope scope(isolate);
     801           5 :   LocalContext env;
     802             : 
     803          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
     804             :   std::vector<uint8_t> buffer;
     805             :   i::PreparseDataBuilder::ByteData bytes;
     806           5 :   bytes.Start(&buffer);
     807             : 
     808           5 :   bytes.Reserve(32);
     809           5 :   bytes.Reserve(32);
     810           5 :   CHECK_EQ(buffer.size(), 32);
     811             :   const int kBufferSize = 64;
     812           5 :   bytes.Reserve(kBufferSize);
     813           5 :   CHECK_EQ(buffer.size(), kBufferSize);
     814             : 
     815             :   // Write some data.
     816             : #ifdef DEBUG
     817             :   bytes.WriteUint32(1983);  // This will be overwritten.
     818             : #else
     819           5 :   bytes.WriteVarint32(1983);
     820             : #endif
     821           5 :   bytes.WriteVarint32(2147483647);
     822           5 :   bytes.WriteUint8(4);
     823           5 :   bytes.WriteUint8(255);
     824           5 :   bytes.WriteVarint32(0);
     825           5 :   bytes.WriteUint8(0);
     826             : #ifdef DEBUG
     827             :   bytes.SaveCurrentSizeAtFirstUint32();
     828             :   int saved_size = 21;
     829             :   CHECK_EQ(buffer.size(), kBufferSize);
     830             :   CHECK_EQ(bytes.length(), saved_size);
     831             : #endif
     832           5 :   bytes.WriteUint8(100);
     833             :   // Write quarter bytes between uint8s and uint32s to verify they're stored
     834             :   // correctly.
     835           5 :   bytes.WriteQuarter(3);
     836           5 :   bytes.WriteQuarter(0);
     837           5 :   bytes.WriteQuarter(2);
     838           5 :   bytes.WriteQuarter(1);
     839           5 :   bytes.WriteQuarter(0);
     840           5 :   bytes.WriteUint8(50);
     841             : 
     842           5 :   bytes.WriteQuarter(0);
     843           5 :   bytes.WriteQuarter(1);
     844           5 :   bytes.WriteQuarter(2);
     845           5 :   bytes.WriteQuarter(3);
     846           5 :   bytes.WriteVarint32(50);
     847             : 
     848             :   // End with a lonely quarter.
     849           5 :   bytes.WriteQuarter(0);
     850           5 :   bytes.WriteQuarter(1);
     851           5 :   bytes.WriteQuarter(2);
     852           5 :   bytes.WriteVarint32(0xff);
     853             : 
     854             :   // End with a lonely quarter.
     855           5 :   bytes.WriteQuarter(2);
     856             : 
     857           5 :   CHECK_EQ(buffer.size(), 64);
     858             : #ifdef DEBUG
     859             :   const int kDataSize = 42;
     860             : #else
     861             :   const int kDataSize = 21;
     862             : #endif
     863           5 :   CHECK_EQ(bytes.length(), kDataSize);
     864           5 :   CHECK_EQ(buffer.size(), kBufferSize);
     865             : 
     866             :   // Copy buffer for sanity checks later-on.
     867           5 :   std::vector<uint8_t> copied_buffer(buffer);
     868             : 
     869             :   // Move the data from the temporary buffer into the zone for later
     870             :   // serialization.
     871           5 :   bytes.Finalize(&zone);
     872           5 :   CHECK_EQ(buffer.size(), 0);
     873           5 :   CHECK_EQ(copied_buffer.size(), kBufferSize);
     874             : 
     875             :   {
     876             :     // Serialize as a ZoneConsumedPreparseData, and read back data.
     877             :     i::ZonePreparseData* data_in_zone = bytes.CopyToZone(&zone, 0);
     878             :     i::ZoneConsumedPreparseData::ByteData bytes_for_reading;
     879             :     i::ZoneVectorWrapper wrapper(data_in_zone->byte_data());
     880             :     i::ZoneConsumedPreparseData::ByteData::ReadingScope reading_scope(
     881             :         &bytes_for_reading, wrapper);
     882             : 
     883           5 :     CHECK_EQ(wrapper.data_length(), kDataSize);
     884             : 
     885         215 :     for (int i = 0; i < kDataSize; i++) {
     886         210 :       CHECK_EQ(copied_buffer.at(i), wrapper.get(i));
     887             :     }
     888             : 
     889             : #ifdef DEBUG
     890             :     CHECK_EQ(bytes_for_reading.ReadUint32(), saved_size);
     891             : #else
     892           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 1983);
     893             : #endif
     894           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 2147483647);
     895           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 4);
     896           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 255);
     897           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 0);
     898           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 0);
     899           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 100);
     900             : 
     901          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
     902          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     903          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     904          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     905          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     906           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 50);
     907             : 
     908          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     909          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     910          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     911          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
     912           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 50);
     913             : 
     914          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     915          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     916          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     917           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 0xff);
     918             : 
     919          10 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     920             :     // We should have consumed all data at this point.
     921           5 :     CHECK(!bytes_for_reading.HasRemainingBytes(1));
     922             :   }
     923             : 
     924             :   {
     925             :     // Serialize as an OnHeapConsumedPreparseData, and read back data.
     926           5 :     i::Handle<i::PreparseData> data_on_heap = bytes.CopyToHeap(isolate, 0);
     927           5 :     CHECK_EQ(data_on_heap->data_length(), kDataSize);
     928           5 :     CHECK_EQ(data_on_heap->children_length(), 0);
     929             :     i::OnHeapConsumedPreparseData::ByteData bytes_for_reading;
     930             :     i::OnHeapConsumedPreparseData::ByteData::ReadingScope reading_scope(
     931             :         &bytes_for_reading, *data_on_heap);
     932             : 
     933         215 :     for (int i = 0; i < kDataSize; i++) {
     934         210 :       CHECK_EQ(copied_buffer[i], data_on_heap->get(i));
     935             :     }
     936             : 
     937             : #ifdef DEBUG
     938             :     CHECK_EQ(bytes_for_reading.ReadUint32(), saved_size);
     939             : #else
     940           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 1983);
     941             : #endif
     942           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 2147483647);
     943           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 4);
     944           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 255);
     945           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 0);
     946           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 0);
     947           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 100);
     948             : 
     949           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
     950           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     951           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     952           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     953           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     954           5 :     CHECK_EQ(bytes_for_reading.ReadUint8(), 50);
     955             : 
     956           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     957           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     958           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     959           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
     960           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 50);
     961             : 
     962           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
     963           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
     964           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     965           5 :     CHECK_EQ(bytes_for_reading.ReadVarint32(), 0xff);
     966             : 
     967           5 :     CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
     968             :     // We should have consumed all data at this point.
     969           5 :     CHECK(!bytes_for_reading.HasRemainingBytes(1));
     970             :   }
     971       79922 : }

Generated by: LCOV version 1.10