Home | History | Annotate | Download | only in cctest
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 #include <string.h>
     31 
     32 #include "src/v8.h"
     33 
     34 #include "src/ast/ast.h"
     35 #include "src/ast/ast-numbering.h"
     36 #include "src/ast/ast-value-factory.h"
     37 #include "src/compiler.h"
     38 #include "src/execution.h"
     39 #include "src/isolate.h"
     40 #include "src/objects.h"
     41 #include "src/parsing/parser.h"
     42 #include "src/parsing/preparser.h"
     43 #include "src/parsing/rewriter.h"
     44 #include "src/parsing/scanner-character-streams.h"
     45 #include "src/parsing/token.h"
     46 #include "src/utils.h"
     47 
     48 #include "test/cctest/cctest.h"
     49 
     50 TEST(ScanKeywords) {
     51   struct KeywordToken {
     52     const char* keyword;
     53     i::Token::Value token;
     54   };
     55 
     56   static const KeywordToken keywords[] = {
     57 #define KEYWORD(t, s, d) { s, i::Token::t },
     58       TOKEN_LIST(IGNORE_TOKEN, KEYWORD)
     59 #undef KEYWORD
     60       { NULL, i::Token::IDENTIFIER }
     61   };
     62 
     63   KeywordToken key_token;
     64   i::UnicodeCache unicode_cache;
     65   i::byte buffer[32];
     66   for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
     67     const i::byte* keyword =
     68         reinterpret_cast<const i::byte*>(key_token.keyword);
     69     int length = i::StrLength(key_token.keyword);
     70     CHECK(static_cast<int>(sizeof(buffer)) >= length);
     71     {
     72       i::Utf8ToUtf16CharacterStream stream(keyword, length);
     73       i::Scanner scanner(&unicode_cache);
     74       scanner.Initialize(&stream);
     75       CHECK_EQ(key_token.token, scanner.Next());
     76       CHECK_EQ(i::Token::EOS, scanner.Next());
     77     }
     78     // Removing characters will make keyword matching fail.
     79     {
     80       i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
     81       i::Scanner scanner(&unicode_cache);
     82       scanner.Initialize(&stream);
     83       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     84       CHECK_EQ(i::Token::EOS, scanner.Next());
     85     }
     86     // Adding characters will make keyword matching fail.
     87     static const char chars_to_append[] = { 'z', '0', '_' };
     88     for (int j = 0; j < static_cast<int>(arraysize(chars_to_append)); ++j) {
     89       i::MemMove(buffer, keyword, length);
     90       buffer[length] = chars_to_append[j];
     91       i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
     92       i::Scanner scanner(&unicode_cache);
     93       scanner.Initialize(&stream);
     94       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     95       CHECK_EQ(i::Token::EOS, scanner.Next());
     96     }
     97     // Replacing characters will make keyword matching fail.
     98     {
     99       i::MemMove(buffer, keyword, length);
    100       buffer[length - 1] = '_';
    101       i::Utf8ToUtf16CharacterStream stream(buffer, length);
    102       i::Scanner scanner(&unicode_cache);
    103       scanner.Initialize(&stream);
    104       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
    105       CHECK_EQ(i::Token::EOS, scanner.Next());
    106     }
    107   }
    108 }
    109 
    110 
    111 TEST(ScanHTMLEndComments) {
    112   v8::V8::Initialize();
    113   v8::Isolate* isolate = CcTest::isolate();
    114   v8::HandleScope handles(isolate);
    115 
    116   // Regression test. See:
    117   //    http://code.google.com/p/chromium/issues/detail?id=53548
    118   // Tests that --> is correctly interpreted as comment-to-end-of-line if there
    119   // is only whitespace before it on the line (with comments considered as
    120   // whitespace, even a multiline-comment containing a newline).
    121   // This was not the case if it occurred before the first real token
    122   // in the input.
    123   const char* tests[] = {
    124       // Before first real token.
    125       "--> is eol-comment\nvar y = 37;\n",
    126       "\n --> is eol-comment\nvar y = 37;\n",
    127       "/* precomment */ --> is eol-comment\nvar y = 37;\n",
    128       "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    129       // After first real token.
    130       "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
    131       "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    132       NULL
    133   };
    134 
    135   const char* fail_tests[] = {
    136       "x --> is eol-comment\nvar y = 37;\n",
    137       "\"\\n\" --> is eol-comment\nvar y = 37;\n",
    138       "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
    139       "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    140       "var x = 42; --> is eol-comment\nvar y = 37;\n",
    141       "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    142       NULL
    143   };
    144 
    145   // Parser/Scanner needs a stack limit.
    146   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    147       i::GetCurrentStackPosition() - 128 * 1024);
    148   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    149   for (int i = 0; tests[i]; i++) {
    150     const i::byte* source =
    151         reinterpret_cast<const i::byte*>(tests[i]);
    152     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i]));
    153     i::CompleteParserRecorder log;
    154     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    155     scanner.Initialize(&stream);
    156     i::Zone zone(CcTest::i_isolate()->allocator());
    157     i::AstValueFactory ast_value_factory(
    158         &zone, CcTest::i_isolate()->heap()->HashSeed());
    159     i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    160                            stack_limit);
    161     preparser.set_allow_lazy(true);
    162     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    163     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    164     CHECK(!log.HasError());
    165   }
    166 
    167   for (int i = 0; fail_tests[i]; i++) {
    168     const i::byte* source =
    169         reinterpret_cast<const i::byte*>(fail_tests[i]);
    170     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i]));
    171     i::CompleteParserRecorder log;
    172     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    173     scanner.Initialize(&stream);
    174     i::Zone zone(CcTest::i_isolate()->allocator());
    175     i::AstValueFactory ast_value_factory(
    176         &zone, CcTest::i_isolate()->heap()->HashSeed());
    177     i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    178                            stack_limit);
    179     preparser.set_allow_lazy(true);
    180     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    181     // Even in the case of a syntax error, kPreParseSuccess is returned.
    182     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    183     CHECK(log.HasError());
    184   }
    185 }
    186 
    187 
    188 class ScriptResource : public v8::String::ExternalOneByteStringResource {
    189  public:
    190   ScriptResource(const char* data, size_t length)
    191       : data_(data), length_(length) { }
    192 
    193   const char* data() const { return data_; }
    194   size_t length() const { return length_; }
    195 
    196  private:
    197   const char* data_;
    198   size_t length_;
    199 };
    200 
    201 
    202 TEST(UsingCachedData) {
    203   // Producing cached parser data while parsing eagerly is not supported.
    204   if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) return;
    205 
    206   v8::Isolate* isolate = CcTest::isolate();
    207   v8::HandleScope handles(isolate);
    208   v8::Local<v8::Context> context = v8::Context::New(isolate);
    209   v8::Context::Scope context_scope(context);
    210   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    211       i::GetCurrentStackPosition() - 128 * 1024);
    212 
    213   // Source containing functions that might be lazily compiled  and all types
    214   // of symbols (string, propertyName, regexp).
    215   const char* source =
    216       "var x = 42;"
    217       "function foo(a) { return function nolazy(b) { return a + b; } }"
    218       "function bar(a) { if (a) return function lazy(b) { return b; } }"
    219       "var z = {'string': 'string literal', bareword: 'propertyName', "
    220       "         42: 'number literal', for: 'keyword as propertyName', "
    221       "         f\\u006fr: 'keyword propertyname with escape'};"
    222       "var v = /RegExp Literal/;"
    223       "var w = /RegExp Literal\\u0020With Escape/gi;"
    224       "var y = { get getter() { return 42; }, "
    225       "          set setter(v) { this.value = v; }};"
    226       "var f = a => function (b) { return a + b; };"
    227       "var g = a => b => a + b;";
    228   int source_length = i::StrLength(source);
    229 
    230   // ScriptResource will be deleted when the corresponding String is GCd.
    231   v8::ScriptCompiler::Source script_source(
    232       v8::String::NewExternalOneByte(isolate,
    233                                      new ScriptResource(source, source_length))
    234           .ToLocalChecked());
    235   i::FLAG_min_preparse_length = 0;
    236   v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &script_source,
    237                               v8::ScriptCompiler::kProduceParserCache)
    238       .ToLocalChecked();
    239   CHECK(script_source.GetCachedData());
    240 
    241   // Compile the script again, using the cached data.
    242   bool lazy_flag = i::FLAG_lazy;
    243   i::FLAG_lazy = true;
    244   v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &script_source,
    245                               v8::ScriptCompiler::kConsumeParserCache)
    246       .ToLocalChecked();
    247   i::FLAG_lazy = false;
    248   v8::ScriptCompiler::CompileUnboundScript(
    249       isolate, &script_source, v8::ScriptCompiler::kConsumeParserCache)
    250       .ToLocalChecked();
    251   i::FLAG_lazy = lazy_flag;
    252 }
    253 
    254 
    255 TEST(PreparseFunctionDataIsUsed) {
    256   // Producing cached parser data while parsing eagerly is not supported.
    257   if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) return;
    258 
    259   // This tests that we actually do use the function data generated by the
    260   // preparser.
    261 
    262   // Make preparsing work for short scripts.
    263   i::FLAG_min_preparse_length = 0;
    264 
    265   v8::Isolate* isolate = CcTest::isolate();
    266   v8::HandleScope handles(isolate);
    267   v8::Local<v8::Context> context = v8::Context::New(isolate);
    268   v8::Context::Scope context_scope(context);
    269   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    270       i::GetCurrentStackPosition() - 128 * 1024);
    271 
    272   const char* good_code[] = {
    273       "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
    274       "var this_is_lazy = () => { var a; }; var foo = () => 25; foo();",
    275   };
    276 
    277   // Insert a syntax error inside the lazy function.
    278   const char* bad_code[] = {
    279       "function this_is_lazy() { if (   } function foo() { return 25; } foo();",
    280       "var this_is_lazy = () => { if (   }; var foo = () => 25; foo();",
    281   };
    282 
    283   for (unsigned i = 0; i < arraysize(good_code); i++) {
    284     v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
    285     v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &good_source,
    286                                 v8::ScriptCompiler::kProduceParserCache)
    287         .ToLocalChecked();
    288 
    289     const v8::ScriptCompiler::CachedData* cached_data =
    290         good_source.GetCachedData();
    291     CHECK(cached_data->data != NULL);
    292     CHECK_GT(cached_data->length, 0);
    293 
    294     // Now compile the erroneous code with the good preparse data. If the
    295     // preparse data is used, the lazy function is skipped and it should
    296     // compile fine.
    297     v8::ScriptCompiler::Source bad_source(
    298         v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
    299                                  cached_data->data, cached_data->length));
    300     v8::Local<v8::Value> result =
    301         CompileRun(isolate->GetCurrentContext(), &bad_source,
    302                    v8::ScriptCompiler::kConsumeParserCache);
    303     CHECK(result->IsInt32());
    304     CHECK_EQ(25, result->Int32Value(isolate->GetCurrentContext()).FromJust());
    305   }
    306 }
    307 
    308 
    309 TEST(StandAlonePreParser) {
    310   v8::V8::Initialize();
    311 
    312   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    313       i::GetCurrentStackPosition() - 128 * 1024);
    314 
    315   const char* programs[] = {
    316       "{label: 42}",
    317       "var x = 42;",
    318       "function foo(x, y) { return x + y; }",
    319       "%ArgleBargle(glop);",
    320       "var x = new new Function('this.x = 42');",
    321       "var f = (x, y) => x + y;",
    322       NULL
    323   };
    324 
    325   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    326   for (int i = 0; programs[i]; i++) {
    327     const char* program = programs[i];
    328     i::Utf8ToUtf16CharacterStream stream(
    329         reinterpret_cast<const i::byte*>(program),
    330         static_cast<unsigned>(strlen(program)));
    331     i::CompleteParserRecorder log;
    332     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    333     scanner.Initialize(&stream);
    334 
    335     i::Zone zone(CcTest::i_isolate()->allocator());
    336     i::AstValueFactory ast_value_factory(
    337         &zone, CcTest::i_isolate()->heap()->HashSeed());
    338     i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    339                            stack_limit);
    340     preparser.set_allow_lazy(true);
    341     preparser.set_allow_natives(true);
    342     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    343     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    344     CHECK(!log.HasError());
    345   }
    346 }
    347 
    348 
    349 TEST(StandAlonePreParserNoNatives) {
    350   v8::V8::Initialize();
    351 
    352   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    353       i::GetCurrentStackPosition() - 128 * 1024);
    354 
    355   const char* programs[] = {
    356       "%ArgleBargle(glop);",
    357       "var x = %_IsSmi(42);",
    358       NULL
    359   };
    360 
    361   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    362   for (int i = 0; programs[i]; i++) {
    363     const char* program = programs[i];
    364     i::Utf8ToUtf16CharacterStream stream(
    365         reinterpret_cast<const i::byte*>(program),
    366         static_cast<unsigned>(strlen(program)));
    367     i::CompleteParserRecorder log;
    368     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    369     scanner.Initialize(&stream);
    370 
    371     // Preparser defaults to disallowing natives syntax.
    372     i::Zone zone(CcTest::i_isolate()->allocator());
    373     i::AstValueFactory ast_value_factory(
    374         &zone, CcTest::i_isolate()->heap()->HashSeed());
    375     i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    376                            stack_limit);
    377     preparser.set_allow_lazy(true);
    378     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    379     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    380     CHECK(log.HasError());
    381   }
    382 }
    383 
    384 
    385 TEST(PreparsingObjectLiterals) {
    386   // Regression test for a bug where the symbol stream produced by PreParser
    387   // didn't match what Parser wanted to consume.
    388   v8::Isolate* isolate = CcTest::isolate();
    389   v8::HandleScope handles(isolate);
    390   v8::Local<v8::Context> context = v8::Context::New(isolate);
    391   v8::Context::Scope context_scope(context);
    392   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    393       i::GetCurrentStackPosition() - 128 * 1024);
    394 
    395   {
    396     const char* source = "var myo = {if: \"foo\"}; myo.if;";
    397     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    398     CHECK(result->IsString());
    399     v8::String::Utf8Value utf8(result);
    400     CHECK_EQ(0, strcmp("foo", *utf8));
    401   }
    402 
    403   {
    404     const char* source = "var myo = {\"bar\": \"foo\"}; myo[\"bar\"];";
    405     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    406     CHECK(result->IsString());
    407     v8::String::Utf8Value utf8(result);
    408     CHECK_EQ(0, strcmp("foo", *utf8));
    409   }
    410 
    411   {
    412     const char* source = "var myo = {1: \"foo\"}; myo[1];";
    413     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    414     CHECK(result->IsString());
    415     v8::String::Utf8Value utf8(result);
    416     CHECK_EQ(0, strcmp("foo", *utf8));
    417   }
    418 }
    419 
    420 
    421 TEST(RegressChromium62639) {
    422   v8::V8::Initialize();
    423   i::Isolate* isolate = CcTest::i_isolate();
    424 
    425   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    426                                         128 * 1024);
    427 
    428   const char* program = "var x = 'something';\n"
    429                         "escape: function() {}";
    430   // Fails parsing expecting an identifier after "function".
    431   // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
    432   // and then used the invalid currently scanned literal. This always
    433   // failed in debug mode, and sometimes crashed in release mode.
    434 
    435   i::Utf8ToUtf16CharacterStream stream(
    436       reinterpret_cast<const i::byte*>(program),
    437       static_cast<unsigned>(strlen(program)));
    438   i::CompleteParserRecorder log;
    439   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    440   scanner.Initialize(&stream);
    441   i::Zone zone(CcTest::i_isolate()->allocator());
    442   i::AstValueFactory ast_value_factory(&zone,
    443                                        CcTest::i_isolate()->heap()->HashSeed());
    444   i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    445                          CcTest::i_isolate()->stack_guard()->real_climit());
    446   preparser.set_allow_lazy(true);
    447   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    448   // Even in the case of a syntax error, kPreParseSuccess is returned.
    449   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    450   CHECK(log.HasError());
    451 }
    452 
    453 
    454 TEST(Regress928) {
    455   v8::V8::Initialize();
    456   i::Isolate* isolate = CcTest::i_isolate();
    457   i::Factory* factory = isolate->factory();
    458 
    459   // Preparsing didn't consider the catch clause of a try statement
    460   // as with-content, which made it assume that a function inside
    461   // the block could be lazily compiled, and an extra, unexpected,
    462   // entry was added to the data.
    463   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    464                                         128 * 1024);
    465 
    466   const char* program =
    467       "try { } catch (e) { var foo = function () { /* first */ } }"
    468       "var bar = function () { /* second */ }";
    469 
    470   v8::HandleScope handles(CcTest::isolate());
    471   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(program);
    472   i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
    473   i::CompleteParserRecorder log;
    474   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    475   scanner.Initialize(&stream);
    476   i::Zone zone(CcTest::i_isolate()->allocator());
    477   i::AstValueFactory ast_value_factory(&zone,
    478                                        CcTest::i_isolate()->heap()->HashSeed());
    479   i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    480                          CcTest::i_isolate()->stack_guard()->real_climit());
    481   preparser.set_allow_lazy(true);
    482   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    483   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    484   i::ScriptData* sd = log.GetScriptData();
    485   i::ParseData* pd = i::ParseData::FromCachedData(sd);
    486   pd->Initialize();
    487 
    488   int first_function =
    489       static_cast<int>(strstr(program, "function") - program);
    490   int first_lbrace = first_function + i::StrLength("function () ");
    491   CHECK_EQ('{', program[first_lbrace]);
    492   i::FunctionEntry entry1 = pd->GetFunctionEntry(first_lbrace);
    493   CHECK(!entry1.is_valid());
    494 
    495   int second_function =
    496       static_cast<int>(strstr(program + first_lbrace, "function") - program);
    497   int second_lbrace =
    498       second_function + i::StrLength("function () ");
    499   CHECK_EQ('{', program[second_lbrace]);
    500   i::FunctionEntry entry2 = pd->GetFunctionEntry(second_lbrace);
    501   CHECK(entry2.is_valid());
    502   CHECK_EQ('}', program[entry2.end_pos() - 1]);
    503   delete sd;
    504   delete pd;
    505 }
    506 
    507 
    508 TEST(PreParseOverflow) {
    509   v8::V8::Initialize();
    510 
    511   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    512       i::GetCurrentStackPosition() - 128 * 1024);
    513 
    514   size_t kProgramSize = 1024 * 1024;
    515   v8::base::SmartArrayPointer<char> program(
    516       i::NewArray<char>(kProgramSize + 1));
    517   memset(program.get(), '(', kProgramSize);
    518   program[kProgramSize] = '\0';
    519 
    520   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    521 
    522   i::Utf8ToUtf16CharacterStream stream(
    523       reinterpret_cast<const i::byte*>(program.get()),
    524       static_cast<unsigned>(kProgramSize));
    525   i::CompleteParserRecorder log;
    526   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    527   scanner.Initialize(&stream);
    528 
    529   i::Zone zone(CcTest::i_isolate()->allocator());
    530   i::AstValueFactory ast_value_factory(&zone,
    531                                        CcTest::i_isolate()->heap()->HashSeed());
    532   i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
    533                          stack_limit);
    534   preparser.set_allow_lazy(true);
    535   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    536   CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
    537 }
    538 
    539 
    540 class TestExternalResource: public v8::String::ExternalStringResource {
    541  public:
    542   explicit TestExternalResource(uint16_t* data, int length)
    543       : data_(data), length_(static_cast<size_t>(length)) { }
    544 
    545   ~TestExternalResource() { }
    546 
    547   const uint16_t* data() const {
    548     return data_;
    549   }
    550 
    551   size_t length() const {
    552     return length_;
    553   }
    554  private:
    555   uint16_t* data_;
    556   size_t length_;
    557 };
    558 
    559 
    560 #define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
    561 
    562 void TestCharacterStream(const char* one_byte_source, unsigned length,
    563                          unsigned start = 0, unsigned end = 0) {
    564   if (end == 0) end = length;
    565   unsigned sub_length = end - start;
    566   i::Isolate* isolate = CcTest::i_isolate();
    567   i::Factory* factory = isolate->factory();
    568   i::HandleScope test_scope(isolate);
    569   v8::base::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
    570   for (unsigned i = 0; i < length; i++) {
    571     uc16_buffer[i] = static_cast<i::uc16>(one_byte_source[i]);
    572   }
    573   i::Vector<const char> one_byte_vector(one_byte_source,
    574                                         static_cast<int>(length));
    575   i::Handle<i::String> one_byte_string =
    576       factory->NewStringFromAscii(one_byte_vector).ToHandleChecked();
    577   TestExternalResource resource(uc16_buffer.get(), length);
    578   i::Handle<i::String> uc16_string(
    579       factory->NewExternalStringFromTwoByte(&resource).ToHandleChecked());
    580 
    581   i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
    582       i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
    583   i::GenericStringUtf16CharacterStream string_stream(one_byte_string, start,
    584                                                      end);
    585   i::Utf8ToUtf16CharacterStream utf8_stream(
    586       reinterpret_cast<const i::byte*>(one_byte_source), end);
    587   utf8_stream.SeekForward(start);
    588 
    589   unsigned i = start;
    590   while (i < end) {
    591     // Read streams one char at a time
    592     CHECK_EQU(i, uc16_stream.pos());
    593     CHECK_EQU(i, string_stream.pos());
    594     CHECK_EQU(i, utf8_stream.pos());
    595     int32_t c0 = one_byte_source[i];
    596     int32_t c1 = uc16_stream.Advance();
    597     int32_t c2 = string_stream.Advance();
    598     int32_t c3 = utf8_stream.Advance();
    599     i++;
    600     CHECK_EQ(c0, c1);
    601     CHECK_EQ(c0, c2);
    602     CHECK_EQ(c0, c3);
    603     CHECK_EQU(i, uc16_stream.pos());
    604     CHECK_EQU(i, string_stream.pos());
    605     CHECK_EQU(i, utf8_stream.pos());
    606   }
    607   while (i > start + sub_length / 4) {
    608     // Pushback, re-read, pushback again.
    609     int32_t c0 = one_byte_source[i - 1];
    610     CHECK_EQU(i, uc16_stream.pos());
    611     CHECK_EQU(i, string_stream.pos());
    612     CHECK_EQU(i, utf8_stream.pos());
    613     uc16_stream.PushBack(c0);
    614     string_stream.PushBack(c0);
    615     utf8_stream.PushBack(c0);
    616     i--;
    617     CHECK_EQU(i, uc16_stream.pos());
    618     CHECK_EQU(i, string_stream.pos());
    619     CHECK_EQU(i, utf8_stream.pos());
    620     int32_t c1 = uc16_stream.Advance();
    621     int32_t c2 = string_stream.Advance();
    622     int32_t c3 = utf8_stream.Advance();
    623     i++;
    624     CHECK_EQU(i, uc16_stream.pos());
    625     CHECK_EQU(i, string_stream.pos());
    626     CHECK_EQU(i, utf8_stream.pos());
    627     CHECK_EQ(c0, c1);
    628     CHECK_EQ(c0, c2);
    629     CHECK_EQ(c0, c3);
    630     uc16_stream.PushBack(c0);
    631     string_stream.PushBack(c0);
    632     utf8_stream.PushBack(c0);
    633     i--;
    634     CHECK_EQU(i, uc16_stream.pos());
    635     CHECK_EQU(i, string_stream.pos());
    636     CHECK_EQU(i, utf8_stream.pos());
    637   }
    638   unsigned halfway = start + sub_length / 2;
    639   uc16_stream.SeekForward(halfway - i);
    640   string_stream.SeekForward(halfway - i);
    641   utf8_stream.SeekForward(halfway - i);
    642   i = halfway;
    643   CHECK_EQU(i, uc16_stream.pos());
    644   CHECK_EQU(i, string_stream.pos());
    645   CHECK_EQU(i, utf8_stream.pos());
    646 
    647   while (i < end) {
    648     // Read streams one char at a time
    649     CHECK_EQU(i, uc16_stream.pos());
    650     CHECK_EQU(i, string_stream.pos());
    651     CHECK_EQU(i, utf8_stream.pos());
    652     int32_t c0 = one_byte_source[i];
    653     int32_t c1 = uc16_stream.Advance();
    654     int32_t c2 = string_stream.Advance();
    655     int32_t c3 = utf8_stream.Advance();
    656     i++;
    657     CHECK_EQ(c0, c1);
    658     CHECK_EQ(c0, c2);
    659     CHECK_EQ(c0, c3);
    660     CHECK_EQU(i, uc16_stream.pos());
    661     CHECK_EQU(i, string_stream.pos());
    662     CHECK_EQU(i, utf8_stream.pos());
    663   }
    664 
    665   int32_t c1 = uc16_stream.Advance();
    666   int32_t c2 = string_stream.Advance();
    667   int32_t c3 = utf8_stream.Advance();
    668   CHECK_LT(c1, 0);
    669   CHECK_LT(c2, 0);
    670   CHECK_LT(c3, 0);
    671 }
    672 
    673 
    674 TEST(CharacterStreams) {
    675   v8::Isolate* isolate = CcTest::isolate();
    676   v8::HandleScope handles(isolate);
    677   v8::Local<v8::Context> context = v8::Context::New(isolate);
    678   v8::Context::Scope context_scope(context);
    679 
    680   TestCharacterStream("abc\0\n\r\x7f", 7);
    681   static const unsigned kBigStringSize = 4096;
    682   char buffer[kBigStringSize + 1];
    683   for (unsigned i = 0; i < kBigStringSize; i++) {
    684     buffer[i] = static_cast<char>(i & 0x7f);
    685   }
    686   TestCharacterStream(buffer, kBigStringSize);
    687 
    688   TestCharacterStream(buffer, kBigStringSize, 576, 3298);
    689 
    690   TestCharacterStream("\0", 1);
    691   TestCharacterStream("", 0);
    692 }
    693 
    694 
    695 TEST(Utf8CharacterStream) {
    696   static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar;
    697   static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU);
    698 
    699   static const int kAllUtf8CharsSize =
    700       (unibrow::Utf8::kMaxOneByteChar + 1) +
    701       (unibrow::Utf8::kMaxTwoByteChar - unibrow::Utf8::kMaxOneByteChar) * 2 +
    702       (unibrow::Utf8::kMaxThreeByteChar - unibrow::Utf8::kMaxTwoByteChar) * 3;
    703   static const unsigned kAllUtf8CharsSizeU =
    704       static_cast<unsigned>(kAllUtf8CharsSize);
    705 
    706   char buffer[kAllUtf8CharsSizeU];
    707   unsigned cursor = 0;
    708   for (int i = 0; i <= kMaxUC16Char; i++) {
    709     cursor += unibrow::Utf8::Encode(buffer + cursor, i,
    710                                     unibrow::Utf16::kNoPreviousCharacter, true);
    711   }
    712   CHECK(cursor == kAllUtf8CharsSizeU);
    713 
    714   i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
    715                                        kAllUtf8CharsSizeU);
    716   int32_t bad = unibrow::Utf8::kBadChar;
    717   for (int i = 0; i <= kMaxUC16Char; i++) {
    718     CHECK_EQU(i, stream.pos());
    719     int32_t c = stream.Advance();
    720     if (i >= 0xd800 && i <= 0xdfff) {
    721       CHECK_EQ(bad, c);
    722     } else {
    723       CHECK_EQ(i, c);
    724     }
    725     CHECK_EQU(i + 1, stream.pos());
    726   }
    727   for (int i = kMaxUC16Char; i >= 0; i--) {
    728     CHECK_EQU(i + 1, stream.pos());
    729     stream.PushBack(i);
    730     CHECK_EQU(i, stream.pos());
    731   }
    732   int i = 0;
    733   while (stream.pos() < kMaxUC16CharU) {
    734     CHECK_EQU(i, stream.pos());
    735     int progress = static_cast<int>(stream.SeekForward(12));
    736     i += progress;
    737     int32_t c = stream.Advance();
    738     if (i >= 0xd800 && i <= 0xdfff) {
    739       CHECK_EQ(bad, c);
    740     } else if (i <= kMaxUC16Char) {
    741       CHECK_EQ(i, c);
    742     } else {
    743       CHECK_EQ(-1, c);
    744     }
    745     i += 1;
    746     CHECK_EQU(i, stream.pos());
    747   }
    748 }
    749 
    750 #undef CHECK_EQU
    751 
    752 void TestStreamScanner(i::Utf16CharacterStream* stream,
    753                        i::Token::Value* expected_tokens,
    754                        int skip_pos = 0,  // Zero means not skipping.
    755                        int skip_to = 0) {
    756   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    757   scanner.Initialize(stream);
    758 
    759   int i = 0;
    760   do {
    761     i::Token::Value expected = expected_tokens[i];
    762     i::Token::Value actual = scanner.Next();
    763     CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
    764     if (scanner.location().end_pos == skip_pos) {
    765       scanner.SeekForward(skip_to);
    766     }
    767     i++;
    768   } while (expected_tokens[i] != i::Token::ILLEGAL);
    769 }
    770 
    771 
    772 TEST(StreamScanner) {
    773   v8::V8::Initialize();
    774 
    775   const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
    776   i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
    777                                         static_cast<unsigned>(strlen(str1)));
    778   i::Token::Value expectations1[] = {
    779       i::Token::LBRACE,
    780       i::Token::IDENTIFIER,
    781       i::Token::IDENTIFIER,
    782       i::Token::FOR,
    783       i::Token::COLON,
    784       i::Token::MUL,
    785       i::Token::DIV,
    786       i::Token::LT,
    787       i::Token::SUB,
    788       i::Token::IDENTIFIER,
    789       i::Token::EOS,
    790       i::Token::ILLEGAL
    791   };
    792   TestStreamScanner(&stream1, expectations1, 0, 0);
    793 
    794   const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
    795   i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
    796                                         static_cast<unsigned>(strlen(str2)));
    797   i::Token::Value expectations2[] = {
    798       i::Token::CASE,
    799       i::Token::DEFAULT,
    800       i::Token::CONST,
    801       i::Token::LBRACE,
    802       // Skipped part here
    803       i::Token::RBRACE,
    804       i::Token::DO,
    805       i::Token::EOS,
    806       i::Token::ILLEGAL
    807   };
    808   CHECK_EQ('{', str2[19]);
    809   CHECK_EQ('}', str2[37]);
    810   TestStreamScanner(&stream2, expectations2, 20, 37);
    811 
    812   const char* str3 = "{}}}}";
    813   i::Token::Value expectations3[] = {
    814       i::Token::LBRACE,
    815       i::Token::RBRACE,
    816       i::Token::RBRACE,
    817       i::Token::RBRACE,
    818       i::Token::RBRACE,
    819       i::Token::EOS,
    820       i::Token::ILLEGAL
    821   };
    822   // Skip zero-four RBRACEs.
    823   for (int i = 0; i <= 4; i++) {
    824      expectations3[6 - i] = i::Token::ILLEGAL;
    825      expectations3[5 - i] = i::Token::EOS;
    826      i::Utf8ToUtf16CharacterStream stream3(
    827          reinterpret_cast<const i::byte*>(str3),
    828          static_cast<unsigned>(strlen(str3)));
    829      TestStreamScanner(&stream3, expectations3, 1, 1 + i);
    830   }
    831 }
    832 
    833 
    834 void TestScanRegExp(const char* re_source, const char* expected) {
    835   i::Utf8ToUtf16CharacterStream stream(
    836        reinterpret_cast<const i::byte*>(re_source),
    837        static_cast<unsigned>(strlen(re_source)));
    838   i::HandleScope scope(CcTest::i_isolate());
    839   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    840   scanner.Initialize(&stream);
    841 
    842   i::Token::Value start = scanner.peek();
    843   CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
    844   CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
    845   scanner.Next();  // Current token is now the regexp literal.
    846   i::Zone zone(CcTest::i_isolate()->allocator());
    847   i::AstValueFactory ast_value_factory(&zone,
    848                                        CcTest::i_isolate()->heap()->HashSeed());
    849   ast_value_factory.Internalize(CcTest::i_isolate());
    850   i::Handle<i::String> val =
    851       scanner.CurrentSymbol(&ast_value_factory)->string();
    852   i::DisallowHeapAllocation no_alloc;
    853   i::String::FlatContent content = val->GetFlatContent();
    854   CHECK(content.IsOneByte());
    855   i::Vector<const uint8_t> actual = content.ToOneByteVector();
    856   for (int i = 0; i < actual.length(); i++) {
    857     CHECK_NE('\0', expected[i]);
    858     CHECK_EQ(expected[i], actual[i]);
    859   }
    860 }
    861 
    862 
    863 TEST(RegExpScanning) {
    864   v8::V8::Initialize();
    865 
    866   // RegExp token with added garbage at the end. The scanner should only
    867   // scan the RegExp until the terminating slash just before "flipperwald".
    868   TestScanRegExp("/b/flipperwald", "b");
    869   // Incomplete escape sequences doesn't hide the terminating slash.
    870   TestScanRegExp("/\\x/flipperwald", "\\x");
    871   TestScanRegExp("/\\u/flipperwald", "\\u");
    872   TestScanRegExp("/\\u1/flipperwald", "\\u1");
    873   TestScanRegExp("/\\u12/flipperwald", "\\u12");
    874   TestScanRegExp("/\\u123/flipperwald", "\\u123");
    875   TestScanRegExp("/\\c/flipperwald", "\\c");
    876   TestScanRegExp("/\\c//flipperwald", "\\c");
    877   // Slashes inside character classes are not terminating.
    878   TestScanRegExp("/[/]/flipperwald", "[/]");
    879   TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
    880   // Incomplete escape sequences inside a character class doesn't hide
    881   // the end of the character class.
    882   TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
    883   TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
    884   TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
    885   TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
    886   TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
    887   TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
    888   TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
    889   TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
    890   // Escaped ']'s wont end the character class.
    891   TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
    892   // Escaped slashes are not terminating.
    893   TestScanRegExp("/\\//flipperwald", "\\/");
    894   // Starting with '=' works too.
    895   TestScanRegExp("/=/", "=");
    896   TestScanRegExp("/=?/", "=?");
    897 }
    898 
    899 
    900 static int Utf8LengthHelper(const char* s) {
    901   int len = i::StrLength(s);
    902   int character_length = len;
    903   for (int i = 0; i < len; i++) {
    904     unsigned char c = s[i];
    905     int input_offset = 0;
    906     int output_adjust = 0;
    907     if (c > 0x7f) {
    908       if (c < 0xc0) continue;
    909       if (c >= 0xf0) {
    910         if (c >= 0xf8) {
    911           // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
    912           // byte.
    913           continue;  // Handle first UTF-8 byte.
    914         }
    915         if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
    916           // This 4 byte sequence could have been coded as a 3 byte sequence.
    917           // Record a single kBadChar for the first byte and continue.
    918           continue;
    919         }
    920         input_offset = 3;
    921         // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
    922         character_length -= 2;
    923       } else if (c >= 0xe0) {
    924         if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
    925           // This 3 byte sequence could have been coded as a 2 byte sequence.
    926           // Record a single kBadChar for the first byte and continue.
    927           continue;
    928         }
    929         if (c == 0xed) {
    930           unsigned char d = s[i + 1];
    931           if ((d < 0x80) || (d > 0x9f)) {
    932             // This 3 byte sequence is part of a surrogate pair which is not
    933             // supported by UTF-8. Record a single kBadChar for the first byte
    934             // and continue.
    935             continue;
    936           }
    937         }
    938         input_offset = 2;
    939         // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
    940         output_adjust = 2;
    941       } else {
    942         if ((c & 0x1e) == 0) {
    943           // This 2 byte sequence could have been coded as a 1 byte sequence.
    944           // Record a single kBadChar for the first byte and continue.
    945           continue;
    946         }
    947         input_offset = 1;
    948         // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
    949         output_adjust = 1;
    950       }
    951       bool bad = false;
    952       for (int j = 1; j <= input_offset; j++) {
    953         if ((s[i + j] & 0xc0) != 0x80) {
    954           // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
    955           // which is a single UTF-16 code unit.
    956           bad = true;
    957           break;
    958         }
    959       }
    960       if (!bad) {
    961         i += input_offset;
    962         character_length -= output_adjust;
    963       }
    964     }
    965   }
    966   return character_length;
    967 }
    968 
    969 
    970 TEST(ScopeUsesArgumentsSuperThis) {
    971   static const struct {
    972     const char* prefix;
    973     const char* suffix;
    974   } surroundings[] = {
    975     { "function f() {", "}" },
    976     { "var f = () => {", "};" },
    977     { "class C { constructor() {", "} }" },
    978   };
    979 
    980   enum Expected {
    981     NONE = 0,
    982     ARGUMENTS = 1,
    983     SUPER_PROPERTY = 1 << 1,
    984     THIS = 1 << 2,
    985     EVAL = 1 << 4
    986   };
    987 
    988   // clang-format off
    989   static const struct {
    990     const char* body;
    991     int expected;
    992   } source_data[] = {
    993     {"", NONE},
    994     {"return this", THIS},
    995     {"return arguments", ARGUMENTS},
    996     {"return super.x", SUPER_PROPERTY},
    997     {"return arguments[0]", ARGUMENTS},
    998     {"return this + arguments[0]", ARGUMENTS | THIS},
    999     {"return this + arguments[0] + super.x",
   1000      ARGUMENTS | SUPER_PROPERTY | THIS},
   1001     {"return x => this + x", THIS},
   1002     {"return x => super.f() + x", SUPER_PROPERTY},
   1003     {"this.foo = 42;", THIS},
   1004     {"this.foo();", THIS},
   1005     {"if (foo()) { this.f() }", THIS},
   1006     {"if (foo()) { super.f() }", SUPER_PROPERTY},
   1007     {"if (arguments.length) { this.f() }", ARGUMENTS | THIS},
   1008     {"while (true) { this.f() }", THIS},
   1009     {"while (true) { super.f() }", SUPER_PROPERTY},
   1010     {"if (true) { while (true) this.foo(arguments) }", ARGUMENTS | THIS},
   1011     // Multiple nesting levels must work as well.
   1012     {"while (true) { while (true) { while (true) return this } }", THIS},
   1013     {"while (true) { while (true) { while (true) return super.f() } }",
   1014      SUPER_PROPERTY},
   1015     {"if (1) { return () => { while (true) new this() } }", THIS},
   1016     {"return function (x) { return this + x }", NONE},
   1017     {"return { m(x) { return super.m() + x } }", NONE},
   1018     {"var x = function () { this.foo = 42 };", NONE},
   1019     {"var x = { m() { super.foo = 42 } };", NONE},
   1020     {"if (1) { return function () { while (true) new this() } }", NONE},
   1021     {"if (1) { return { m() { while (true) super.m() } } }", NONE},
   1022     {"return function (x) { return () => this }", NONE},
   1023     {"return { m(x) { return () => super.m() } }", NONE},
   1024     // Flags must be correctly set when using block scoping.
   1025     {"\"use strict\"; while (true) { let x; this, arguments; }",
   1026      THIS},
   1027     {"\"use strict\"; while (true) { let x; this, super.f(), arguments; }",
   1028      SUPER_PROPERTY | THIS},
   1029     {"\"use strict\"; if (foo()) { let x; this.f() }", THIS},
   1030     {"\"use strict\"; if (foo()) { let x; super.f() }", SUPER_PROPERTY},
   1031     {"\"use strict\"; if (1) {"
   1032      "  let x; return { m() { return this + super.m() + arguments } }"
   1033      "}",
   1034      NONE},
   1035     {"eval(42)", EVAL},
   1036     {"if (1) { eval(42) }", EVAL},
   1037     {"eval('super.x')", EVAL},
   1038     {"eval('this.x')", EVAL},
   1039     {"eval('arguments')", EVAL},
   1040   };
   1041   // clang-format on
   1042 
   1043   i::Isolate* isolate = CcTest::i_isolate();
   1044   i::Factory* factory = isolate->factory();
   1045 
   1046   v8::HandleScope handles(CcTest::isolate());
   1047   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   1048   v8::Context::Scope context_scope(context);
   1049 
   1050   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   1051                                         128 * 1024);
   1052 
   1053   for (unsigned j = 0; j < arraysize(surroundings); ++j) {
   1054     for (unsigned i = 0; i < arraysize(source_data); ++i) {
   1055       // Super property is only allowed in constructor and method.
   1056       if (((source_data[i].expected & SUPER_PROPERTY) ||
   1057            (source_data[i].expected == NONE)) && j != 2) {
   1058         continue;
   1059       }
   1060       int kProgramByteSize = i::StrLength(surroundings[j].prefix) +
   1061                              i::StrLength(surroundings[j].suffix) +
   1062                              i::StrLength(source_data[i].body);
   1063       i::ScopedVector<char> program(kProgramByteSize + 1);
   1064       i::SNPrintF(program, "%s%s%s", surroundings[j].prefix,
   1065                   source_data[i].body, surroundings[j].suffix);
   1066       i::Handle<i::String> source =
   1067           factory->NewStringFromUtf8(i::CStrVector(program.start()))
   1068               .ToHandleChecked();
   1069       i::Handle<i::Script> script = factory->NewScript(source);
   1070       i::Zone zone(CcTest::i_isolate()->allocator());
   1071       i::ParseInfo info(&zone, script);
   1072       i::Parser parser(&info);
   1073       info.set_global();
   1074       CHECK(parser.Parse(&info));
   1075       CHECK(i::Rewriter::Rewrite(&info));
   1076       CHECK(i::Scope::Analyze(&info));
   1077       CHECK(info.literal() != NULL);
   1078 
   1079       i::Scope* script_scope = info.literal()->scope();
   1080       CHECK(script_scope->is_script_scope());
   1081       CHECK_EQ(1, script_scope->inner_scopes()->length());
   1082 
   1083       i::Scope* scope = script_scope->inner_scopes()->at(0);
   1084       // Adjust for constructor scope.
   1085       if (j == 2) {
   1086         CHECK_EQ(1, scope->inner_scopes()->length());
   1087         scope = scope->inner_scopes()->at(0);
   1088       }
   1089       CHECK_EQ((source_data[i].expected & ARGUMENTS) != 0,
   1090                scope->uses_arguments());
   1091       CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
   1092                scope->uses_super_property());
   1093       if ((source_data[i].expected & THIS) != 0) {
   1094         // Currently the is_used() flag is conservative; all variables in a
   1095         // script scope are marked as used.
   1096         CHECK(
   1097             scope->Lookup(info.ast_value_factory()->this_string())->is_used());
   1098       }
   1099       CHECK_EQ((source_data[i].expected & EVAL) != 0, scope->calls_eval());
   1100     }
   1101   }
   1102 }
   1103 
   1104 
   1105 static void CheckParsesToNumber(const char* source, bool with_dot) {
   1106   v8::V8::Initialize();
   1107   HandleAndZoneScope handles;
   1108 
   1109   i::Isolate* isolate = CcTest::i_isolate();
   1110   i::Factory* factory = isolate->factory();
   1111 
   1112   std::string full_source = "function f() { return ";
   1113   full_source += source;
   1114   full_source += "; }";
   1115 
   1116   i::Handle<i::String> source_code =
   1117       factory->NewStringFromUtf8(i::CStrVector(full_source.c_str()))
   1118           .ToHandleChecked();
   1119 
   1120   i::Handle<i::Script> script = factory->NewScript(source_code);
   1121 
   1122   i::ParseInfo info(handles.main_zone(), script);
   1123   i::Parser parser(&info);
   1124   info.set_global();
   1125   info.set_lazy(false);
   1126   info.set_allow_lazy_parsing(false);
   1127   info.set_toplevel(true);
   1128 
   1129   CHECK(i::Compiler::ParseAndAnalyze(&info));
   1130 
   1131   CHECK(info.scope()->declarations()->length() == 1);
   1132   i::FunctionLiteral* fun =
   1133       info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
   1134   CHECK(fun->body()->length() == 1);
   1135   CHECK(fun->body()->at(0)->IsReturnStatement());
   1136   i::ReturnStatement* ret = fun->body()->at(0)->AsReturnStatement();
   1137   i::Literal* lit = ret->expression()->AsLiteral();
   1138   if (lit != NULL) {
   1139     const i::AstValue* val = lit->raw_value();
   1140     CHECK(with_dot == val->ContainsDot());
   1141   } else if (with_dot) {
   1142     i::BinaryOperation* bin = ret->expression()->AsBinaryOperation();
   1143     CHECK(bin != NULL);
   1144     CHECK_EQ(i::Token::MUL, bin->op());
   1145     i::Literal* rlit = bin->right()->AsLiteral();
   1146     const i::AstValue* val = rlit->raw_value();
   1147     CHECK(with_dot == val->ContainsDot());
   1148     CHECK_EQ(1.0, val->AsNumber());
   1149   }
   1150 }
   1151 
   1152 
   1153 TEST(ParseNumbers) {
   1154   CheckParsesToNumber("1.", true);
   1155   CheckParsesToNumber("1.34", true);
   1156   CheckParsesToNumber("134", false);
   1157   CheckParsesToNumber("134e44", false);
   1158   CheckParsesToNumber("134.e44", true);
   1159   CheckParsesToNumber("134.44e44", true);
   1160   CheckParsesToNumber(".44", true);
   1161 
   1162   CheckParsesToNumber("-1.", true);
   1163   CheckParsesToNumber("-1.0", true);
   1164   CheckParsesToNumber("-1.34", true);
   1165   CheckParsesToNumber("-134", false);
   1166   CheckParsesToNumber("-134e44", false);
   1167   CheckParsesToNumber("-134.e44", true);
   1168   CheckParsesToNumber("-134.44e44", true);
   1169   CheckParsesToNumber("-.44", true);
   1170 
   1171   CheckParsesToNumber("+x", true);
   1172 }
   1173 
   1174 
   1175 TEST(ScopePositions) {
   1176   // Test the parser for correctly setting the start and end positions
   1177   // of a scope. We check the scope positions of exactly one scope
   1178   // nested in the global scope of a program. 'inner source' is the
   1179   // source code that determines the part of the source belonging
   1180   // to the nested scope. 'outer_prefix' and 'outer_suffix' are
   1181   // parts of the source that belong to the global scope.
   1182   struct SourceData {
   1183     const char* outer_prefix;
   1184     const char* inner_source;
   1185     const char* outer_suffix;
   1186     i::ScopeType scope_type;
   1187     i::LanguageMode language_mode;
   1188   };
   1189 
   1190   const SourceData source_data[] = {
   1191     { "  with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::SLOPPY },
   1192     { "  with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::SLOPPY },
   1193     { "  with ({}) ", "{\n"
   1194       "    block;\n"
   1195       "  }", "\n"
   1196       "  more;", i::WITH_SCOPE, i::SLOPPY },
   1197     { "  with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::SLOPPY },
   1198     { "  with ({}) ", "statement", "\n"
   1199       "  more;", i::WITH_SCOPE, i::SLOPPY },
   1200     { "  with ({})\n"
   1201       "    ", "statement;", "\n"
   1202       "  more;", i::WITH_SCOPE, i::SLOPPY },
   1203     { "  try {} catch ", "(e) { block; }", " more;",
   1204       i::CATCH_SCOPE, i::SLOPPY },
   1205     { "  try {} catch ", "(e) { block; }", "; more;",
   1206       i::CATCH_SCOPE, i::SLOPPY },
   1207     { "  try {} catch ", "(e) {\n"
   1208       "    block;\n"
   1209       "  }", "\n"
   1210       "  more;", i::CATCH_SCOPE, i::SLOPPY },
   1211     { "  try {} catch ", "(e) { block; }", " finally { block; } more;",
   1212       i::CATCH_SCOPE, i::SLOPPY },
   1213     { "  start;\n"
   1214       "  ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::STRICT },
   1215     { "  start;\n"
   1216       "  ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::STRICT },
   1217     { "  start;\n"
   1218       "  ", "{\n"
   1219       "    let block;\n"
   1220       "  }", "\n"
   1221       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1222     { "  start;\n"
   1223       "  function fun", "(a,b) { infunction; }", " more;",
   1224       i::FUNCTION_SCOPE, i::SLOPPY },
   1225     { "  start;\n"
   1226       "  function fun", "(a,b) {\n"
   1227       "    infunction;\n"
   1228       "  }", "\n"
   1229       "  more;", i::FUNCTION_SCOPE, i::SLOPPY },
   1230     { "  start;\n", "(a,b) => a + b", "; more;",
   1231       i::FUNCTION_SCOPE, i::SLOPPY },
   1232     { "  start;\n", "(a,b) => { return a+b; }", "\nmore;",
   1233       i::FUNCTION_SCOPE, i::SLOPPY },
   1234     { "  start;\n"
   1235       "  (function fun", "(a,b) { infunction; }", ")();",
   1236       i::FUNCTION_SCOPE, i::SLOPPY },
   1237     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
   1238       i::BLOCK_SCOPE, i::STRICT },
   1239     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
   1240       i::BLOCK_SCOPE, i::STRICT },
   1241     { "  for ", "(let x = 1 ; x < 10; ++ x) {\n"
   1242       "    block;\n"
   1243       "  }", "\n"
   1244       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1245     { "  for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
   1246       i::BLOCK_SCOPE, i::STRICT },
   1247     { "  for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
   1248       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1249     { "  for ", "(let x = 1 ; x < 10; ++ x)\n"
   1250       "    statement;", "\n"
   1251       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1252     { "  for ", "(let x in {}) { block; }", " more;",
   1253       i::BLOCK_SCOPE, i::STRICT },
   1254     { "  for ", "(let x in {}) { block; }", "; more;",
   1255       i::BLOCK_SCOPE, i::STRICT },
   1256     { "  for ", "(let x in {}) {\n"
   1257       "    block;\n"
   1258       "  }", "\n"
   1259       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1260     { "  for ", "(let x in {}) statement;", " more;",
   1261       i::BLOCK_SCOPE, i::STRICT },
   1262     { "  for ", "(let x in {}) statement", "\n"
   1263       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1264     { "  for ", "(let x in {})\n"
   1265       "    statement;", "\n"
   1266       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1267     // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
   1268     // the preparser off in terms of byte offsets.
   1269     // 6 byte encoding.
   1270     { "  'foo\355\240\201\355\260\211';\n"
   1271       "  (function fun", "(a,b) { infunction; }", ")();",
   1272       i::FUNCTION_SCOPE, i::SLOPPY },
   1273     // 4 byte encoding.
   1274     { "  'foo\360\220\220\212';\n"
   1275       "  (function fun", "(a,b) { infunction; }", ")();",
   1276       i::FUNCTION_SCOPE, i::SLOPPY },
   1277     // 3 byte encoding of \u0fff.
   1278     { "  'foo\340\277\277';\n"
   1279       "  (function fun", "(a,b) { infunction; }", ")();",
   1280       i::FUNCTION_SCOPE, i::SLOPPY },
   1281     // Broken 6 byte encoding with missing last byte.
   1282     { "  'foo\355\240\201\355\211';\n"
   1283       "  (function fun", "(a,b) { infunction; }", ")();",
   1284       i::FUNCTION_SCOPE, i::SLOPPY },
   1285     // Broken 3 byte encoding of \u0fff with missing last byte.
   1286     { "  'foo\340\277';\n"
   1287       "  (function fun", "(a,b) { infunction; }", ")();",
   1288       i::FUNCTION_SCOPE, i::SLOPPY },
   1289     // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
   1290     { "  'foo\340';\n"
   1291       "  (function fun", "(a,b) { infunction; }", ")();",
   1292       i::FUNCTION_SCOPE, i::SLOPPY },
   1293     // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
   1294     { "  'foo\340\203\277';\n"
   1295       "  (function fun", "(a,b) { infunction; }", ")();",
   1296       i::FUNCTION_SCOPE, i::SLOPPY },
   1297     // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
   1298     { "  'foo\340\201\277';\n"
   1299       "  (function fun", "(a,b) { infunction; }", ")();",
   1300       i::FUNCTION_SCOPE, i::SLOPPY },
   1301     // Unpaired lead surrogate.
   1302     { "  'foo\355\240\201';\n"
   1303       "  (function fun", "(a,b) { infunction; }", ")();",
   1304       i::FUNCTION_SCOPE, i::SLOPPY },
   1305     // Unpaired lead surrogate where following code point is a 3 byte sequence.
   1306     { "  'foo\355\240\201\340\277\277';\n"
   1307       "  (function fun", "(a,b) { infunction; }", ")();",
   1308       i::FUNCTION_SCOPE, i::SLOPPY },
   1309     // Unpaired lead surrogate where following code point is a 4 byte encoding
   1310     // of a trail surrogate.
   1311     { "  'foo\355\240\201\360\215\260\211';\n"
   1312       "  (function fun", "(a,b) { infunction; }", ")();",
   1313       i::FUNCTION_SCOPE, i::SLOPPY },
   1314     // Unpaired trail surrogate.
   1315     { "  'foo\355\260\211';\n"
   1316       "  (function fun", "(a,b) { infunction; }", ")();",
   1317       i::FUNCTION_SCOPE, i::SLOPPY },
   1318     // 2 byte encoding of \u00ff.
   1319     { "  'foo\303\277';\n"
   1320       "  (function fun", "(a,b) { infunction; }", ")();",
   1321       i::FUNCTION_SCOPE, i::SLOPPY },
   1322     // Broken 2 byte encoding of \u00ff with missing last byte.
   1323     { "  'foo\303';\n"
   1324       "  (function fun", "(a,b) { infunction; }", ")();",
   1325       i::FUNCTION_SCOPE, i::SLOPPY },
   1326     // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
   1327     { "  'foo\301\277';\n"
   1328       "  (function fun", "(a,b) { infunction; }", ")();",
   1329       i::FUNCTION_SCOPE, i::SLOPPY },
   1330     // Illegal 5 byte encoding.
   1331     { "  'foo\370\277\277\277\277';\n"
   1332       "  (function fun", "(a,b) { infunction; }", ")();",
   1333       i::FUNCTION_SCOPE, i::SLOPPY },
   1334     // Illegal 6 byte encoding.
   1335     { "  'foo\374\277\277\277\277\277';\n"
   1336       "  (function fun", "(a,b) { infunction; }", ")();",
   1337       i::FUNCTION_SCOPE, i::SLOPPY },
   1338     // Illegal 0xfe byte
   1339     { "  'foo\376\277\277\277\277\277\277';\n"
   1340       "  (function fun", "(a,b) { infunction; }", ")();",
   1341       i::FUNCTION_SCOPE, i::SLOPPY },
   1342     // Illegal 0xff byte
   1343     { "  'foo\377\277\277\277\277\277\277\277';\n"
   1344       "  (function fun", "(a,b) { infunction; }", ")();",
   1345       i::FUNCTION_SCOPE, i::SLOPPY },
   1346     { "  'foo';\n"
   1347       "  (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
   1348       i::FUNCTION_SCOPE, i::SLOPPY },
   1349     { "  'foo';\n"
   1350       "  (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
   1351       i::FUNCTION_SCOPE, i::SLOPPY },
   1352     { NULL, NULL, NULL, i::EVAL_SCOPE, i::SLOPPY }
   1353   };
   1354 
   1355   i::Isolate* isolate = CcTest::i_isolate();
   1356   i::Factory* factory = isolate->factory();
   1357 
   1358   v8::HandleScope handles(CcTest::isolate());
   1359   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   1360   v8::Context::Scope context_scope(context);
   1361 
   1362   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   1363                                         128 * 1024);
   1364 
   1365   for (int i = 0; source_data[i].outer_prefix; i++) {
   1366     int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
   1367     int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
   1368     int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
   1369     int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
   1370     int kInnerByteLen = i::StrLength(source_data[i].inner_source);
   1371     int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
   1372     int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
   1373     int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
   1374     i::ScopedVector<char> program(kProgramByteSize + 1);
   1375     i::SNPrintF(program, "%s%s%s",
   1376                          source_data[i].outer_prefix,
   1377                          source_data[i].inner_source,
   1378                          source_data[i].outer_suffix);
   1379 
   1380     // Parse program source.
   1381     i::Handle<i::String> source = factory->NewStringFromUtf8(
   1382         i::CStrVector(program.start())).ToHandleChecked();
   1383     CHECK_EQ(source->length(), kProgramSize);
   1384     i::Handle<i::Script> script = factory->NewScript(source);
   1385     i::Zone zone(CcTest::i_isolate()->allocator());
   1386     i::ParseInfo info(&zone, script);
   1387     i::Parser parser(&info);
   1388     parser.set_allow_lazy(true);
   1389     info.set_global();
   1390     info.set_language_mode(source_data[i].language_mode);
   1391     parser.Parse(&info);
   1392     CHECK(info.literal() != NULL);
   1393 
   1394     // Check scope types and positions.
   1395     i::Scope* scope = info.literal()->scope();
   1396     CHECK(scope->is_script_scope());
   1397     CHECK_EQ(scope->start_position(), 0);
   1398     CHECK_EQ(scope->end_position(), kProgramSize);
   1399     CHECK_EQ(scope->inner_scopes()->length(), 1);
   1400 
   1401     i::Scope* inner_scope = scope->inner_scopes()->at(0);
   1402     CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type);
   1403     CHECK_EQ(inner_scope->start_position(), kPrefixLen);
   1404     // The end position of a token is one position after the last
   1405     // character belonging to that token.
   1406     CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
   1407   }
   1408 }
   1409 
   1410 
   1411 TEST(DiscardFunctionBody) {
   1412   // Test that inner function bodies are discarded if possible.
   1413   // See comments in ParseFunctionLiteral in parser.cc.
   1414   const char* discard_sources[] = {
   1415       "(function f() { function g() { var a; } })();",
   1416       "(function f() { function g() { { function h() { } } } })();",
   1417       /* TODO(conradw): In future it may be possible to apply this optimisation
   1418        * to these productions.
   1419       "(function f() { 0, function g() { var a; } })();",
   1420       "(function f() { 0, { g() { var a; } } })();",
   1421       "(function f() { 0, class c { g() { var a; } } })();", */
   1422       NULL};
   1423 
   1424   i::Isolate* isolate = CcTest::i_isolate();
   1425   i::Factory* factory = isolate->factory();
   1426   v8::HandleScope handles(CcTest::isolate());
   1427   i::FunctionLiteral* function;
   1428 
   1429   for (int i = 0; discard_sources[i]; i++) {
   1430     const char* source = discard_sources[i];
   1431     i::Handle<i::String> source_code =
   1432         factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
   1433     i::Handle<i::Script> script = factory->NewScript(source_code);
   1434     i::Zone zone(CcTest::i_isolate()->allocator());
   1435     i::ParseInfo info(&zone, script);
   1436     info.set_allow_lazy_parsing();
   1437     i::Parser parser(&info);
   1438     parser.Parse(&info);
   1439     function = info.literal();
   1440     CHECK_NOT_NULL(function);
   1441     CHECK_NOT_NULL(function->body());
   1442     CHECK_EQ(1, function->body()->length());
   1443     i::FunctionLiteral* inner =
   1444         function->body()->first()->AsExpressionStatement()->expression()->
   1445         AsCall()->expression()->AsFunctionLiteral();
   1446     i::Scope* inner_scope = inner->scope();
   1447     i::FunctionLiteral* fun = nullptr;
   1448     if (inner_scope->declarations()->length() > 1) {
   1449       fun = inner_scope->declarations()->at(1)->AsFunctionDeclaration()->fun();
   1450     } else {
   1451       // TODO(conradw): This path won't be hit until the other test cases can be
   1452       // uncommented.
   1453       UNREACHABLE();
   1454       CHECK_NOT_NULL(inner->body());
   1455       CHECK_GE(2, inner->body()->length());
   1456       i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()->
   1457                            expression()->AsBinaryOperation()->right();
   1458       if (exp->IsFunctionLiteral()) {
   1459         fun = exp->AsFunctionLiteral();
   1460       } else if (exp->IsObjectLiteral()) {
   1461         fun = exp->AsObjectLiteral()->properties()->at(0)->value()->
   1462               AsFunctionLiteral();
   1463       } else {
   1464         fun = exp->AsClassLiteral()->properties()->at(0)->value()->
   1465               AsFunctionLiteral();
   1466       }
   1467     }
   1468     CHECK_NULL(fun->body());
   1469   }
   1470 }
   1471 
   1472 
   1473 const char* ReadString(unsigned* start) {
   1474   int length = start[0];
   1475   char* result = i::NewArray<char>(length + 1);
   1476   for (int i = 0; i < length; i++) {
   1477     result[i] = start[i + 1];
   1478   }
   1479   result[length] = '\0';
   1480   return result;
   1481 }
   1482 
   1483 
   1484 i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
   1485   i::Isolate* isolate = CcTest::i_isolate();
   1486   int message = data[i::PreparseDataConstants::kMessageTemplatePos];
   1487   int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
   1488   i::Handle<i::Object> arg_object;
   1489   if (arg_count == 1) {
   1490     // Position after text found by skipping past length field and
   1491     // length field content words.
   1492     const char* arg =
   1493         ReadString(&data[i::PreparseDataConstants::kMessageArgPos]);
   1494     arg_object = v8::Utils::OpenHandle(*v8_str(arg));
   1495     i::DeleteArray(arg);
   1496   } else {
   1497     CHECK_EQ(0, arg_count);
   1498     arg_object = isolate->factory()->undefined_value();
   1499   }
   1500 
   1501   data.Dispose();
   1502   return i::MessageTemplate::FormatMessage(isolate, message, arg_object);
   1503 }
   1504 
   1505 enum ParserFlag {
   1506   kAllowLazy,
   1507   kAllowNatives,
   1508   kAllowHarmonyFunctionSent,
   1509   kAllowHarmonyRestrictiveDeclarations,
   1510   kAllowHarmonyExponentiationOperator,
   1511   kAllowHarmonyForIn,
   1512   kAllowHarmonyAsyncAwait,
   1513   kAllowHarmonyRestrictiveGenerators,
   1514 };
   1515 
   1516 enum ParserSyncTestResult {
   1517   kSuccessOrError,
   1518   kSuccess,
   1519   kError
   1520 };
   1521 
   1522 template <typename Traits>
   1523 void SetParserFlags(i::ParserBase<Traits>* parser,
   1524                     i::EnumSet<ParserFlag> flags) {
   1525   parser->set_allow_lazy(flags.Contains(kAllowLazy));
   1526   parser->set_allow_natives(flags.Contains(kAllowNatives));
   1527   parser->set_allow_harmony_function_sent(
   1528       flags.Contains(kAllowHarmonyFunctionSent));
   1529   parser->set_allow_harmony_restrictive_declarations(
   1530       flags.Contains(kAllowHarmonyRestrictiveDeclarations));
   1531   parser->set_allow_harmony_exponentiation_operator(
   1532       flags.Contains(kAllowHarmonyExponentiationOperator));
   1533   parser->set_allow_harmony_for_in(flags.Contains(kAllowHarmonyForIn));
   1534   parser->set_allow_harmony_async_await(
   1535       flags.Contains(kAllowHarmonyAsyncAwait));
   1536   parser->set_allow_harmony_restrictive_generators(
   1537       flags.Contains(kAllowHarmonyRestrictiveGenerators));
   1538 }
   1539 
   1540 
   1541 void TestParserSyncWithFlags(i::Handle<i::String> source,
   1542                              i::EnumSet<ParserFlag> flags,
   1543                              ParserSyncTestResult result,
   1544                              bool is_module = false,
   1545                              bool test_preparser = true) {
   1546   i::Isolate* isolate = CcTest::i_isolate();
   1547   i::Factory* factory = isolate->factory();
   1548 
   1549   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
   1550   int preparser_materialized_literals = -1;
   1551   int parser_materialized_literals = -2;
   1552 
   1553   // Preparse the data.
   1554   i::CompleteParserRecorder log;
   1555   if (test_preparser) {
   1556     i::Scanner scanner(isolate->unicode_cache());
   1557     i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
   1558     i::Zone zone(CcTest::i_isolate()->allocator());
   1559     i::AstValueFactory ast_value_factory(
   1560         &zone, CcTest::i_isolate()->heap()->HashSeed());
   1561     i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
   1562                            stack_limit);
   1563     SetParserFlags(&preparser, flags);
   1564     scanner.Initialize(&stream);
   1565     i::PreParser::PreParseResult result =
   1566         preparser.PreParseProgram(&preparser_materialized_literals, is_module);
   1567     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
   1568   }
   1569   bool preparse_error = log.HasError();
   1570 
   1571   // Parse the data
   1572   i::FunctionLiteral* function;
   1573   {
   1574     i::Handle<i::Script> script = factory->NewScript(source);
   1575     i::Zone zone(CcTest::i_isolate()->allocator());
   1576     i::ParseInfo info(&zone, script);
   1577     i::Parser parser(&info);
   1578     SetParserFlags(&parser, flags);
   1579     if (is_module) {
   1580       info.set_module();
   1581     } else {
   1582       info.set_global();
   1583     }
   1584     parser.Parse(&info);
   1585     function = info.literal();
   1586     if (function) {
   1587       parser_materialized_literals = function->materialized_literal_count();
   1588     }
   1589   }
   1590 
   1591   // Check that preparsing fails iff parsing fails.
   1592   if (function == NULL) {
   1593     // Extract exception from the parser.
   1594     CHECK(isolate->has_pending_exception());
   1595     i::Handle<i::JSObject> exception_handle(
   1596         i::JSObject::cast(isolate->pending_exception()));
   1597     i::Handle<i::String> message_string = i::Handle<i::String>::cast(
   1598         i::JSReceiver::GetProperty(isolate, exception_handle, "message")
   1599             .ToHandleChecked());
   1600 
   1601     if (result == kSuccess) {
   1602       v8::base::OS::Print(
   1603           "Parser failed on:\n"
   1604           "\t%s\n"
   1605           "with error:\n"
   1606           "\t%s\n"
   1607           "However, we expected no error.",
   1608           source->ToCString().get(), message_string->ToCString().get());
   1609       CHECK(false);
   1610     }
   1611 
   1612     if (test_preparser && !preparse_error) {
   1613       v8::base::OS::Print(
   1614           "Parser failed on:\n"
   1615           "\t%s\n"
   1616           "with error:\n"
   1617           "\t%s\n"
   1618           "However, the preparser succeeded",
   1619           source->ToCString().get(), message_string->ToCString().get());
   1620       CHECK(false);
   1621     }
   1622     // Check that preparser and parser produce the same error.
   1623     if (test_preparser) {
   1624       i::Handle<i::String> preparser_message =
   1625           FormatMessage(log.ErrorMessageData());
   1626       if (!i::String::Equals(message_string, preparser_message)) {
   1627         v8::base::OS::Print(
   1628             "Expected parser and preparser to produce the same error on:\n"
   1629             "\t%s\n"
   1630             "However, found the following error messages\n"
   1631             "\tparser:    %s\n"
   1632             "\tpreparser: %s\n",
   1633             source->ToCString().get(), message_string->ToCString().get(),
   1634             preparser_message->ToCString().get());
   1635         CHECK(false);
   1636       }
   1637     }
   1638   } else if (test_preparser && preparse_error) {
   1639     v8::base::OS::Print(
   1640         "Preparser failed on:\n"
   1641         "\t%s\n"
   1642         "with error:\n"
   1643         "\t%s\n"
   1644         "However, the parser succeeded",
   1645         source->ToCString().get(),
   1646         FormatMessage(log.ErrorMessageData())->ToCString().get());
   1647     CHECK(false);
   1648   } else if (result == kError) {
   1649     v8::base::OS::Print(
   1650         "Expected error on:\n"
   1651         "\t%s\n"
   1652         "However, parser and preparser succeeded",
   1653         source->ToCString().get());
   1654     CHECK(false);
   1655   } else if (test_preparser &&
   1656              preparser_materialized_literals != parser_materialized_literals) {
   1657     v8::base::OS::Print(
   1658         "Preparser materialized literals (%d) differ from Parser materialized "
   1659         "literals (%d) on:\n"
   1660         "\t%s\n"
   1661         "However, parser and preparser succeeded",
   1662         preparser_materialized_literals, parser_materialized_literals,
   1663         source->ToCString().get());
   1664     CHECK(false);
   1665   }
   1666 }
   1667 
   1668 
   1669 void TestParserSync(const char* source, const ParserFlag* varying_flags,
   1670                     size_t varying_flags_length,
   1671                     ParserSyncTestResult result = kSuccessOrError,
   1672                     const ParserFlag* always_true_flags = NULL,
   1673                     size_t always_true_flags_length = 0,
   1674                     const ParserFlag* always_false_flags = NULL,
   1675                     size_t always_false_flags_length = 0,
   1676                     bool is_module = false, bool test_preparser = true) {
   1677   i::Handle<i::String> str =
   1678       CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
   1679   for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
   1680     i::EnumSet<ParserFlag> flags;
   1681     for (size_t flag_index = 0; flag_index < varying_flags_length;
   1682          ++flag_index) {
   1683       if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
   1684     }
   1685     for (size_t flag_index = 0; flag_index < always_true_flags_length;
   1686          ++flag_index) {
   1687       flags.Add(always_true_flags[flag_index]);
   1688     }
   1689     for (size_t flag_index = 0; flag_index < always_false_flags_length;
   1690          ++flag_index) {
   1691       flags.Remove(always_false_flags[flag_index]);
   1692     }
   1693     TestParserSyncWithFlags(str, flags, result, is_module, test_preparser);
   1694   }
   1695 }
   1696 
   1697 
   1698 TEST(ParserSync) {
   1699   const char* context_data[][2] = {
   1700     { "", "" },
   1701     { "{", "}" },
   1702     { "if (true) ", " else {}" },
   1703     { "if (true) {} else ", "" },
   1704     { "if (true) ", "" },
   1705     { "do ", " while (false)" },
   1706     { "while (false) ", "" },
   1707     { "for (;;) ", "" },
   1708     { "with ({})", "" },
   1709     { "switch (12) { case 12: ", "}" },
   1710     { "switch (12) { default: ", "}" },
   1711     { "switch (12) { ", "case 12: }" },
   1712     { "label2: ", "" },
   1713     { NULL, NULL }
   1714   };
   1715 
   1716   const char* statement_data[] = {
   1717     "{}",
   1718     "var x",
   1719     "var x = 1",
   1720     "const x",
   1721     "const x = 1",
   1722     ";",
   1723     "12",
   1724     "if (false) {} else ;",
   1725     "if (false) {} else {}",
   1726     "if (false) {} else 12",
   1727     "if (false) ;",
   1728     "if (false) {}",
   1729     "if (false) 12",
   1730     "do {} while (false)",
   1731     "for (;;) ;",
   1732     "for (;;) {}",
   1733     "for (;;) 12",
   1734     "continue",
   1735     "continue label",
   1736     "continue\nlabel",
   1737     "break",
   1738     "break label",
   1739     "break\nlabel",
   1740     // TODO(marja): activate once parsing 'return' is merged into ParserBase.
   1741     // "return",
   1742     // "return  12",
   1743     // "return\n12",
   1744     "with ({}) ;",
   1745     "with ({}) {}",
   1746     "with ({}) 12",
   1747     "switch ({}) { default: }",
   1748     "label3: ",
   1749     "throw",
   1750     "throw  12",
   1751     "throw\n12",
   1752     "try {} catch(e) {}",
   1753     "try {} finally {}",
   1754     "try {} catch(e) {} finally {}",
   1755     "debugger",
   1756     NULL
   1757   };
   1758 
   1759   const char* termination_data[] = {
   1760     "",
   1761     ";",
   1762     "\n",
   1763     ";\n",
   1764     "\n;",
   1765     NULL
   1766   };
   1767 
   1768   v8::HandleScope handles(CcTest::isolate());
   1769   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   1770   v8::Context::Scope context_scope(context);
   1771 
   1772   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1773       i::GetCurrentStackPosition() - 128 * 1024);
   1774 
   1775   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1776     for (int j = 0; statement_data[j] != NULL; ++j) {
   1777       for (int k = 0; termination_data[k] != NULL; ++k) {
   1778         int kPrefixLen = i::StrLength(context_data[i][0]);
   1779         int kStatementLen = i::StrLength(statement_data[j]);
   1780         int kTerminationLen = i::StrLength(termination_data[k]);
   1781         int kSuffixLen = i::StrLength(context_data[i][1]);
   1782         int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
   1783             + kSuffixLen + i::StrLength("label: for (;;) {  }");
   1784 
   1785         // Plug the source code pieces together.
   1786         i::ScopedVector<char> program(kProgramSize + 1);
   1787         int length = i::SNPrintF(program,
   1788             "label: for (;;) { %s%s%s%s }",
   1789             context_data[i][0],
   1790             statement_data[j],
   1791             termination_data[k],
   1792             context_data[i][1]);
   1793         CHECK(length == kProgramSize);
   1794         TestParserSync(program.start(), NULL, 0);
   1795       }
   1796     }
   1797   }
   1798 
   1799   // Neither Harmony numeric literals nor our natives syntax have any
   1800   // interaction with the flags above, so test these separately to reduce
   1801   // the combinatorial explosion.
   1802   TestParserSync("0o1234", NULL, 0);
   1803   TestParserSync("0b1011", NULL, 0);
   1804 
   1805   static const ParserFlag flags3[] = { kAllowNatives };
   1806   TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3));
   1807 }
   1808 
   1809 
   1810 TEST(StrictOctal) {
   1811   // Test that syntax error caused by octal literal is reported correctly as
   1812   // such (issue 2220).
   1813   v8::V8::Initialize();
   1814   v8::HandleScope scope(CcTest::isolate());
   1815   v8::Context::Scope context_scope(
   1816       v8::Context::New(CcTest::isolate()));
   1817   v8::TryCatch try_catch(CcTest::isolate());
   1818   const char* script =
   1819       "\"use strict\";       \n"
   1820       "a = function() {      \n"
   1821       "  b = function() {    \n"
   1822       "    01;               \n"
   1823       "  };                  \n"
   1824       "};                    \n";
   1825   v8_compile(v8_str(script));
   1826   CHECK(try_catch.HasCaught());
   1827   v8::String::Utf8Value exception(try_catch.Exception());
   1828   CHECK_EQ(0,
   1829            strcmp("SyntaxError: Octal literals are not allowed in strict mode.",
   1830                   *exception));
   1831 }
   1832 
   1833 
   1834 void RunParserSyncTest(const char* context_data[][2],
   1835                        const char* statement_data[],
   1836                        ParserSyncTestResult result,
   1837                        const ParserFlag* flags = NULL, int flags_len = 0,
   1838                        const ParserFlag* always_true_flags = NULL,
   1839                        int always_true_len = 0,
   1840                        const ParserFlag* always_false_flags = NULL,
   1841                        int always_false_len = 0, bool is_module = false,
   1842                        bool test_preparser = true) {
   1843   v8::HandleScope handles(CcTest::isolate());
   1844   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   1845   v8::Context::Scope context_scope(context);
   1846 
   1847   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1848       i::GetCurrentStackPosition() - 128 * 1024);
   1849 
   1850   // Experimental feature flags should not go here; pass the flags as
   1851   // always_true_flags if the test needs them.
   1852   static const ParserFlag default_flags[] = {
   1853     kAllowLazy,
   1854     kAllowNatives,
   1855   };
   1856   ParserFlag* generated_flags = NULL;
   1857   if (flags == NULL) {
   1858     flags = default_flags;
   1859     flags_len = arraysize(default_flags);
   1860     if (always_true_flags != NULL || always_false_flags != NULL) {
   1861       // Remove always_true/false_flags from default_flags (if present).
   1862       CHECK((always_true_flags != NULL) == (always_true_len > 0));
   1863       CHECK((always_false_flags != NULL) == (always_false_len > 0));
   1864       generated_flags = new ParserFlag[flags_len + always_true_len];
   1865       int flag_index = 0;
   1866       for (int i = 0; i < flags_len; ++i) {
   1867         bool use_flag = true;
   1868         for (int j = 0; use_flag && j < always_true_len; ++j) {
   1869           if (flags[i] == always_true_flags[j]) use_flag = false;
   1870         }
   1871         for (int j = 0; use_flag && j < always_false_len; ++j) {
   1872           if (flags[i] == always_false_flags[j]) use_flag = false;
   1873         }
   1874         if (use_flag) generated_flags[flag_index++] = flags[i];
   1875       }
   1876       flags_len = flag_index;
   1877       flags = generated_flags;
   1878     }
   1879   }
   1880   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1881     for (int j = 0; statement_data[j] != NULL; ++j) {
   1882       int kPrefixLen = i::StrLength(context_data[i][0]);
   1883       int kStatementLen = i::StrLength(statement_data[j]);
   1884       int kSuffixLen = i::StrLength(context_data[i][1]);
   1885       int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
   1886 
   1887       // Plug the source code pieces together.
   1888       i::ScopedVector<char> program(kProgramSize + 1);
   1889       int length = i::SNPrintF(program,
   1890                                "%s%s%s",
   1891                                context_data[i][0],
   1892                                statement_data[j],
   1893                                context_data[i][1]);
   1894       CHECK(length == kProgramSize);
   1895       TestParserSync(program.start(), flags, flags_len, result,
   1896                      always_true_flags, always_true_len, always_false_flags,
   1897                      always_false_len, is_module, test_preparser);
   1898     }
   1899   }
   1900   delete[] generated_flags;
   1901 }
   1902 
   1903 
   1904 void RunModuleParserSyncTest(const char* context_data[][2],
   1905                              const char* statement_data[],
   1906                              ParserSyncTestResult result,
   1907                              const ParserFlag* flags = NULL, int flags_len = 0,
   1908                              const ParserFlag* always_true_flags = NULL,
   1909                              int always_true_len = 0,
   1910                              const ParserFlag* always_false_flags = NULL,
   1911                              int always_false_len = 0,
   1912                              bool test_preparser = true) {
   1913   RunParserSyncTest(context_data, statement_data, result, flags, flags_len,
   1914                     always_true_flags, always_true_len, always_false_flags,
   1915                     always_false_len, true, test_preparser);
   1916 }
   1917 
   1918 
   1919 TEST(ErrorsEvalAndArguments) {
   1920   // Tests that both preparsing and parsing produce the right kind of errors for
   1921   // using "eval" and "arguments" as identifiers. Without the strict mode, it's
   1922   // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
   1923   // isn't.
   1924   const char* context_data[][2] = {
   1925       {"\"use strict\";", ""},
   1926       {"var eval; function test_func() {\"use strict\"; ", "}"},
   1927       {NULL, NULL}};
   1928 
   1929   const char* statement_data[] = {
   1930     "var eval;",
   1931     "var arguments",
   1932     "var foo, eval;",
   1933     "var foo, arguments;",
   1934     "try { } catch (eval) { }",
   1935     "try { } catch (arguments) { }",
   1936     "function eval() { }",
   1937     "function arguments() { }",
   1938     "function foo(eval) { }",
   1939     "function foo(arguments) { }",
   1940     "function foo(bar, eval) { }",
   1941     "function foo(bar, arguments) { }",
   1942     "(eval) => { }",
   1943     "(arguments) => { }",
   1944     "(foo, eval) => { }",
   1945     "(foo, arguments) => { }",
   1946     "eval = 1;",
   1947     "arguments = 1;",
   1948     "var foo = eval = 1;",
   1949     "var foo = arguments = 1;",
   1950     "++eval;",
   1951     "++arguments;",
   1952     "eval++;",
   1953     "arguments++;",
   1954     NULL
   1955   };
   1956 
   1957   RunParserSyncTest(context_data, statement_data, kError);
   1958 }
   1959 
   1960 
   1961 TEST(NoErrorsEvalAndArgumentsSloppy) {
   1962   // Tests that both preparsing and parsing accept "eval" and "arguments" as
   1963   // identifiers when needed.
   1964   const char* context_data[][2] = {
   1965     { "", "" },
   1966     { "function test_func() {", "}"},
   1967     { NULL, NULL }
   1968   };
   1969 
   1970   const char* statement_data[] = {
   1971     "var eval;",
   1972     "var arguments",
   1973     "var foo, eval;",
   1974     "var foo, arguments;",
   1975     "try { } catch (eval) { }",
   1976     "try { } catch (arguments) { }",
   1977     "function eval() { }",
   1978     "function arguments() { }",
   1979     "function foo(eval) { }",
   1980     "function foo(arguments) { }",
   1981     "function foo(bar, eval) { }",
   1982     "function foo(bar, arguments) { }",
   1983     "eval = 1;",
   1984     "arguments = 1;",
   1985     "var foo = eval = 1;",
   1986     "var foo = arguments = 1;",
   1987     "++eval;",
   1988     "++arguments;",
   1989     "eval++;",
   1990     "arguments++;",
   1991     NULL
   1992   };
   1993 
   1994   RunParserSyncTest(context_data, statement_data, kSuccess);
   1995 }
   1996 
   1997 
   1998 TEST(NoErrorsEvalAndArgumentsStrict) {
   1999   const char* context_data[][2] = {
   2000     { "\"use strict\";", "" },
   2001     { "function test_func() { \"use strict\";", "}" },
   2002     { "() => { \"use strict\"; ", "}" },
   2003     { NULL, NULL }
   2004   };
   2005 
   2006   const char* statement_data[] = {
   2007     "eval;",
   2008     "arguments;",
   2009     "var foo = eval;",
   2010     "var foo = arguments;",
   2011     "var foo = { eval: 1 };",
   2012     "var foo = { arguments: 1 };",
   2013     "var foo = { }; foo.eval = {};",
   2014     "var foo = { }; foo.arguments = {};",
   2015     NULL
   2016   };
   2017 
   2018   RunParserSyncTest(context_data, statement_data, kSuccess);
   2019 }
   2020 
   2021 #define FUTURE_STRICT_RESERVED_WORDS_NO_LET(V) \
   2022   V(implements)                                \
   2023   V(interface)                                 \
   2024   V(package)                                   \
   2025   V(private)                                   \
   2026   V(protected)                                 \
   2027   V(public)                                    \
   2028   V(static)                                    \
   2029   V(yield)
   2030 
   2031 #define FUTURE_STRICT_RESERVED_WORDS(V) \
   2032   V(let)                                \
   2033   FUTURE_STRICT_RESERVED_WORDS_NO_LET(V)
   2034 
   2035 #define LIMITED_FUTURE_STRICT_RESERVED_WORDS_NO_LET(V) \
   2036   V(implements)                                        \
   2037   V(static)                                            \
   2038   V(yield)
   2039 
   2040 #define LIMITED_FUTURE_STRICT_RESERVED_WORDS(V) \
   2041   V(let)                                        \
   2042   LIMITED_FUTURE_STRICT_RESERVED_WORDS_NO_LET(V)
   2043 
   2044 #define FUTURE_STRICT_RESERVED_STATEMENTS(NAME) \
   2045   "var " #NAME ";",                             \
   2046   "var foo, " #NAME ";",                        \
   2047   "try { } catch (" #NAME ") { }",              \
   2048   "function " #NAME "() { }",                   \
   2049   "(function " #NAME "() { })",                 \
   2050   "function foo(" #NAME ") { }",                \
   2051   "function foo(bar, " #NAME ") { }",           \
   2052   #NAME " = 1;",                                \
   2053   #NAME " += 1;",                               \
   2054   "var foo = " #NAME " = 1;",                   \
   2055   "++" #NAME ";",                               \
   2056   #NAME " ++;",
   2057 
   2058 // clang-format off
   2059 #define FUTURE_STRICT_RESERVED_LEX_BINDINGS(NAME) \
   2060   "let " #NAME ";",                               \
   2061   "for (let " #NAME "; false; ) {}",              \
   2062   "for (let " #NAME " in {}) {}",                 \
   2063   "for (let " #NAME " of []) {}",                 \
   2064   "const " #NAME " = null;",                      \
   2065   "for (const " #NAME " = null; false; ) {}",     \
   2066   "for (const " #NAME " in {}) {}",               \
   2067   "for (const " #NAME " of []) {}",
   2068 // clang-format on
   2069 
   2070 TEST(ErrorsFutureStrictReservedWords) {
   2071   // Tests that both preparsing and parsing produce the right kind of errors for
   2072   // using future strict reserved words as identifiers. Without the strict mode,
   2073   // it's ok to use future strict reserved words as identifiers. With the strict
   2074   // mode, it isn't.
   2075   const char* strict_contexts[][2] = {
   2076       {"function test_func() {\"use strict\"; ", "}"},
   2077       {"() => { \"use strict\"; ", "}"},
   2078       {NULL, NULL}};
   2079 
   2080   // clang-format off
   2081   const char* statement_data[] {
   2082     LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
   2083     LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_LEX_BINDINGS)
   2084     NULL
   2085   };
   2086   // clang-format on
   2087 
   2088   RunParserSyncTest(strict_contexts, statement_data, kError);
   2089 
   2090   // From ES2015, 13.3.1.1 Static Semantics: Early Errors:
   2091   //
   2092   // > LexicalDeclaration : LetOrConst BindingList ;
   2093   // >
   2094   // > - It is a Syntax Error if the BoundNames of BindingList contains "let".
   2095   const char* non_strict_contexts[][2] = {{"", ""},
   2096                                           {"function test_func() {", "}"},
   2097                                           {"() => {", "}"},
   2098                                           {NULL, NULL}};
   2099   const char* invalid_statements[] = {FUTURE_STRICT_RESERVED_LEX_BINDINGS("let")
   2100                                           NULL};
   2101 
   2102   RunParserSyncTest(non_strict_contexts, invalid_statements, kError);
   2103 }
   2104 
   2105 #undef LIMITED_FUTURE_STRICT_RESERVED_WORDS
   2106 
   2107 
   2108 TEST(NoErrorsFutureStrictReservedWords) {
   2109   const char* context_data[][2] = {
   2110     { "", "" },
   2111     { "function test_func() {", "}"},
   2112     { "() => {", "}" },
   2113     { NULL, NULL }
   2114   };
   2115 
   2116   // clang-format off
   2117   const char* statement_data[] = {
   2118     FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
   2119     FUTURE_STRICT_RESERVED_WORDS_NO_LET(FUTURE_STRICT_RESERVED_LEX_BINDINGS)
   2120     NULL
   2121   };
   2122   // clang-format on
   2123 
   2124   RunParserSyncTest(context_data, statement_data, kSuccess);
   2125 }
   2126 
   2127 
   2128 TEST(ErrorsReservedWords) {
   2129   // Tests that both preparsing and parsing produce the right kind of errors for
   2130   // using future reserved words as identifiers. These tests don't depend on the
   2131   // strict mode.
   2132   const char* context_data[][2] = {
   2133     { "", "" },
   2134     { "\"use strict\";", "" },
   2135     { "var eval; function test_func() {", "}"},
   2136     { "var eval; function test_func() {\"use strict\"; ", "}"},
   2137     { "var eval; () => {", "}"},
   2138     { "var eval; () => {\"use strict\"; ", "}"},
   2139     { NULL, NULL }
   2140   };
   2141 
   2142   const char* statement_data[] = {
   2143     "var super;",
   2144     "var foo, super;",
   2145     "try { } catch (super) { }",
   2146     "function super() { }",
   2147     "function foo(super) { }",
   2148     "function foo(bar, super) { }",
   2149     "(super) => { }",
   2150     "(bar, super) => { }",
   2151     "super = 1;",
   2152     "var foo = super = 1;",
   2153     "++super;",
   2154     "super++;",
   2155     "function foo super",
   2156     NULL
   2157   };
   2158 
   2159   RunParserSyncTest(context_data, statement_data, kError);
   2160 }
   2161 
   2162 
   2163 TEST(NoErrorsLetSloppyAllModes) {
   2164   // In sloppy mode, it's okay to use "let" as identifier.
   2165   const char* context_data[][2] = {
   2166     { "", "" },
   2167     { "function f() {", "}" },
   2168     { "(function f() {", "})" },
   2169     { NULL, NULL }
   2170   };
   2171 
   2172   const char* statement_data[] = {
   2173     "var let;",
   2174     "var foo, let;",
   2175     "try { } catch (let) { }",
   2176     "function let() { }",
   2177     "(function let() { })",
   2178     "function foo(let) { }",
   2179     "function foo(bar, let) { }",
   2180     "let = 1;",
   2181     "var foo = let = 1;",
   2182     "let * 2;",
   2183     "++let;",
   2184     "let++;",
   2185     "let: 34",
   2186     "function let(let) { let: let(let + let(0)); }",
   2187     "({ let: 1 })",
   2188     "({ get let() { 1 } })",
   2189     "let(100)",
   2190     NULL
   2191   };
   2192 
   2193   RunParserSyncTest(context_data, statement_data, kSuccess);
   2194 }
   2195 
   2196 
   2197 TEST(NoErrorsYieldSloppyAllModes) {
   2198   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
   2199   // generator (see other test).
   2200   const char* context_data[][2] = {
   2201     { "", "" },
   2202     { "function not_gen() {", "}" },
   2203     { "(function not_gen() {", "})" },
   2204     { NULL, NULL }
   2205   };
   2206 
   2207   const char* statement_data[] = {
   2208     "var yield;",
   2209     "var foo, yield;",
   2210     "try { } catch (yield) { }",
   2211     "function yield() { }",
   2212     "(function yield() { })",
   2213     "function foo(yield) { }",
   2214     "function foo(bar, yield) { }",
   2215     "yield = 1;",
   2216     "var foo = yield = 1;",
   2217     "yield * 2;",
   2218     "++yield;",
   2219     "yield++;",
   2220     "yield: 34",
   2221     "function yield(yield) { yield: yield (yield + yield(0)); }",
   2222     "({ yield: 1 })",
   2223     "({ get yield() { 1 } })",
   2224     "yield(100)",
   2225     "yield[100]",
   2226     NULL
   2227   };
   2228 
   2229   RunParserSyncTest(context_data, statement_data, kSuccess);
   2230 }
   2231 
   2232 
   2233 TEST(NoErrorsYieldSloppyGeneratorsEnabled) {
   2234   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
   2235   // generator (see next test).
   2236   const char* context_data[][2] = {
   2237     { "", "" },
   2238     { "function not_gen() {", "}" },
   2239     { "function * gen() { function not_gen() {", "} }" },
   2240     { "(function not_gen() {", "})" },
   2241     { "(function * gen() { (function not_gen() {", "}) })" },
   2242     { NULL, NULL }
   2243   };
   2244 
   2245   const char* statement_data[] = {
   2246     "var yield;",
   2247     "var foo, yield;",
   2248     "try { } catch (yield) { }",
   2249     "function yield() { }",
   2250     "(function yield() { })",
   2251     "function foo(yield) { }",
   2252     "function foo(bar, yield) { }",
   2253     "function * yield() { }",
   2254     "yield = 1;",
   2255     "var foo = yield = 1;",
   2256     "yield * 2;",
   2257     "++yield;",
   2258     "yield++;",
   2259     "yield: 34",
   2260     "function yield(yield) { yield: yield (yield + yield(0)); }",
   2261     "({ yield: 1 })",
   2262     "({ get yield() { 1 } })",
   2263     "yield(100)",
   2264     "yield[100]",
   2265     NULL
   2266   };
   2267 
   2268   RunParserSyncTest(context_data, statement_data, kSuccess);
   2269 }
   2270 
   2271 
   2272 TEST(ErrorsYieldStrict) {
   2273   const char* context_data[][2] = {
   2274       {"\"use strict\";", ""},
   2275       {"\"use strict\"; function not_gen() {", "}"},
   2276       {"function test_func() {\"use strict\"; ", "}"},
   2277       {"\"use strict\"; function * gen() { function not_gen() {", "} }"},
   2278       {"\"use strict\"; (function not_gen() {", "})"},
   2279       {"\"use strict\"; (function * gen() { (function not_gen() {", "}) })"},
   2280       {"() => {\"use strict\"; ", "}"},
   2281       {NULL, NULL}};
   2282 
   2283   const char* statement_data[] = {
   2284     "var yield;",
   2285     "var foo, yield;",
   2286     "try { } catch (yield) { }",
   2287     "function yield() { }",
   2288     "(function yield() { })",
   2289     "function foo(yield) { }",
   2290     "function foo(bar, yield) { }",
   2291     "function * yield() { }",
   2292     "(function * yield() { })",
   2293     "yield = 1;",
   2294     "var foo = yield = 1;",
   2295     "++yield;",
   2296     "yield++;",
   2297     "yield: 34;",
   2298     NULL
   2299   };
   2300 
   2301   RunParserSyncTest(context_data, statement_data, kError);
   2302 }
   2303 
   2304 
   2305 TEST(ErrorsYieldSloppy) {
   2306   const char* context_data[][2] = {
   2307     { "", "" },
   2308     { "function not_gen() {", "}" },
   2309     { "(function not_gen() {", "})" },
   2310     { NULL, NULL }
   2311   };
   2312 
   2313   const char* statement_data[] = {
   2314     "(function * yield() { })",
   2315     NULL
   2316   };
   2317 
   2318   RunParserSyncTest(context_data, statement_data, kError);
   2319 }
   2320 
   2321 
   2322 TEST(NoErrorsGenerator) {
   2323   // clang-format off
   2324   const char* context_data[][2] = {
   2325     { "function * gen() {", "}" },
   2326     { "(function * gen() {", "})" },
   2327     { "(function * () {", "})" },
   2328     { NULL, NULL }
   2329   };
   2330 
   2331   const char* statement_data[] = {
   2332     // A generator without a body is valid.
   2333     ""
   2334     // Valid yield expressions inside generators.
   2335     "yield 2;",
   2336     "yield * 2;",
   2337     "yield * \n 2;",
   2338     "yield yield 1;",
   2339     "yield * yield * 1;",
   2340     "yield 3 + (yield 4);",
   2341     "yield * 3 + (yield * 4);",
   2342     "(yield * 3) + (yield * 4);",
   2343     "yield 3; yield 4;",
   2344     "yield * 3; yield * 4;",
   2345     "(function (yield) { })",
   2346     "(function yield() { })",
   2347     "yield { yield: 12 }",
   2348     "yield /* comment */ { yield: 12 }",
   2349     "yield * \n { yield: 12 }",
   2350     "yield /* comment */ * \n { yield: 12 }",
   2351     // You can return in a generator.
   2352     "yield 1; return",
   2353     "yield * 1; return",
   2354     "yield 1; return 37",
   2355     "yield * 1; return 37",
   2356     "yield 1; return 37; yield 'dead';",
   2357     "yield * 1; return 37; yield * 'dead';",
   2358     // Yield is still a valid key in object literals.
   2359     "({ yield: 1 })",
   2360     "({ get yield() { } })",
   2361     // And in assignment pattern computed properties
   2362     "({ [yield]: x } = { })",
   2363     // Yield without RHS.
   2364     "yield;",
   2365     "yield",
   2366     "yield\n",
   2367     "yield /* comment */"
   2368     "yield // comment\n"
   2369     "(yield)",
   2370     "[yield]",
   2371     "{yield}",
   2372     "yield, yield",
   2373     "yield; yield",
   2374     "(yield) ? yield : yield",
   2375     "(yield) \n ? yield : yield",
   2376     // If there is a newline before the next token, we don't look for RHS.
   2377     "yield\nfor (;;) {}",
   2378     "x = class extends (yield) {}",
   2379     "x = class extends f(yield) {}",
   2380     "x = class extends (null, yield) { }",
   2381     "x = class extends (a ? null : yield) { }",
   2382     NULL
   2383   };
   2384   // clang-format on
   2385 
   2386   RunParserSyncTest(context_data, statement_data, kSuccess);
   2387 }
   2388 
   2389 
   2390 TEST(ErrorsYieldGenerator) {
   2391   // clang-format off
   2392   const char* context_data[][2] = {
   2393     { "function * gen() {", "}" },
   2394     { "\"use strict\"; function * gen() {", "}" },
   2395     { NULL, NULL }
   2396   };
   2397 
   2398   const char* statement_data[] = {
   2399     // Invalid yield expressions inside generators.
   2400     "var yield;",
   2401     "var foo, yield;",
   2402     "try { } catch (yield) { }",
   2403     "function yield() { }",
   2404     // The name of the NFE is bound in the generator, which does not permit
   2405     // yield to be an identifier.
   2406     "(function * yield() { })",
   2407     // Yield isn't valid as a formal parameter for generators.
   2408     "function * foo(yield) { }",
   2409     "(function * foo(yield) { })",
   2410     "yield = 1;",
   2411     "var foo = yield = 1;",
   2412     "++yield;",
   2413     "yield++;",
   2414     "yield *",
   2415     "(yield *)",
   2416     // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
   2417     // is invalid.
   2418     "yield 3 + yield 4;",
   2419     "yield: 34",
   2420     "yield ? 1 : 2",
   2421     // Parses as yield (/ yield): invalid.
   2422     "yield / yield",
   2423     "+ yield",
   2424     "+ yield 3",
   2425     // Invalid (no newline allowed between yield and *).
   2426     "yield\n*3",
   2427     // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
   2428     // object literal, and yield is not a valid label).
   2429     "yield\n{yield: 42}",
   2430     "yield /* comment */\n {yield: 42}",
   2431     "yield //comment\n {yield: 42}",
   2432     // Destructuring binding and assignment are both disallowed
   2433     "var [yield] = [42];",
   2434     "var {foo: yield} = {a: 42};",
   2435     "[yield] = [42];",
   2436     "({a: yield} = {a: 42});",
   2437     // Also disallow full yield expressions on LHS
   2438     "var [yield 24] = [42];",
   2439     "var {foo: yield 24} = {a: 42};",
   2440     "[yield 24] = [42];",
   2441     "({a: yield 24} = {a: 42});",
   2442     "for (yield 'x' in {});",
   2443     "for (yield 'x' of {});",
   2444     "for (yield 'x' in {} in {});",
   2445     "for (yield 'x' in {} of {});",
   2446     "class C extends yield { }",
   2447     NULL
   2448   };
   2449   // clang-format on
   2450 
   2451   RunParserSyncTest(context_data, statement_data, kError);
   2452 }
   2453 
   2454 
   2455 TEST(ErrorsNameOfStrictFunction) {
   2456   // Tests that illegal tokens as names of a strict function produce the correct
   2457   // errors.
   2458   const char* context_data[][2] = {
   2459     { "function ", ""},
   2460     { "\"use strict\"; function", ""},
   2461     { "function * ", ""},
   2462     { "\"use strict\"; function * ", ""},
   2463     { NULL, NULL }
   2464   };
   2465 
   2466   const char* statement_data[] = {
   2467     "eval() {\"use strict\";}",
   2468     "arguments() {\"use strict\";}",
   2469     "interface() {\"use strict\";}",
   2470     "yield() {\"use strict\";}",
   2471     // Future reserved words are always illegal
   2472     "super() { }",
   2473     "super() {\"use strict\";}",
   2474     NULL
   2475   };
   2476 
   2477   RunParserSyncTest(context_data, statement_data, kError);
   2478 }
   2479 
   2480 
   2481 TEST(NoErrorsNameOfStrictFunction) {
   2482   const char* context_data[][2] = {
   2483     { "function ", ""},
   2484     { NULL, NULL }
   2485   };
   2486 
   2487   const char* statement_data[] = {
   2488     "eval() { }",
   2489     "arguments() { }",
   2490     "interface() { }",
   2491     "yield() { }",
   2492     NULL
   2493   };
   2494 
   2495   RunParserSyncTest(context_data, statement_data, kSuccess);
   2496 }
   2497 
   2498 
   2499 TEST(NoErrorsNameOfStrictGenerator) {
   2500   const char* context_data[][2] = {
   2501     { "function * ", ""},
   2502     { NULL, NULL }
   2503   };
   2504 
   2505   const char* statement_data[] = {
   2506     "eval() { }",
   2507     "arguments() { }",
   2508     "interface() { }",
   2509     "yield() { }",
   2510     NULL
   2511   };
   2512 
   2513   RunParserSyncTest(context_data, statement_data, kSuccess);
   2514 }
   2515 
   2516 
   2517 TEST(ErrorsIllegalWordsAsLabelsSloppy) {
   2518   // Using future reserved words as labels is always an error.
   2519   const char* context_data[][2] = {
   2520     { "", ""},
   2521     { "function test_func() {", "}" },
   2522     { "() => {", "}" },
   2523     { NULL, NULL }
   2524   };
   2525 
   2526   const char* statement_data[] = {
   2527     "super: while(true) { break super; }",
   2528     NULL
   2529   };
   2530 
   2531   RunParserSyncTest(context_data, statement_data, kError);
   2532 }
   2533 
   2534 
   2535 TEST(ErrorsIllegalWordsAsLabelsStrict) {
   2536   // Tests that illegal tokens as labels produce the correct errors.
   2537   const char* context_data[][2] = {
   2538       {"\"use strict\";", ""},
   2539       {"function test_func() {\"use strict\"; ", "}"},
   2540       {"() => {\"use strict\"; ", "}"},
   2541       {NULL, NULL}};
   2542 
   2543 #define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
   2544   const char* statement_data[] = {
   2545     "super: while(true) { break super; }",
   2546     FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE)
   2547     NULL
   2548   };
   2549 #undef LABELLED_WHILE
   2550 
   2551   RunParserSyncTest(context_data, statement_data, kError);
   2552 }
   2553 
   2554 
   2555 TEST(NoErrorsIllegalWordsAsLabels) {
   2556   // Using eval and arguments as labels is legal even in strict mode.
   2557   const char* context_data[][2] = {
   2558     { "", ""},
   2559     { "function test_func() {", "}" },
   2560     { "() => {", "}" },
   2561     { "\"use strict\";", "" },
   2562     { "\"use strict\"; function test_func() {", "}" },
   2563     { "\"use strict\"; () => {", "}" },
   2564     { NULL, NULL }
   2565   };
   2566 
   2567   const char* statement_data[] = {
   2568     "mylabel: while(true) { break mylabel; }",
   2569     "eval: while(true) { break eval; }",
   2570     "arguments: while(true) { break arguments; }",
   2571     NULL
   2572   };
   2573 
   2574   RunParserSyncTest(context_data, statement_data, kSuccess);
   2575 }
   2576 
   2577 
   2578 TEST(NoErrorsFutureStrictReservedAsLabelsSloppy) {
   2579   const char* context_data[][2] = {
   2580     { "", ""},
   2581     { "function test_func() {", "}" },
   2582     { "() => {", "}" },
   2583     { NULL, NULL }
   2584   };
   2585 
   2586 #define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
   2587   const char* statement_data[] {
   2588     FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE)
   2589     NULL
   2590   };
   2591 #undef LABELLED_WHILE
   2592 
   2593   RunParserSyncTest(context_data, statement_data, kSuccess);
   2594 }
   2595 
   2596 
   2597 TEST(ErrorsParenthesizedLabels) {
   2598   // Parenthesized identifiers shouldn't be recognized as labels.
   2599   const char* context_data[][2] = {
   2600     { "", ""},
   2601     { "function test_func() {", "}" },
   2602     { "() => {", "}" },
   2603     { NULL, NULL }
   2604   };
   2605 
   2606   const char* statement_data[] = {
   2607     "(mylabel): while(true) { break mylabel; }",
   2608     NULL
   2609   };
   2610 
   2611   RunParserSyncTest(context_data, statement_data, kError);
   2612 }
   2613 
   2614 
   2615 TEST(NoErrorsParenthesizedDirectivePrologue) {
   2616   // Parenthesized directive prologue shouldn't be recognized.
   2617   const char* context_data[][2] = {
   2618     { "", ""},
   2619     { NULL, NULL }
   2620   };
   2621 
   2622   const char* statement_data[] = {
   2623     "(\"use strict\"); var eval;",
   2624     NULL
   2625   };
   2626 
   2627   RunParserSyncTest(context_data, statement_data, kSuccess);
   2628 }
   2629 
   2630 
   2631 TEST(ErrorsNotAnIdentifierName) {
   2632   const char* context_data[][2] = {
   2633     { "", ""},
   2634     { "\"use strict\";", ""},
   2635     { NULL, NULL }
   2636   };
   2637 
   2638   const char* statement_data[] = {
   2639     "var foo = {}; foo.{;",
   2640     "var foo = {}; foo.};",
   2641     "var foo = {}; foo.=;",
   2642     "var foo = {}; foo.888;",
   2643     "var foo = {}; foo.-;",
   2644     "var foo = {}; foo.--;",
   2645     NULL
   2646   };
   2647 
   2648   RunParserSyncTest(context_data, statement_data, kError);
   2649 }
   2650 
   2651 
   2652 TEST(NoErrorsIdentifierNames) {
   2653   // Keywords etc. are valid as property names.
   2654   const char* context_data[][2] = {
   2655     { "", ""},
   2656     { "\"use strict\";", ""},
   2657     { NULL, NULL }
   2658   };
   2659 
   2660   const char* statement_data[] = {
   2661     "var foo = {}; foo.if;",
   2662     "var foo = {}; foo.yield;",
   2663     "var foo = {}; foo.super;",
   2664     "var foo = {}; foo.interface;",
   2665     "var foo = {}; foo.eval;",
   2666     "var foo = {}; foo.arguments;",
   2667     NULL
   2668   };
   2669 
   2670   RunParserSyncTest(context_data, statement_data, kSuccess);
   2671 }
   2672 
   2673 
   2674 TEST(DontRegressPreParserDataSizes) {
   2675   // These tests make sure that Parser doesn't start producing less "preparse
   2676   // data" (data which the embedder can cache).
   2677   v8::V8::Initialize();
   2678   v8::Isolate* isolate = CcTest::isolate();
   2679   v8::HandleScope handles(isolate);
   2680 
   2681   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   2682       i::GetCurrentStackPosition() - 128 * 1024);
   2683 
   2684   struct TestCase {
   2685     const char* program;
   2686     int functions;
   2687   } test_cases[] = {
   2688     // No functions.
   2689     {"var x = 42;", 0},
   2690     // Functions.
   2691     {"function foo() {}", 1},
   2692     {"function foo() {} function bar() {}", 2},
   2693     // Getter / setter functions are recorded as functions if they're on the top
   2694     // level.
   2695     {"var x = {get foo(){} };", 1},
   2696     // Functions insize lazy functions are not recorded.
   2697     {"function lazy() { function a() {} function b() {} function c() {} }", 1},
   2698     {"function lazy() { var x = {get foo(){} } }", 1},
   2699     {NULL, 0}
   2700   };
   2701 
   2702   for (int i = 0; test_cases[i].program; i++) {
   2703     const char* program = test_cases[i].program;
   2704     i::Factory* factory = CcTest::i_isolate()->factory();
   2705     i::Handle<i::String> source =
   2706         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   2707     i::Handle<i::Script> script = factory->NewScript(source);
   2708     i::Zone zone(CcTest::i_isolate()->allocator());
   2709     i::ParseInfo info(&zone, script);
   2710     i::ScriptData* sd = NULL;
   2711     info.set_cached_data(&sd);
   2712     info.set_compile_options(v8::ScriptCompiler::kProduceParserCache);
   2713     info.set_allow_lazy_parsing();
   2714     i::Parser::ParseStatic(&info);
   2715     i::ParseData* pd = i::ParseData::FromCachedData(sd);
   2716 
   2717     if (pd->FunctionCount() != test_cases[i].functions) {
   2718       v8::base::OS::Print(
   2719           "Expected preparse data for program:\n"
   2720           "\t%s\n"
   2721           "to contain %d functions, however, received %d functions.\n",
   2722           program, test_cases[i].functions, pd->FunctionCount());
   2723       CHECK(false);
   2724     }
   2725     delete sd;
   2726     delete pd;
   2727   }
   2728 }
   2729 
   2730 
   2731 TEST(FunctionDeclaresItselfStrict) {
   2732   // Tests that we produce the right kinds of errors when a function declares
   2733   // itself strict (we cannot produce there errors as soon as we see the
   2734   // offending identifiers, because we don't know at that point whether the
   2735   // function is strict or not).
   2736   const char* context_data[][2] = {
   2737     {"function eval() {", "}"},
   2738     {"function arguments() {", "}"},
   2739     {"function yield() {", "}"},
   2740     {"function interface() {", "}"},
   2741     {"function foo(eval) {", "}"},
   2742     {"function foo(arguments) {", "}"},
   2743     {"function foo(yield) {", "}"},
   2744     {"function foo(interface) {", "}"},
   2745     {"function foo(bar, eval) {", "}"},
   2746     {"function foo(bar, arguments) {", "}"},
   2747     {"function foo(bar, yield) {", "}"},
   2748     {"function foo(bar, interface) {", "}"},
   2749     {"function foo(bar, bar) {", "}"},
   2750     { NULL, NULL }
   2751   };
   2752 
   2753   const char* strict_statement_data[] = {
   2754     "\"use strict\";",
   2755     NULL
   2756   };
   2757 
   2758   const char* non_strict_statement_data[] = {
   2759     ";",
   2760     NULL
   2761   };
   2762 
   2763   RunParserSyncTest(context_data, strict_statement_data, kError);
   2764   RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
   2765 }
   2766 
   2767 
   2768 TEST(ErrorsTryWithoutCatchOrFinally) {
   2769   const char* context_data[][2] = {
   2770     {"", ""},
   2771     { NULL, NULL }
   2772   };
   2773 
   2774   const char* statement_data[] = {
   2775     "try { }",
   2776     "try { } foo();",
   2777     "try { } catch (e) foo();",
   2778     "try { } catch { }",
   2779     "try { } finally foo();",
   2780     NULL
   2781   };
   2782 
   2783   RunParserSyncTest(context_data, statement_data, kError);
   2784 }
   2785 
   2786 
   2787 TEST(NoErrorsTryCatchFinally) {
   2788   const char* context_data[][2] = {
   2789     {"", ""},
   2790     { NULL, NULL }
   2791   };
   2792 
   2793   const char* statement_data[] = {
   2794     "try { } catch (e) { }",
   2795     "try { } catch (e) { } finally { }",
   2796     "try { } finally { }",
   2797     NULL
   2798   };
   2799 
   2800   RunParserSyncTest(context_data, statement_data, kSuccess);
   2801 }
   2802 
   2803 
   2804 TEST(ErrorsRegexpLiteral) {
   2805   const char* context_data[][2] = {
   2806     {"var r = ", ""},
   2807     { NULL, NULL }
   2808   };
   2809 
   2810   const char* statement_data[] = {
   2811     "/unterminated",
   2812     NULL
   2813   };
   2814 
   2815   RunParserSyncTest(context_data, statement_data, kError);
   2816 }
   2817 
   2818 
   2819 TEST(NoErrorsRegexpLiteral) {
   2820   const char* context_data[][2] = {
   2821     {"var r = ", ""},
   2822     { NULL, NULL }
   2823   };
   2824 
   2825   const char* statement_data[] = {
   2826     "/foo/",
   2827     "/foo/g",
   2828     NULL
   2829   };
   2830 
   2831   RunParserSyncTest(context_data, statement_data, kSuccess);
   2832 }
   2833 
   2834 
   2835 TEST(NoErrorsNewExpression) {
   2836   const char* context_data[][2] = {
   2837     {"", ""},
   2838     {"var f =", ""},
   2839     { NULL, NULL }
   2840   };
   2841 
   2842   const char* statement_data[] = {
   2843     "new foo",
   2844     "new foo();",
   2845     "new foo(1);",
   2846     "new foo(1, 2);",
   2847     // The first () will be processed as a part of the NewExpression and the
   2848     // second () will be processed as part of LeftHandSideExpression.
   2849     "new foo()();",
   2850     // The first () will be processed as a part of the inner NewExpression and
   2851     // the second () will be processed as a part of the outer NewExpression.
   2852     "new new foo()();",
   2853     "new foo.bar;",
   2854     "new foo.bar();",
   2855     "new foo.bar.baz;",
   2856     "new foo.bar().baz;",
   2857     "new foo[bar];",
   2858     "new foo[bar]();",
   2859     "new foo[bar][baz];",
   2860     "new foo[bar]()[baz];",
   2861     "new foo[bar].baz(baz)()[bar].baz;",
   2862     "new \"foo\"",  // Runtime error
   2863     "new 1",  // Runtime error
   2864     // This even runs:
   2865     "(new new Function(\"this.x = 1\")).x;",
   2866     "new new Test_Two(String, 2).v(0123).length;",
   2867     NULL
   2868   };
   2869 
   2870   RunParserSyncTest(context_data, statement_data, kSuccess);
   2871 }
   2872 
   2873 
   2874 TEST(ErrorsNewExpression) {
   2875   const char* context_data[][2] = {
   2876     {"", ""},
   2877     {"var f =", ""},
   2878     { NULL, NULL }
   2879   };
   2880 
   2881   const char* statement_data[] = {
   2882     "new foo bar",
   2883     "new ) foo",
   2884     "new ++foo",
   2885     "new foo ++",
   2886     NULL
   2887   };
   2888 
   2889   RunParserSyncTest(context_data, statement_data, kError);
   2890 }
   2891 
   2892 
   2893 TEST(StrictObjectLiteralChecking) {
   2894   const char* context_data[][2] = {
   2895     {"\"use strict\"; var myobject = {", "};"},
   2896     {"\"use strict\"; var myobject = {", ",};"},
   2897     {"var myobject = {", "};"},
   2898     {"var myobject = {", ",};"},
   2899     { NULL, NULL }
   2900   };
   2901 
   2902   // These are only errors in strict mode.
   2903   const char* statement_data[] = {
   2904     "foo: 1, foo: 2",
   2905     "\"foo\": 1, \"foo\": 2",
   2906     "foo: 1, \"foo\": 2",
   2907     "1: 1, 1: 2",
   2908     "1: 1, \"1\": 2",
   2909     "get: 1, get: 2",  // Not a getter for real, just a property called get.
   2910     "set: 1, set: 2",  // Not a setter for real, just a property called set.
   2911     NULL
   2912   };
   2913 
   2914   RunParserSyncTest(context_data, statement_data, kSuccess);
   2915 }
   2916 
   2917 
   2918 TEST(ErrorsObjectLiteralChecking) {
   2919   const char* context_data[][2] = {
   2920     {"\"use strict\"; var myobject = {", "};"},
   2921     {"var myobject = {", "};"},
   2922     { NULL, NULL }
   2923   };
   2924 
   2925   const char* statement_data[] = {
   2926     ",",
   2927     // Wrong number of parameters
   2928     "get bar(x) {}",
   2929     "get bar(x, y) {}",
   2930     "set bar() {}",
   2931     "set bar(x, y) {}",
   2932     // Parsing FunctionLiteral for getter or setter fails
   2933     "get foo( +",
   2934     "get foo() \"error\"",
   2935     NULL
   2936   };
   2937 
   2938   RunParserSyncTest(context_data, statement_data, kError);
   2939 }
   2940 
   2941 
   2942 TEST(NoErrorsObjectLiteralChecking) {
   2943   const char* context_data[][2] = {
   2944     {"var myobject = {", "};"},
   2945     {"var myobject = {", ",};"},
   2946     {"\"use strict\"; var myobject = {", "};"},
   2947     {"\"use strict\"; var myobject = {", ",};"},
   2948     { NULL, NULL }
   2949   };
   2950 
   2951   const char* statement_data[] = {
   2952     "foo: 1, get foo() {}",
   2953     "foo: 1, set foo(v) {}",
   2954     "\"foo\": 1, get \"foo\"() {}",
   2955     "\"foo\": 1, set \"foo\"(v) {}",
   2956     "1: 1, get 1() {}",
   2957     "1: 1, set 1(v) {}",
   2958     "get foo() {}, get foo() {}",
   2959     "set foo(_) {}, set foo(v) {}",
   2960     "foo: 1, get \"foo\"() {}",
   2961     "foo: 1, set \"foo\"(v) {}",
   2962     "\"foo\": 1, get foo() {}",
   2963     "\"foo\": 1, set foo(v) {}",
   2964     "1: 1, get \"1\"() {}",
   2965     "1: 1, set \"1\"(v) {}",
   2966     "\"1\": 1, get 1() {}",
   2967     "\"1\": 1, set 1(v) {}",
   2968     "foo: 1, bar: 2",
   2969     "\"foo\": 1, \"bar\": 2",
   2970     "1: 1, 2: 2",
   2971     // Syntax: IdentifierName ':' AssignmentExpression
   2972     "foo: bar = 5 + baz",
   2973     // Syntax: 'get' PropertyName '(' ')' '{' FunctionBody '}'
   2974     "get foo() {}",
   2975     "get \"foo\"() {}",
   2976     "get 1() {}",
   2977     // Syntax: 'set' PropertyName '(' PropertySetParameterList ')'
   2978     //     '{' FunctionBody '}'
   2979     "set foo(v) {}",
   2980     "set \"foo\"(v) {}",
   2981     "set 1(v) {}",
   2982     // Non-colliding getters and setters -> no errors
   2983     "foo: 1, get bar() {}",
   2984     "foo: 1, set bar(v) {}",
   2985     "\"foo\": 1, get \"bar\"() {}",
   2986     "\"foo\": 1, set \"bar\"(v) {}",
   2987     "1: 1, get 2() {}",
   2988     "1: 1, set 2(v) {}",
   2989     "get: 1, get foo() {}",
   2990     "set: 1, set foo(_) {}",
   2991     // Keywords, future reserved and strict future reserved are also allowed as
   2992     // property names.
   2993     "if: 4",
   2994     "interface: 5",
   2995     "super: 6",
   2996     "eval: 7",
   2997     "arguments: 8",
   2998     NULL
   2999   };
   3000 
   3001   RunParserSyncTest(context_data, statement_data, kSuccess);
   3002 }
   3003 
   3004 
   3005 TEST(TooManyArguments) {
   3006   const char* context_data[][2] = {
   3007     {"foo(", "0)"},
   3008     { NULL, NULL }
   3009   };
   3010 
   3011   using v8::internal::Code;
   3012   char statement[Code::kMaxArguments * 2 + 1];
   3013   for (int i = 0; i < Code::kMaxArguments; ++i) {
   3014     statement[2 * i] = '0';
   3015     statement[2 * i + 1] = ',';
   3016   }
   3017   statement[Code::kMaxArguments * 2] = 0;
   3018 
   3019   const char* statement_data[] = {
   3020     statement,
   3021     NULL
   3022   };
   3023 
   3024   // The test is quite slow, so run it with a reduced set of flags.
   3025   static const ParserFlag empty_flags[] = {kAllowLazy};
   3026   RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
   3027 }
   3028 
   3029 
   3030 TEST(StrictDelete) {
   3031   // "delete <Identifier>" is not allowed in strict mode.
   3032   const char* strict_context_data[][2] = {
   3033     {"\"use strict\"; ", ""},
   3034     { NULL, NULL }
   3035   };
   3036 
   3037   const char* sloppy_context_data[][2] = {
   3038     {"", ""},
   3039     { NULL, NULL }
   3040   };
   3041 
   3042   // These are errors in the strict mode.
   3043   const char* sloppy_statement_data[] = {
   3044     "delete foo;",
   3045     "delete foo + 1;",
   3046     "delete (foo);",
   3047     "delete eval;",
   3048     "delete interface;",
   3049     NULL
   3050   };
   3051 
   3052   // These are always OK
   3053   const char* good_statement_data[] = {
   3054     "delete this;",
   3055     "delete 1;",
   3056     "delete 1 + 2;",
   3057     "delete foo();",
   3058     "delete foo.bar;",
   3059     "delete foo[bar];",
   3060     "delete foo--;",
   3061     "delete --foo;",
   3062     "delete new foo();",
   3063     "delete new foo(bar);",
   3064     NULL
   3065   };
   3066 
   3067   // These are always errors
   3068   const char* bad_statement_data[] = {
   3069     "delete if;",
   3070     NULL
   3071   };
   3072 
   3073   RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
   3074   RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
   3075 
   3076   RunParserSyncTest(strict_context_data, good_statement_data, kSuccess);
   3077   RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess);
   3078 
   3079   RunParserSyncTest(strict_context_data, bad_statement_data, kError);
   3080   RunParserSyncTest(sloppy_context_data, bad_statement_data, kError);
   3081 }
   3082 
   3083 
   3084 TEST(NoErrorsDeclsInCase) {
   3085   const char* context_data[][2] = {
   3086     {"'use strict'; switch(x) { case 1:", "}"},
   3087     {"function foo() {'use strict'; switch(x) { case 1:", "}}"},
   3088     {"'use strict'; switch(x) { case 1: case 2:", "}"},
   3089     {"function foo() {'use strict'; switch(x) { case 1: case 2:", "}}"},
   3090     {"'use strict'; switch(x) { default:", "}"},
   3091     {"function foo() {'use strict'; switch(x) { default:", "}}"},
   3092     {"'use strict'; switch(x) { case 1: default:", "}"},
   3093     {"function foo() {'use strict'; switch(x) { case 1: default:", "}}"},
   3094     { nullptr, nullptr }
   3095   };
   3096 
   3097   const char* statement_data[] = {
   3098     "function f() { }",
   3099     "class C { }",
   3100     "class C extends Q {}",
   3101     "function f() { } class C {}",
   3102     "function f() { }; class C {}",
   3103     "class C {}; function f() {}",
   3104     nullptr
   3105   };
   3106 
   3107   RunParserSyncTest(context_data, statement_data, kSuccess);
   3108 }
   3109 
   3110 
   3111 TEST(InvalidLeftHandSide) {
   3112   const char* assignment_context_data[][2] = {
   3113     {"", " = 1;"},
   3114     {"\"use strict\"; ", " = 1;"},
   3115     { NULL, NULL }
   3116   };
   3117 
   3118   const char* prefix_context_data[][2] = {
   3119     {"++", ";"},
   3120     {"\"use strict\"; ++", ";"},
   3121     {NULL, NULL},
   3122   };
   3123 
   3124   const char* postfix_context_data[][2] = {
   3125     {"", "++;"},
   3126     {"\"use strict\"; ", "++;"},
   3127     { NULL, NULL }
   3128   };
   3129 
   3130   // Good left hand sides for assigment or prefix / postfix operations.
   3131   const char* good_statement_data[] = {
   3132     "foo",
   3133     "foo.bar",
   3134     "foo[bar]",
   3135     "foo()[bar]",
   3136     "foo().bar",
   3137     "this.foo",
   3138     "this[foo]",
   3139     "new foo()[bar]",
   3140     "new foo().bar",
   3141     "foo()",
   3142     "foo(bar)",
   3143     "foo[bar]()",
   3144     "foo.bar()",
   3145     "this()",
   3146     "this.foo()",
   3147     "this[foo].bar()",
   3148     "this.foo[foo].bar(this)(bar)[foo]()",
   3149     NULL
   3150   };
   3151 
   3152   // Bad left hand sides for assigment or prefix / postfix operations.
   3153   const char* bad_statement_data_common[] = {
   3154     "2",
   3155     "new foo",
   3156     "new foo()",
   3157     "null",
   3158     "if",  // Unexpected token
   3159     "{x: 1}",  // Unexpected token
   3160     "this",
   3161     "\"bar\"",
   3162     "(foo + bar)",
   3163     "new new foo()[bar]",  // means: new (new foo()[bar])
   3164     "new new foo().bar",  // means: new (new foo()[bar])
   3165     NULL
   3166   };
   3167 
   3168   // These are not okay for assignment, but okay for prefix / postix.
   3169   const char* bad_statement_data_for_assignment[] = {
   3170     "++foo",
   3171     "foo++",
   3172     "foo + bar",
   3173     NULL
   3174   };
   3175 
   3176   RunParserSyncTest(assignment_context_data, good_statement_data, kSuccess);
   3177   RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
   3178   RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
   3179                     kError);
   3180 
   3181   RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
   3182   RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
   3183 
   3184   RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
   3185   RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
   3186 }
   3187 
   3188 
   3189 TEST(FuncNameInferrerBasic) {
   3190   // Tests that function names are inferred properly.
   3191   i::FLAG_allow_natives_syntax = true;
   3192   v8::Isolate* isolate = CcTest::isolate();
   3193   v8::HandleScope scope(isolate);
   3194   LocalContext env;
   3195   CompileRun("var foo1 = function() {}; "
   3196              "var foo2 = function foo3() {}; "
   3197              "function not_ctor() { "
   3198              "  var foo4 = function() {}; "
   3199              "  return %FunctionGetInferredName(foo4); "
   3200              "} "
   3201              "function Ctor() { "
   3202              "  var foo5 = function() {}; "
   3203              "  return %FunctionGetInferredName(foo5); "
   3204              "} "
   3205              "var obj1 = { foo6: function() {} }; "
   3206              "var obj2 = { 'foo7': function() {} }; "
   3207              "var obj3 = {}; "
   3208              "obj3[1] = function() {}; "
   3209              "var obj4 = {}; "
   3210              "obj4[1] = function foo8() {}; "
   3211              "var obj5 = {}; "
   3212              "obj5['foo9'] = function() {}; "
   3213              "var obj6 = { obj7 : { foo10: function() {} } };");
   3214   ExpectString("%FunctionGetInferredName(foo1)", "foo1");
   3215   // foo2 is not unnamed -> its name is not inferred.
   3216   ExpectString("%FunctionGetInferredName(foo2)", "");
   3217   ExpectString("not_ctor()", "foo4");
   3218   ExpectString("Ctor()", "Ctor.foo5");
   3219   ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
   3220   ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
   3221   ExpectString("%FunctionGetInferredName(obj3[1])",
   3222                "obj3.(anonymous function)");
   3223   ExpectString("%FunctionGetInferredName(obj4[1])", "");
   3224   ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
   3225   ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
   3226 }
   3227 
   3228 
   3229 TEST(FuncNameInferrerTwoByte) {
   3230   // Tests function name inferring in cases where some parts of the inferred
   3231   // function name are two-byte strings.
   3232   i::FLAG_allow_natives_syntax = true;
   3233   v8::Isolate* isolate = CcTest::isolate();
   3234   v8::HandleScope scope(isolate);
   3235   LocalContext env;
   3236   uint16_t* two_byte_source = AsciiToTwoByteString(
   3237       "var obj1 = { oXj2 : { foo1: function() {} } }; "
   3238       "%FunctionGetInferredName(obj1.oXj2.foo1)");
   3239   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   3240   // Make it really non-Latin1 (replace the Xs with a non-Latin1 character).
   3241   two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010d;
   3242   v8::Local<v8::String> source =
   3243       v8::String::NewFromTwoByte(isolate, two_byte_source,
   3244                                  v8::NewStringType::kNormal)
   3245           .ToLocalChecked();
   3246   v8::Local<v8::Value> result = CompileRun(source);
   3247   CHECK(result->IsString());
   3248   v8::Local<v8::String> expected_name =
   3249       v8::String::NewFromTwoByte(isolate, two_byte_name,
   3250                                  v8::NewStringType::kNormal)
   3251           .ToLocalChecked();
   3252   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
   3253   i::DeleteArray(two_byte_source);
   3254   i::DeleteArray(two_byte_name);
   3255 }
   3256 
   3257 
   3258 TEST(FuncNameInferrerEscaped) {
   3259   // The same as FuncNameInferrerTwoByte, except that we express the two-byte
   3260   // character as a unicode escape.
   3261   i::FLAG_allow_natives_syntax = true;
   3262   v8::Isolate* isolate = CcTest::isolate();
   3263   v8::HandleScope scope(isolate);
   3264   LocalContext env;
   3265   uint16_t* two_byte_source = AsciiToTwoByteString(
   3266       "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
   3267       "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
   3268   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   3269   // Fix to correspond to the non-ASCII name in two_byte_source.
   3270   two_byte_name[6] = 0x010d;
   3271   v8::Local<v8::String> source =
   3272       v8::String::NewFromTwoByte(isolate, two_byte_source,
   3273                                  v8::NewStringType::kNormal)
   3274           .ToLocalChecked();
   3275   v8::Local<v8::Value> result = CompileRun(source);
   3276   CHECK(result->IsString());
   3277   v8::Local<v8::String> expected_name =
   3278       v8::String::NewFromTwoByte(isolate, two_byte_name,
   3279                                  v8::NewStringType::kNormal)
   3280           .ToLocalChecked();
   3281   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
   3282   i::DeleteArray(two_byte_source);
   3283   i::DeleteArray(two_byte_name);
   3284 }
   3285 
   3286 
   3287 TEST(RegressionLazyFunctionWithErrorWithArg) {
   3288   // Test only applies when lazy parsing.
   3289   if (!i::FLAG_lazy || (i::FLAG_ignition && i::FLAG_ignition_eager)) return;
   3290 
   3291   // The bug occurred when a lazy function had an error which requires a
   3292   // parameter (such as "unknown label" here). The error message was processed
   3293   // before the AstValueFactory containing the error message string was
   3294   // internalized.
   3295   v8::Isolate* isolate = CcTest::isolate();
   3296   v8::HandleScope scope(isolate);
   3297   LocalContext env;
   3298   i::FLAG_lazy = true;
   3299   i::FLAG_min_preparse_length = 0;
   3300   CompileRun("function this_is_lazy() {\n"
   3301              "  break p;\n"
   3302              "}\n"
   3303              "this_is_lazy();\n");
   3304 }
   3305 
   3306 
   3307 TEST(SerializationOfMaybeAssignmentFlag) {
   3308   i::Isolate* isolate = CcTest::i_isolate();
   3309   i::Factory* factory = isolate->factory();
   3310   i::HandleScope scope(isolate);
   3311   LocalContext env;
   3312 
   3313   const char* src =
   3314       "function h() {"
   3315       "  var result = [];"
   3316       "  function f() {"
   3317       "    result.push(2);"
   3318       "  }"
   3319       "  function assertResult(r) {"
   3320       "    f();"
   3321       "    result = [];"
   3322       "  }"
   3323       "  assertResult([2]);"
   3324       "  assertResult([2]);"
   3325       "  return f;"
   3326       "};"
   3327       "h();";
   3328 
   3329   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
   3330   i::SNPrintF(program, "%s", src);
   3331   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
   3332   source->PrintOn(stdout);
   3333   printf("\n");
   3334   i::Zone zone(CcTest::i_isolate()->allocator());
   3335   v8::Local<v8::Value> v = CompileRun(src);
   3336   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
   3337   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
   3338   i::Context* context = f->context();
   3339   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   3340   avf.Internalize(isolate);
   3341   const i::AstRawString* name = avf.GetOneByteString("result");
   3342   i::Handle<i::String> str = name->string();
   3343   CHECK(str->IsInternalizedString());
   3344   i::Scope* script_scope =
   3345       new (&zone) i::Scope(&zone, NULL, i::SCRIPT_SCOPE, &avf);
   3346   script_scope->Initialize();
   3347   i::Scope* s =
   3348       i::Scope::DeserializeScopeChain(isolate, &zone, context, script_scope);
   3349   CHECK(s != script_scope);
   3350   CHECK(name != NULL);
   3351 
   3352   // Get result from h's function context (that is f's context)
   3353   i::Variable* var = s->Lookup(name);
   3354 
   3355   CHECK(var != NULL);
   3356   // Maybe assigned should survive deserialization
   3357   CHECK(var->maybe_assigned() == i::kMaybeAssigned);
   3358   // TODO(sigurds) Figure out if is_used should survive context serialization.
   3359 }
   3360 
   3361 
   3362 TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
   3363   i::Isolate* isolate = CcTest::i_isolate();
   3364   i::Factory* factory = isolate->factory();
   3365   i::HandleScope scope(isolate);
   3366   LocalContext env;
   3367 
   3368 
   3369   const char* src =
   3370       "function f(x) {"
   3371       "    var a = arguments;"
   3372       "    function g(i) {"
   3373       "      ++a[0];"
   3374       "    };"
   3375       "    return g;"
   3376       "  }"
   3377       "f(0);";
   3378 
   3379   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
   3380   i::SNPrintF(program, "%s", src);
   3381   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
   3382   source->PrintOn(stdout);
   3383   printf("\n");
   3384   i::Zone zone(CcTest::i_isolate()->allocator());
   3385   v8::Local<v8::Value> v = CompileRun(src);
   3386   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
   3387   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
   3388   i::Context* context = f->context();
   3389   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   3390   avf.Internalize(isolate);
   3391 
   3392   i::Scope* script_scope =
   3393       new (&zone) i::Scope(&zone, NULL, i::SCRIPT_SCOPE, &avf);
   3394   script_scope->Initialize();
   3395   i::Scope* s =
   3396       i::Scope::DeserializeScopeChain(isolate, &zone, context, script_scope);
   3397   CHECK(s != script_scope);
   3398   const i::AstRawString* name_x = avf.GetOneByteString("x");
   3399 
   3400   // Get result from f's function context (that is g's outer context)
   3401   i::Variable* var_x = s->Lookup(name_x);
   3402   CHECK(var_x != NULL);
   3403   CHECK(var_x->maybe_assigned() == i::kMaybeAssigned);
   3404 }
   3405 
   3406 
   3407 TEST(InnerAssignment) {
   3408   i::Isolate* isolate = CcTest::i_isolate();
   3409   i::Factory* factory = isolate->factory();
   3410   i::HandleScope scope(isolate);
   3411   LocalContext env;
   3412 
   3413   const char* prefix = "function f() {";
   3414   const char* midfix = " function g() {";
   3415   const char* suffix = "}}";
   3416   struct { const char* source; bool assigned; bool strict; } outers[] = {
   3417     // Actual assignments.
   3418     { "var x; var x = 5;", true, false },
   3419     { "var x; { var x = 5; }", true, false },
   3420     { "'use strict'; let x; x = 6;", true, true },
   3421     { "var x = 5; function x() {}", true, false },
   3422     // Actual non-assignments.
   3423     { "var x;", false, false },
   3424     { "var x = 5;", false, false },
   3425     { "'use strict'; let x;", false, true },
   3426     { "'use strict'; let x = 6;", false, true },
   3427     { "'use strict'; var x = 0; { let x = 6; }", false, true },
   3428     { "'use strict'; var x = 0; { let x; x = 6; }", false, true },
   3429     { "'use strict'; let x = 0; { let x = 6; }", false, true },
   3430     { "'use strict'; let x = 0; { let x; x = 6; }", false, true },
   3431     { "var x; try {} catch (x) { x = 5; }", false, false },
   3432     { "function x() {}", false, false },
   3433     // Eval approximation.
   3434     { "var x; eval('');", true, false },
   3435     { "eval(''); var x;", true, false },
   3436     { "'use strict'; let x; eval('');", true, true },
   3437     { "'use strict'; eval(''); let x;", true, true },
   3438     // Non-assignments not recognized, because the analysis is approximative.
   3439     { "var x; var x;", true, false },
   3440     { "var x = 5; var x;", true, false },
   3441     { "var x; { var x; }", true, false },
   3442     { "var x; function x() {}", true, false },
   3443     { "function x() {}; var x;", true, false },
   3444     { "var x; try {} catch (x) { var x = 5; }", true, false },
   3445   };
   3446   struct { const char* source; bool assigned; bool with; } inners[] = {
   3447     // Actual assignments.
   3448     { "x = 1;", true, false },
   3449     { "x++;", true, false },
   3450     { "++x;", true, false },
   3451     { "x--;", true, false },
   3452     { "--x;", true, false },
   3453     { "{ x = 1; }", true, false },
   3454     { "'use strict'; { let x; }; x = 0;", true, false },
   3455     { "'use strict'; { const x = 1; }; x = 0;", true, false },
   3456     { "'use strict'; { function x() {} }; x = 0;", true, false },
   3457     { "with ({}) { x = 1; }", true, true },
   3458     { "eval('');", true, false },
   3459     { "'use strict'; { let y; eval('') }", true, false },
   3460     { "function h() { x = 0; }", true, false },
   3461     { "(function() { x = 0; })", true, false },
   3462     { "(function() { x = 0; })", true, false },
   3463     { "with ({}) (function() { x = 0; })", true, true },
   3464     // Actual non-assignments.
   3465     { "", false, false },
   3466     { "x;", false, false },
   3467     { "var x;", false, false },
   3468     { "var x = 8;", false, false },
   3469     { "var x; x = 8;", false, false },
   3470     { "'use strict'; let x;", false, false },
   3471     { "'use strict'; let x = 8;", false, false },
   3472     { "'use strict'; let x; x = 8;", false, false },
   3473     { "'use strict'; const x = 8;", false, false },
   3474     { "function x() {}", false, false },
   3475     { "function x() { x = 0; }", false, false },
   3476     { "function h(x) { x = 0; }", false, false },
   3477     { "'use strict'; { let x; x = 0; }", false, false },
   3478     { "{ var x; }; x = 0;", false, false },
   3479     { "with ({}) {}", false, true },
   3480     { "var x; { with ({}) { x = 1; } }", false, true },
   3481     { "try {} catch(x) { x = 0; }", false, false },
   3482     { "try {} catch(x) { with ({}) { x = 1; } }", false, true },
   3483     // Eval approximation.
   3484     { "eval('');", true, false },
   3485     { "function h() { eval(''); }", true, false },
   3486     { "(function() { eval(''); })", true, false },
   3487     // Shadowing not recognized because of eval approximation.
   3488     { "var x; eval('');", true, false },
   3489     { "'use strict'; let x; eval('');", true, false },
   3490     { "try {} catch(x) { eval(''); }", true, false },
   3491     { "function x() { eval(''); }", true, false },
   3492     { "(function(x) { eval(''); })", true, false },
   3493   };
   3494 
   3495   // Used to trigger lazy compilation of function
   3496   int comment_len = 2048;
   3497   i::ScopedVector<char> comment(comment_len + 1);
   3498   i::SNPrintF(comment, "/*%0*d*/", comment_len - 4, 0);
   3499   int prefix_len = Utf8LengthHelper(prefix);
   3500   int midfix_len = Utf8LengthHelper(midfix);
   3501   int suffix_len = Utf8LengthHelper(suffix);
   3502   for (unsigned i = 0; i < arraysize(outers); ++i) {
   3503     const char* outer = outers[i].source;
   3504     int outer_len = Utf8LengthHelper(outer);
   3505     for (unsigned j = 0; j < arraysize(inners); ++j) {
   3506       for (unsigned outer_lazy = 0; outer_lazy < 2; ++outer_lazy) {
   3507         for (unsigned inner_lazy = 0; inner_lazy < 2; ++inner_lazy) {
   3508           if (outers[i].strict && inners[j].with) continue;
   3509           const char* inner = inners[j].source;
   3510           int inner_len = Utf8LengthHelper(inner);
   3511 
   3512           int outer_comment_len = outer_lazy ? comment_len : 0;
   3513           int inner_comment_len = inner_lazy ? comment_len : 0;
   3514           const char* outer_comment = outer_lazy ? comment.start() : "";
   3515           const char* inner_comment = inner_lazy ? comment.start() : "";
   3516           int len = prefix_len + outer_comment_len + outer_len + midfix_len +
   3517                     inner_comment_len + inner_len + suffix_len;
   3518           i::ScopedVector<char> program(len + 1);
   3519 
   3520           i::SNPrintF(program, "%s%s%s%s%s%s%s", prefix, outer_comment, outer,
   3521                       midfix, inner_comment, inner, suffix);
   3522           i::Handle<i::String> source =
   3523               factory->InternalizeUtf8String(program.start());
   3524           source->PrintOn(stdout);
   3525           printf("\n");
   3526 
   3527           i::Handle<i::Script> script = factory->NewScript(source);
   3528           i::Zone zone(CcTest::i_isolate()->allocator());
   3529           i::ParseInfo info(&zone, script);
   3530           i::Parser parser(&info);
   3531           CHECK(parser.Parse(&info));
   3532           CHECK(i::Compiler::Analyze(&info));
   3533           CHECK(info.literal() != NULL);
   3534 
   3535           i::Scope* scope = info.literal()->scope();
   3536           CHECK_EQ(scope->inner_scopes()->length(), 1);
   3537           i::Scope* inner_scope = scope->inner_scopes()->at(0);
   3538           const i::AstRawString* var_name =
   3539               info.ast_value_factory()->GetOneByteString("x");
   3540           i::Variable* var = inner_scope->Lookup(var_name);
   3541           bool expected = outers[i].assigned || inners[j].assigned;
   3542           CHECK(var != NULL);
   3543           CHECK(var->is_used() || !expected);
   3544           CHECK((var->maybe_assigned() == i::kMaybeAssigned) == expected);
   3545         }
   3546       }
   3547     }
   3548   }
   3549 }
   3550 
   3551 namespace {
   3552 
   3553 int* global_use_counts = NULL;
   3554 
   3555 void MockUseCounterCallback(v8::Isolate* isolate,
   3556                             v8::Isolate::UseCounterFeature feature) {
   3557   ++global_use_counts[feature];
   3558 }
   3559 
   3560 }
   3561 
   3562 
   3563 TEST(UseAsmUseCount) {
   3564   i::Isolate* isolate = CcTest::i_isolate();
   3565   i::HandleScope scope(isolate);
   3566   LocalContext env;
   3567   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
   3568   global_use_counts = use_counts;
   3569   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
   3570   CompileRun("\"use asm\";\n"
   3571              "var foo = 1;\n"
   3572              "function bar() { \"use asm\"; var baz = 1; }");
   3573   CHECK_LT(0, use_counts[v8::Isolate::kUseAsm]);
   3574 }
   3575 
   3576 
   3577 TEST(StrictModeUseCount) {
   3578   i::Isolate* isolate = CcTest::i_isolate();
   3579   i::HandleScope scope(isolate);
   3580   LocalContext env;
   3581   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
   3582   global_use_counts = use_counts;
   3583   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
   3584   CompileRun(
   3585       "\"use strict\";\n"
   3586       "function bar() { var baz = 1; }");  // strict mode inherits
   3587   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
   3588   CHECK_EQ(0, use_counts[v8::Isolate::kSloppyMode]);
   3589 }
   3590 
   3591 
   3592 TEST(SloppyModeUseCount) {
   3593   i::Isolate* isolate = CcTest::i_isolate();
   3594   i::HandleScope scope(isolate);
   3595   LocalContext env;
   3596   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
   3597   global_use_counts = use_counts;
   3598   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
   3599   CompileRun("function bar() { var baz = 1; }");
   3600   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
   3601   CHECK_EQ(0, use_counts[v8::Isolate::kStrictMode]);
   3602 }
   3603 
   3604 
   3605 TEST(BothModesUseCount) {
   3606   i::Isolate* isolate = CcTest::i_isolate();
   3607   i::HandleScope scope(isolate);
   3608   LocalContext env;
   3609   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
   3610   global_use_counts = use_counts;
   3611   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
   3612   CompileRun("function bar() { 'use strict'; var baz = 1; }");
   3613   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
   3614   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
   3615 }
   3616 
   3617 
   3618 TEST(ErrorsArrowFormalParameters) {
   3619   const char* context_data[][2] = {
   3620     { "()", "=>{}" },
   3621     { "()", "=>{};" },
   3622     { "var x = ()", "=>{}" },
   3623     { "var x = ()", "=>{};" },
   3624 
   3625     { "a", "=>{}" },
   3626     { "a", "=>{};" },
   3627     { "var x = a", "=>{}" },
   3628     { "var x = a", "=>{};" },
   3629 
   3630     { "(a)", "=>{}" },
   3631     { "(a)", "=>{};" },
   3632     { "var x = (a)", "=>{}" },
   3633     { "var x = (a)", "=>{};" },
   3634 
   3635     { "(...a)", "=>{}" },
   3636     { "(...a)", "=>{};" },
   3637     { "var x = (...a)", "=>{}" },
   3638     { "var x = (...a)", "=>{};" },
   3639 
   3640     { "(a,b)", "=>{}" },
   3641     { "(a,b)", "=>{};" },
   3642     { "var x = (a,b)", "=>{}" },
   3643     { "var x = (a,b)", "=>{};" },
   3644 
   3645     { "(a,...b)", "=>{}" },
   3646     { "(a,...b)", "=>{};" },
   3647     { "var x = (a,...b)", "=>{}" },
   3648     { "var x = (a,...b)", "=>{};" },
   3649 
   3650     { nullptr, nullptr }
   3651   };
   3652   const char* assignment_expression_suffix_data[] = {
   3653     "?c:d=>{}",
   3654     "=c=>{}",
   3655     "()",
   3656     "(c)",
   3657     "[1]",
   3658     "[c]",
   3659     ".c",
   3660     "-c",
   3661     "+c",
   3662     "c++",
   3663     "`c`",
   3664     "`${c}`",
   3665     "`template-head${c}`",
   3666     "`${c}template-tail`",
   3667     "`template-head${c}template-tail`",
   3668     "`${c}template-tail`",
   3669     nullptr
   3670   };
   3671 
   3672   RunParserSyncTest(context_data, assignment_expression_suffix_data, kError);
   3673 }
   3674 
   3675 
   3676 TEST(ErrorsArrowFunctions) {
   3677   // Tests that parser and preparser generate the same kind of errors
   3678   // on invalid arrow function syntax.
   3679 
   3680   // clang-format off
   3681   const char* context_data[][2] = {
   3682     {"", ";"},
   3683     {"v = ", ";"},
   3684     {"bar ? (", ") : baz;"},
   3685     {"bar ? baz : (", ");"},
   3686     {"bar[", "];"},
   3687     {"bar, ", ";"},
   3688     {"", ", bar;"},
   3689     {NULL, NULL}
   3690   };
   3691 
   3692   const char* statement_data[] = {
   3693     "=> 0",
   3694     "=>",
   3695     "() =>",
   3696     "=> {}",
   3697     ") => {}",
   3698     ", => {}",
   3699     "(,) => {}",
   3700     "return => {}",
   3701     "() => {'value': 42}",
   3702 
   3703     // Check that the early return introduced in ParsePrimaryExpression
   3704     // does not accept stray closing parentheses.
   3705     ")",
   3706     ") => 0",
   3707     "foo[()]",
   3708     "()",
   3709 
   3710     // Parameter lists with extra parens should be recognized as errors.
   3711     "(()) => 0",
   3712     "((x)) => 0",
   3713     "((x, y)) => 0",
   3714     "(x, (y)) => 0",
   3715     "((x, y, z)) => 0",
   3716     "(x, (y, z)) => 0",
   3717     "((x, y), z) => 0",
   3718 
   3719     // Arrow function formal parameters are parsed as StrictFormalParameters,
   3720     // which confusingly only implies that there are no duplicates.  Words
   3721     // reserved in strict mode, and eval or arguments, are indeed valid in
   3722     // sloppy mode.
   3723     "eval => { 'use strict'; 0 }",
   3724     "arguments => { 'use strict'; 0 }",
   3725     "yield => { 'use strict'; 0 }",
   3726     "interface => { 'use strict'; 0 }",
   3727     "(eval) => { 'use strict'; 0 }",
   3728     "(arguments) => { 'use strict'; 0 }",
   3729     "(yield) => { 'use strict'; 0 }",
   3730     "(interface) => { 'use strict'; 0 }",
   3731     "(eval, bar) => { 'use strict'; 0 }",
   3732     "(bar, eval) => { 'use strict'; 0 }",
   3733     "(bar, arguments) => { 'use strict'; 0 }",
   3734     "(bar, yield) => { 'use strict'; 0 }",
   3735     "(bar, interface) => { 'use strict'; 0 }",
   3736     // TODO(aperez): Detecting duplicates does not work in PreParser.
   3737     // "(bar, bar) => {}",
   3738 
   3739     // The parameter list is parsed as an expression, but only
   3740     // a comma-separated list of identifier is valid.
   3741     "32 => {}",
   3742     "(32) => {}",
   3743     "(a, 32) => {}",
   3744     "if => {}",
   3745     "(if) => {}",
   3746     "(a, if) => {}",
   3747     "a + b => {}",
   3748     "(a + b) => {}",
   3749     "(a + b, c) => {}",
   3750     "(a, b - c) => {}",
   3751     "\"a\" => {}",
   3752     "(\"a\") => {}",
   3753     "(\"a\", b) => {}",
   3754     "(a, \"b\") => {}",
   3755     "-a => {}",
   3756     "(-a) => {}",
   3757     "(-a, b) => {}",
   3758     "(a, -b) => {}",
   3759     "{} => {}",
   3760     "a++ => {}",
   3761     "(a++) => {}",
   3762     "(a++, b) => {}",
   3763     "(a, b++) => {}",
   3764     "[] => {}",
   3765     "(foo ? bar : baz) => {}",
   3766     "(a, foo ? bar : baz) => {}",
   3767     "(foo ? bar : baz, a) => {}",
   3768     "(a.b, c) => {}",
   3769     "(c, a.b) => {}",
   3770     "(a['b'], c) => {}",
   3771     "(c, a['b']) => {}",
   3772 
   3773     // crbug.com/582626
   3774     "(...rest - a) => b",
   3775     "(a, ...b - 10) => b",
   3776 
   3777     NULL
   3778   };
   3779   // clang-format on
   3780 
   3781   // The test is quite slow, so run it with a reduced set of flags.
   3782   static const ParserFlag flags[] = {kAllowLazy};
   3783   RunParserSyncTest(context_data, statement_data, kError, flags,
   3784                     arraysize(flags));
   3785 
   3786   // In a context where a concise arrow body is parsed with [~In] variant,
   3787   // ensure that an error is reported in both full parser and preparser.
   3788   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
   3789                                         {nullptr, nullptr}};
   3790   const char* loop_expr_data[] = {"f => 'key' in {}", nullptr};
   3791   RunParserSyncTest(loop_context_data, loop_expr_data, kError, flags,
   3792                     arraysize(flags));
   3793 }
   3794 
   3795 
   3796 TEST(NoErrorsArrowFunctions) {
   3797   // Tests that parser and preparser accept valid arrow functions syntax.
   3798   // clang-format off
   3799   const char* context_data[][2] = {
   3800     {"", ";"},
   3801     {"bar ? (", ") : baz;"},
   3802     {"bar ? baz : (", ");"},
   3803     {"bar, ", ";"},
   3804     {"", ", bar;"},
   3805     {NULL, NULL}
   3806   };
   3807 
   3808   const char* statement_data[] = {
   3809     "() => {}",
   3810     "() => { return 42 }",
   3811     "x => { return x; }",
   3812     "(x) => { return x; }",
   3813     "(x, y) => { return x + y; }",
   3814     "(x, y, z) => { return x + y + z; }",
   3815     "(x, y) => { x.a = y; }",
   3816     "() => 42",
   3817     "x => x",
   3818     "x => x * x",
   3819     "(x) => x",
   3820     "(x) => x * x",
   3821     "(x, y) => x + y",
   3822     "(x, y, z) => x, y, z",
   3823     "(x, y) => x.a = y",
   3824     "() => ({'value': 42})",
   3825     "x => y => x + y",
   3826     "(x, y) => (u, v) => x*u + y*v",
   3827     "(x, y) => z => z * (x + y)",
   3828     "x => (y, z) => z * (x + y)",
   3829 
   3830     // Those are comma-separated expressions, with arrow functions as items.
   3831     // They stress the code for validating arrow function parameter lists.
   3832     "a, b => 0",
   3833     "a, b, (c, d) => 0",
   3834     "(a, b, (c, d) => 0)",
   3835     "(a, b) => 0, (c, d) => 1",
   3836     "(a, b => {}, a => a + 1)",
   3837     "((a, b) => {}, (a => a + 1))",
   3838     "(a, (a, (b, c) => 0))",
   3839 
   3840     // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
   3841     "foo ? bar : baz => {}",
   3842 
   3843     // Arrows with non-simple parameters.
   3844     "({}) => {}",
   3845     "(a, {}) => {}",
   3846     "({}, a) => {}",
   3847     "([]) => {}",
   3848     "(a, []) => {}",
   3849     "([], a) => {}",
   3850     "(a = b) => {}",
   3851     "(a = b, c) => {}",
   3852     "(a, b = c) => {}",
   3853     "({a}) => {}",
   3854     "(x = 9) => {}",
   3855     "(x, y = 9) => {}",
   3856     "(x = 9, y) => {}",
   3857     "(x, y = 9, z) => {}",
   3858     "(x, y = 9, z = 8) => {}",
   3859     "(...a) => {}",
   3860     "(x, ...a) => {}",
   3861     "(x = 9, ...a) => {}",
   3862     "(x, y = 9, ...a) => {}",
   3863     "(x, y = 9, {b}, z = 8, ...a) => {}",
   3864     "({a} = {}) => {}",
   3865     "([x] = []) => {}",
   3866     "({a = 42}) => {}",
   3867     "([x = 0]) => {}",
   3868     NULL
   3869   };
   3870   // clang-format on
   3871 
   3872   RunParserSyncTest(context_data, statement_data, kSuccess);
   3873 
   3874   static const ParserFlag flags[] = {kAllowLazy};
   3875   // In a context where a concise arrow body is parsed with [~In] variant,
   3876   // ensure that nested expressions can still use the 'in' operator,
   3877   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
   3878                                         {nullptr, nullptr}};
   3879   const char* loop_expr_data[] = {"f => ('key' in {})", nullptr};
   3880   RunParserSyncTest(loop_context_data, loop_expr_data, kSuccess, flags,
   3881                     arraysize(flags));
   3882 }
   3883 
   3884 
   3885 TEST(ArrowFunctionsSloppyParameterNames) {
   3886   const char* strict_context_data[][2] = {
   3887     {"'use strict'; ", ";"},
   3888     {"'use strict'; bar ? (", ") : baz;"},
   3889     {"'use strict'; bar ? baz : (", ");"},
   3890     {"'use strict'; bar, ", ";"},
   3891     {"'use strict'; ", ", bar;"},
   3892     {NULL, NULL}
   3893   };
   3894 
   3895   const char* sloppy_context_data[][2] = {
   3896     {"", ";"},
   3897     {"bar ? (", ") : baz;"},
   3898     {"bar ? baz : (", ");"},
   3899     {"bar, ", ";"},
   3900     {"", ", bar;"},
   3901     {NULL, NULL}
   3902   };
   3903 
   3904   const char* statement_data[] = {
   3905     "eval => {}",
   3906     "arguments => {}",
   3907     "yield => {}",
   3908     "interface => {}",
   3909     "(eval) => {}",
   3910     "(arguments) => {}",
   3911     "(yield) => {}",
   3912     "(interface) => {}",
   3913     "(eval, bar) => {}",
   3914     "(bar, eval) => {}",
   3915     "(bar, arguments) => {}",
   3916     "(bar, yield) => {}",
   3917     "(bar, interface) => {}",
   3918     "(interface, eval) => {}",
   3919     "(interface, arguments) => {}",
   3920     "(eval, interface) => {}",
   3921     "(arguments, interface) => {}",
   3922     NULL
   3923   };
   3924 
   3925   RunParserSyncTest(strict_context_data, statement_data, kError);
   3926   RunParserSyncTest(sloppy_context_data, statement_data, kSuccess);
   3927 }
   3928 
   3929 
   3930 TEST(ArrowFunctionsYieldParameterNameInGenerator) {
   3931   const char* sloppy_function_context_data[][2] = {
   3932     {"(function f() { (", "); });"},
   3933     {NULL, NULL}
   3934   };
   3935 
   3936   const char* strict_function_context_data[][2] = {
   3937     {"(function f() {'use strict'; (", "); });"},
   3938     {NULL, NULL}
   3939   };
   3940 
   3941   const char* generator_context_data[][2] = {
   3942     {"(function *g() {'use strict'; (", "); });"},
   3943     {"(function *g() { (", "); });"},
   3944     {NULL, NULL}
   3945   };
   3946 
   3947   const char* arrow_data[] = {
   3948     "yield => {}",
   3949     "(yield) => {}",
   3950     "(a, yield) => {}",
   3951     "(yield, a) => {}",
   3952     "(yield, ...a) => {}",
   3953     "(a, ...yield) => {}",
   3954     "({yield}) => {}",
   3955     "([yield]) => {}",
   3956     NULL
   3957   };
   3958 
   3959   RunParserSyncTest(sloppy_function_context_data, arrow_data, kSuccess);
   3960   RunParserSyncTest(strict_function_context_data, arrow_data, kError);
   3961   RunParserSyncTest(generator_context_data, arrow_data, kError);
   3962 }
   3963 
   3964 
   3965 TEST(SuperNoErrors) {
   3966   // Tests that parser and preparser accept 'super' keyword in right places.
   3967   const char* context_data[][2] = {
   3968     {"class C { m() { ", "; } }"},
   3969     {"class C { m() { k = ", "; } }"},
   3970     {"class C { m() { foo(", "); } }"},
   3971     {"class C { m() { () => ", "; } }"},
   3972     {NULL, NULL}
   3973   };
   3974 
   3975   const char* statement_data[] = {
   3976     "super.x",
   3977     "super[27]",
   3978     "new super.x",
   3979     "new super.x()",
   3980     "new super[27]",
   3981     "new super[27]()",
   3982     "z.super",  // Ok, property lookup.
   3983     NULL
   3984   };
   3985 
   3986   RunParserSyncTest(context_data, statement_data, kSuccess);
   3987 }
   3988 
   3989 
   3990 TEST(SuperErrors) {
   3991   const char* context_data[][2] = {
   3992     {"class C { m() { ", "; } }"},
   3993     {"class C { m() { k = ", "; } }"},
   3994     {"class C { m() { foo(", "); } }"},
   3995     {"class C { m() { () => ", "; } }"},
   3996     {NULL, NULL}
   3997   };
   3998 
   3999   const char* expression_data[] = {
   4000     "super",
   4001     "super = x",
   4002     "y = super",
   4003     "f(super)",
   4004     "new super",
   4005     "new super()",
   4006     "new super(12, 45)",
   4007     "new new super",
   4008     "new new super()",
   4009     "new new super()()",
   4010     NULL
   4011   };
   4012 
   4013   RunParserSyncTest(context_data, expression_data, kError);
   4014 }
   4015 
   4016 
   4017 TEST(SuperCall) {
   4018   const char* context_data[][2] = {{"", ""},
   4019                                    {NULL, NULL}};
   4020 
   4021   const char* success_data[] = {
   4022     "class C extends B { constructor() { super(); } }",
   4023     "class C extends B { constructor() { () => super(); } }",
   4024     NULL
   4025   };
   4026 
   4027   RunParserSyncTest(context_data, success_data, kSuccess);
   4028 
   4029   const char* error_data[] = {
   4030     "class C { constructor() { super(); } }",
   4031     "class C { method() { super(); } }",
   4032     "class C { method() { () => super(); } }",
   4033     "class C { *method() { super(); } }",
   4034     "class C { get x() { super(); } }",
   4035     "class C { set x(_) { super(); } }",
   4036     "({ method() { super(); } })",
   4037     "({ *method() { super(); } })",
   4038     "({ get x() { super(); } })",
   4039     "({ set x(_) { super(); } })",
   4040     "({ f: function() { super(); } })",
   4041     "(function() { super(); })",
   4042     "var f = function() { super(); }",
   4043     "({ f: function*() { super(); } })",
   4044     "(function*() { super(); })",
   4045     "var f = function*() { super(); }",
   4046     NULL
   4047   };
   4048 
   4049   RunParserSyncTest(context_data, error_data, kError);
   4050 }
   4051 
   4052 
   4053 TEST(SuperNewNoErrors) {
   4054   const char* context_data[][2] = {
   4055     {"class C { constructor() { ", " } }"},
   4056     {"class C { *method() { ", " } }"},
   4057     {"class C { get x() { ", " } }"},
   4058     {"class C { set x(_) { ", " } }"},
   4059     {"({ method() { ", " } })"},
   4060     {"({ *method() { ", " } })"},
   4061     {"({ get x() { ", " } })"},
   4062     {"({ set x(_) { ", " } })"},
   4063     {NULL, NULL}
   4064   };
   4065 
   4066   const char* expression_data[] = {
   4067     "new super.x;",
   4068     "new super.x();",
   4069     "() => new super.x;",
   4070     "() => new super.x();",
   4071     NULL
   4072   };
   4073 
   4074   RunParserSyncTest(context_data, expression_data, kSuccess);
   4075 }
   4076 
   4077 
   4078 TEST(SuperNewErrors) {
   4079   const char* context_data[][2] = {
   4080     {"class C { method() { ", " } }"},
   4081     {"class C { *method() { ", " } }"},
   4082     {"class C { get x() { ", " } }"},
   4083     {"class C { set x(_) { ", " } }"},
   4084     {"({ method() { ", " } })"},
   4085     {"({ *method() { ", " } })"},
   4086     {"({ get x() { ", " } })"},
   4087     {"({ set x(_) { ", " } })"},
   4088     {"({ f: function() { ", " } })"},
   4089     {"(function() { ", " })"},
   4090     {"var f = function() { ", " }"},
   4091     {"({ f: function*() { ", " } })"},
   4092     {"(function*() { ", " })"},
   4093     {"var f = function*() { ", " }"},
   4094     {NULL, NULL}
   4095   };
   4096 
   4097   const char* statement_data[] = {
   4098     "new super;",
   4099     "new super();",
   4100     "() => new super;",
   4101     "() => new super();",
   4102     NULL
   4103   };
   4104 
   4105   RunParserSyncTest(context_data, statement_data, kError);
   4106 }
   4107 
   4108 
   4109 TEST(SuperErrorsNonMethods) {
   4110   // super is only allowed in methods, accessors and constructors.
   4111   const char* context_data[][2] = {
   4112     {"", ";"},
   4113     {"k = ", ";"},
   4114     {"foo(", ");"},
   4115     {"if (", ") {}"},
   4116     {"if (true) {", "}"},
   4117     {"if (false) {} else {", "}"},
   4118     {"while (true) {", "}"},
   4119     {"function f() {", "}"},
   4120     {"class C extends (", ") {}"},
   4121     {"class C { m() { function f() {", "} } }"},
   4122     {"({ m() { function f() {", "} } })"},
   4123     {NULL, NULL}
   4124   };
   4125 
   4126   const char* statement_data[] = {
   4127     "super",
   4128     "super = x",
   4129     "y = super",
   4130     "f(super)",
   4131     "super.x",
   4132     "super[27]",
   4133     "super.x()",
   4134     "super[27]()",
   4135     "super()",
   4136     "new super.x",
   4137     "new super.x()",
   4138     "new super[27]",
   4139     "new super[27]()",
   4140     NULL
   4141   };
   4142 
   4143   RunParserSyncTest(context_data, statement_data, kError);
   4144 }
   4145 
   4146 
   4147 TEST(NoErrorsMethodDefinition) {
   4148   const char* context_data[][2] = {{"({", "});"},
   4149                                    {"'use strict'; ({", "});"},
   4150                                    {"({*", "});"},
   4151                                    {"'use strict'; ({*", "});"},
   4152                                    {NULL, NULL}};
   4153 
   4154   const char* object_literal_body_data[] = {
   4155     "m() {}",
   4156     "m(x) { return x; }",
   4157     "m(x, y) {}, n() {}",
   4158     "set(x, y) {}",
   4159     "get(x, y) {}",
   4160     NULL
   4161   };
   4162 
   4163   RunParserSyncTest(context_data, object_literal_body_data, kSuccess);
   4164 }
   4165 
   4166 
   4167 TEST(MethodDefinitionNames) {
   4168   const char* context_data[][2] = {{"({", "(x, y) {}});"},
   4169                                    {"'use strict'; ({", "(x, y) {}});"},
   4170                                    {"({*", "(x, y) {}});"},
   4171                                    {"'use strict'; ({*", "(x, y) {}});"},
   4172                                    {NULL, NULL}};
   4173 
   4174   const char* name_data[] = {
   4175     "m",
   4176     "'m'",
   4177     "\"m\"",
   4178     "\"m n\"",
   4179     "true",
   4180     "false",
   4181     "null",
   4182     "0",
   4183     "1.2",
   4184     "1e1",
   4185     "1E1",
   4186     "1e+1",
   4187     "1e-1",
   4188 
   4189     // Keywords
   4190     "async",
   4191     "await",
   4192     "break",
   4193     "case",
   4194     "catch",
   4195     "class",
   4196     "const",
   4197     "continue",
   4198     "debugger",
   4199     "default",
   4200     "delete",
   4201     "do",
   4202     "else",
   4203     "enum",
   4204     "export",
   4205     "extends",
   4206     "finally",
   4207     "for",
   4208     "function",
   4209     "if",
   4210     "implements",
   4211     "import",
   4212     "in",
   4213     "instanceof",
   4214     "interface",
   4215     "let",
   4216     "new",
   4217     "package",
   4218     "private",
   4219     "protected",
   4220     "public",
   4221     "return",
   4222     "static",
   4223     "super",
   4224     "switch",
   4225     "this",
   4226     "throw",
   4227     "try",
   4228     "typeof",
   4229     "var",
   4230     "void",
   4231     "while",
   4232     "with",
   4233     "yield",
   4234     NULL
   4235   };
   4236 
   4237   RunParserSyncTest(context_data, name_data, kSuccess);
   4238 }
   4239 
   4240 
   4241 TEST(MethodDefinitionStrictFormalParamereters) {
   4242   const char* context_data[][2] = {{"({method(", "){}});"},
   4243                                    {"'use strict'; ({method(", "){}});"},
   4244                                    {"({*method(", "){}});"},
   4245                                    {"'use strict'; ({*method(", "){}});"},
   4246                                    {NULL, NULL}};
   4247 
   4248   const char* params_data[] = {
   4249     "x, x",
   4250     "x, y, x",
   4251     "var",
   4252     "const",
   4253     NULL
   4254   };
   4255 
   4256   RunParserSyncTest(context_data, params_data, kError);
   4257 }
   4258 
   4259 
   4260 TEST(MethodDefinitionEvalArguments) {
   4261   const char* strict_context_data[][2] =
   4262       {{"'use strict'; ({method(", "){}});"},
   4263        {"'use strict'; ({*method(", "){}});"},
   4264        {NULL, NULL}};
   4265   const char* sloppy_context_data[][2] =
   4266       {{"({method(", "){}});"},
   4267        {"({*method(", "){}});"},
   4268        {NULL, NULL}};
   4269 
   4270   const char* data[] = {
   4271       "eval",
   4272       "arguments",
   4273       NULL};
   4274 
   4275   // Fail in strict mode
   4276   RunParserSyncTest(strict_context_data, data, kError);
   4277 
   4278   // OK in sloppy mode
   4279   RunParserSyncTest(sloppy_context_data, data, kSuccess);
   4280 }
   4281 
   4282 
   4283 TEST(MethodDefinitionDuplicateEvalArguments) {
   4284   const char* context_data[][2] =
   4285       {{"'use strict'; ({method(", "){}});"},
   4286        {"'use strict'; ({*method(", "){}});"},
   4287        {"({method(", "){}});"},
   4288        {"({*method(", "){}});"},
   4289        {NULL, NULL}};
   4290 
   4291   const char* data[] = {
   4292       "eval, eval",
   4293       "eval, a, eval",
   4294       "arguments, arguments",
   4295       "arguments, a, arguments",
   4296       NULL};
   4297 
   4298   // In strict mode, the error is using "eval" or "arguments" as parameter names
   4299   // In sloppy mode, the error is that eval / arguments are duplicated
   4300   RunParserSyncTest(context_data, data, kError);
   4301 }
   4302 
   4303 
   4304 TEST(MethodDefinitionDuplicateProperty) {
   4305   const char* context_data[][2] = {{"'use strict'; ({", "});"},
   4306                                    {NULL, NULL}};
   4307 
   4308   const char* params_data[] = {
   4309     "x: 1, x() {}",
   4310     "x() {}, x: 1",
   4311     "x() {}, get x() {}",
   4312     "x() {}, set x(_) {}",
   4313     "x() {}, x() {}",
   4314     "x() {}, y() {}, x() {}",
   4315     "x() {}, \"x\"() {}",
   4316     "x() {}, 'x'() {}",
   4317     "0() {}, '0'() {}",
   4318     "1.0() {}, 1: 1",
   4319 
   4320     "x: 1, *x() {}",
   4321     "*x() {}, x: 1",
   4322     "*x() {}, get x() {}",
   4323     "*x() {}, set x(_) {}",
   4324     "*x() {}, *x() {}",
   4325     "*x() {}, y() {}, *x() {}",
   4326     "*x() {}, *\"x\"() {}",
   4327     "*x() {}, *'x'() {}",
   4328     "*0() {}, *'0'() {}",
   4329     "*1.0() {}, 1: 1",
   4330 
   4331     NULL
   4332   };
   4333 
   4334   RunParserSyncTest(context_data, params_data, kSuccess);
   4335 }
   4336 
   4337 
   4338 TEST(ClassExpressionNoErrors) {
   4339   const char* context_data[][2] = {{"(", ");"},
   4340                                    {"var C = ", ";"},
   4341                                    {"bar, ", ";"},
   4342                                    {NULL, NULL}};
   4343   const char* class_data[] = {
   4344     "class {}",
   4345     "class name {}",
   4346     "class extends F {}",
   4347     "class name extends F {}",
   4348     "class extends (F, G) {}",
   4349     "class name extends (F, G) {}",
   4350     "class extends class {} {}",
   4351     "class name extends class {} {}",
   4352     "class extends class base {} {}",
   4353     "class name extends class base {} {}",
   4354     NULL};
   4355 
   4356   RunParserSyncTest(context_data, class_data, kSuccess);
   4357 }
   4358 
   4359 
   4360 TEST(ClassDeclarationNoErrors) {
   4361   const char* context_data[][2] = {{"'use strict'; ", ""},
   4362                                    {"'use strict'; {", "}"},
   4363                                    {"'use strict'; if (true) {", "}"},
   4364                                    {NULL, NULL}};
   4365   const char* statement_data[] = {
   4366     "class name {}",
   4367     "class name extends F {}",
   4368     "class name extends (F, G) {}",
   4369     "class name extends class {} {}",
   4370     "class name extends class base {} {}",
   4371     NULL};
   4372 
   4373   RunParserSyncTest(context_data, statement_data, kSuccess);
   4374 }
   4375 
   4376 
   4377 TEST(ClassBodyNoErrors) {
   4378   // clang-format off
   4379   // Tests that parser and preparser accept valid class syntax.
   4380   const char* context_data[][2] = {{"(class {", "});"},
   4381                                    {"(class extends Base {", "});"},
   4382                                    {"class C {", "}"},
   4383                                    {"class C extends Base {", "}"},
   4384                                    {NULL, NULL}};
   4385   const char* class_body_data[] = {
   4386     ";",
   4387     ";;",
   4388     "m() {}",
   4389     "m() {};",
   4390     "; m() {}",
   4391     "m() {}; n(x) {}",
   4392     "get x() {}",
   4393     "set x(v) {}",
   4394     "get() {}",
   4395     "set() {}",
   4396     "*g() {}",
   4397     "*g() {};",
   4398     "; *g() {}",
   4399     "*g() {}; *h(x) {}",
   4400     "static() {}",
   4401     "get static() {}",
   4402     "set static(v) {}",
   4403     "static m() {}",
   4404     "static get x() {}",
   4405     "static set x(v) {}",
   4406     "static get() {}",
   4407     "static set() {}",
   4408     "static static() {}",
   4409     "static get static() {}",
   4410     "static set static(v) {}",
   4411     "*static() {}",
   4412     "static *static() {}",
   4413     "*get() {}",
   4414     "*set() {}",
   4415     "static *g() {}",
   4416 
   4417     // Escaped 'static' should be allowed anywhere
   4418     // static-as-PropertyName is.
   4419     "st\\u0061tic() {}",
   4420     "get st\\u0061tic() {}",
   4421     "set st\\u0061tic(v) {}",
   4422     "static st\\u0061tic() {}",
   4423     "static get st\\u0061tic() {}",
   4424     "static set st\\u0061tic(v) {}",
   4425     "*st\\u0061tic() {}",
   4426     "static *st\\u0061tic() {}",
   4427     NULL};
   4428   // clang-format on
   4429 
   4430   RunParserSyncTest(context_data, class_body_data, kSuccess);
   4431 }
   4432 
   4433 
   4434 TEST(ClassPropertyNameNoErrors) {
   4435   const char* context_data[][2] = {{"(class {", "() {}});"},
   4436                                    {"(class { get ", "() {}});"},
   4437                                    {"(class { set ", "(v) {}});"},
   4438                                    {"(class { static ", "() {}});"},
   4439                                    {"(class { static get ", "() {}});"},
   4440                                    {"(class { static set ", "(v) {}});"},
   4441                                    {"(class { *", "() {}});"},
   4442                                    {"(class { static *", "() {}});"},
   4443                                    {"class C {", "() {}}"},
   4444                                    {"class C { get ", "() {}}"},
   4445                                    {"class C { set ", "(v) {}}"},
   4446                                    {"class C { static ", "() {}}"},
   4447                                    {"class C { static get ", "() {}}"},
   4448                                    {"class C { static set ", "(v) {}}"},
   4449                                    {"class C { *", "() {}}"},
   4450                                    {"class C { static *", "() {}}"},
   4451                                    {NULL, NULL}};
   4452   const char* name_data[] = {
   4453     "42",
   4454     "42.5",
   4455     "42e2",
   4456     "42e+2",
   4457     "42e-2",
   4458     "null",
   4459     "false",
   4460     "true",
   4461     "'str'",
   4462     "\"str\"",
   4463     "static",
   4464     "get",
   4465     "set",
   4466     "var",
   4467     "const",
   4468     "let",
   4469     "this",
   4470     "class",
   4471     "function",
   4472     "yield",
   4473     "if",
   4474     "else",
   4475     "for",
   4476     "while",
   4477     "do",
   4478     "try",
   4479     "catch",
   4480     "finally",
   4481     NULL};
   4482 
   4483   RunParserSyncTest(context_data, name_data, kSuccess);
   4484 }
   4485 
   4486 
   4487 TEST(ClassExpressionErrors) {
   4488   const char* context_data[][2] = {{"(", ");"},
   4489                                    {"var C = ", ";"},
   4490                                    {"bar, ", ";"},
   4491                                    {NULL, NULL}};
   4492   const char* class_data[] = {
   4493     "class",
   4494     "class name",
   4495     "class name extends",
   4496     "class extends",
   4497     "class {",
   4498     "class { m }",
   4499     "class { m; n }",
   4500     "class { m: 1 }",
   4501     "class { m(); n() }",
   4502     "class { get m }",
   4503     "class { get m() }",
   4504     "class { get m() { }",
   4505     "class { set m() {} }",  // Missing required parameter.
   4506     "class { m() {}, n() {} }",  // No commas allowed.
   4507     NULL};
   4508 
   4509   RunParserSyncTest(context_data, class_data, kError);
   4510 }
   4511 
   4512 
   4513 TEST(ClassDeclarationErrors) {
   4514   const char* context_data[][2] = {{"", ""},
   4515                                    {"{", "}"},
   4516                                    {"if (true) {", "}"},
   4517                                    {NULL, NULL}};
   4518   const char* class_data[] = {
   4519     "class",
   4520     "class name",
   4521     "class name extends",
   4522     "class extends",
   4523     "class name {",
   4524     "class name { m }",
   4525     "class name { m; n }",
   4526     "class name { m: 1 }",
   4527     "class name { m(); n() }",
   4528     "class name { get x }",
   4529     "class name { get x() }",
   4530     "class name { set x() {) }",  // missing required param
   4531     "class {}",  // Name is required for declaration
   4532     "class extends base {}",
   4533     "class name { *",
   4534     "class name { * }",
   4535     "class name { *; }",
   4536     "class name { *get x() {} }",
   4537     "class name { *set x(_) {} }",
   4538     "class name { *static m() {} }",
   4539     NULL};
   4540 
   4541   RunParserSyncTest(context_data, class_data, kError);
   4542 }
   4543 
   4544 
   4545 TEST(ClassNameErrors) {
   4546   const char* context_data[][2] = {{"class ", "{}"},
   4547                                    {"(class ", "{});"},
   4548                                    {"'use strict'; class ", "{}"},
   4549                                    {"'use strict'; (class ", "{});"},
   4550                                    {NULL, NULL}};
   4551   const char* class_name[] = {
   4552     "arguments",
   4553     "eval",
   4554     "implements",
   4555     "interface",
   4556     "let",
   4557     "package",
   4558     "private",
   4559     "protected",
   4560     "public",
   4561     "static",
   4562     "var",
   4563     "yield",
   4564     NULL};
   4565 
   4566   RunParserSyncTest(context_data, class_name, kError);
   4567 }
   4568 
   4569 
   4570 TEST(ClassGetterParamNameErrors) {
   4571   const char* context_data[][2] = {
   4572     {"class C { get name(", ") {} }"},
   4573     {"(class { get name(", ") {} });"},
   4574     {"'use strict'; class C { get name(", ") {} }"},
   4575     {"'use strict'; (class { get name(", ") {} })"},
   4576     {NULL, NULL}
   4577   };
   4578 
   4579   const char* class_name[] = {
   4580     "arguments",
   4581     "eval",
   4582     "implements",
   4583     "interface",
   4584     "let",
   4585     "package",
   4586     "private",
   4587     "protected",
   4588     "public",
   4589     "static",
   4590     "var",
   4591     "yield",
   4592     NULL};
   4593 
   4594   RunParserSyncTest(context_data, class_name, kError);
   4595 }
   4596 
   4597 
   4598 TEST(ClassStaticPrototypeErrors) {
   4599   const char* context_data[][2] = {{"class C {", "}"},
   4600                                    {"(class {", "});"},
   4601                                    {NULL, NULL}};
   4602 
   4603   const char* class_body_data[] = {
   4604     "static prototype() {}",
   4605     "static get prototype() {}",
   4606     "static set prototype(_) {}",
   4607     "static *prototype() {}",
   4608     "static 'prototype'() {}",
   4609     "static *'prototype'() {}",
   4610     "static prot\\u006ftype() {}",
   4611     "static 'prot\\u006ftype'() {}",
   4612     "static get 'prot\\u006ftype'() {}",
   4613     "static set 'prot\\u006ftype'(_) {}",
   4614     "static *'prot\\u006ftype'() {}",
   4615     NULL};
   4616 
   4617   RunParserSyncTest(context_data, class_body_data, kError);
   4618 }
   4619 
   4620 
   4621 TEST(ClassSpecialConstructorErrors) {
   4622   const char* context_data[][2] = {{"class C {", "}"},
   4623                                    {"(class {", "});"},
   4624                                    {NULL, NULL}};
   4625 
   4626   const char* class_body_data[] = {
   4627     "get constructor() {}",
   4628     "get constructor(_) {}",
   4629     "*constructor() {}",
   4630     "get 'constructor'() {}",
   4631     "*'constructor'() {}",
   4632     "get c\\u006fnstructor() {}",
   4633     "*c\\u006fnstructor() {}",
   4634     "get 'c\\u006fnstructor'() {}",
   4635     "get 'c\\u006fnstructor'(_) {}",
   4636     "*'c\\u006fnstructor'() {}",
   4637     NULL};
   4638 
   4639   RunParserSyncTest(context_data, class_body_data, kError);
   4640 }
   4641 
   4642 
   4643 TEST(ClassConstructorNoErrors) {
   4644   const char* context_data[][2] = {{"class C {", "}"},
   4645                                    {"(class {", "});"},
   4646                                    {NULL, NULL}};
   4647 
   4648   const char* class_body_data[] = {
   4649     "constructor() {}",
   4650     "static constructor() {}",
   4651     "static get constructor() {}",
   4652     "static set constructor(_) {}",
   4653     "static *constructor() {}",
   4654     NULL};
   4655 
   4656   RunParserSyncTest(context_data, class_body_data, kSuccess);
   4657 }
   4658 
   4659 
   4660 TEST(ClassMultipleConstructorErrors) {
   4661   const char* context_data[][2] = {{"class C {", "}"},
   4662                                    {"(class {", "});"},
   4663                                    {NULL, NULL}};
   4664 
   4665   const char* class_body_data[] = {
   4666     "constructor() {}; constructor() {}",
   4667     NULL};
   4668 
   4669   RunParserSyncTest(context_data, class_body_data, kError);
   4670 }
   4671 
   4672 
   4673 TEST(ClassMultiplePropertyNamesNoErrors) {
   4674   const char* context_data[][2] = {{"class C {", "}"},
   4675                                    {"(class {", "});"},
   4676                                    {NULL, NULL}};
   4677 
   4678   const char* class_body_data[] = {
   4679     "constructor() {}; static constructor() {}",
   4680     "m() {}; static m() {}",
   4681     "m() {}; m() {}",
   4682     "static m() {}; static m() {}",
   4683     "get m() {}; set m(_) {}; get m() {}; set m(_) {};",
   4684     NULL};
   4685 
   4686   RunParserSyncTest(context_data, class_body_data, kSuccess);
   4687 }
   4688 
   4689 
   4690 TEST(ClassesAreStrictErrors) {
   4691   const char* context_data[][2] = {{"", ""},
   4692                                    {"(", ");"},
   4693                                    {NULL, NULL}};
   4694 
   4695   const char* class_body_data[] = {
   4696     "class C { method() { with ({}) {} } }",
   4697     "class C extends function() { with ({}) {} } {}",
   4698     "class C { *method() { with ({}) {} } }",
   4699     NULL};
   4700 
   4701   RunParserSyncTest(context_data, class_body_data, kError);
   4702 }
   4703 
   4704 
   4705 TEST(ObjectLiteralPropertyShorthandKeywordsError) {
   4706   const char* context_data[][2] = {{"({", "});"},
   4707                                    {"'use strict'; ({", "});"},
   4708                                    {NULL, NULL}};
   4709 
   4710   const char* name_data[] = {
   4711     "break",
   4712     "case",
   4713     "catch",
   4714     "class",
   4715     "const",
   4716     "continue",
   4717     "debugger",
   4718     "default",
   4719     "delete",
   4720     "do",
   4721     "else",
   4722     "enum",
   4723     "export",
   4724     "extends",
   4725     "false",
   4726     "finally",
   4727     "for",
   4728     "function",
   4729     "if",
   4730     "import",
   4731     "in",
   4732     "instanceof",
   4733     "new",
   4734     "null",
   4735     "return",
   4736     "super",
   4737     "switch",
   4738     "this",
   4739     "throw",
   4740     "true",
   4741     "try",
   4742     "typeof",
   4743     "var",
   4744     "void",
   4745     "while",
   4746     "with",
   4747     NULL
   4748   };
   4749 
   4750   RunParserSyncTest(context_data, name_data, kError);
   4751 }
   4752 
   4753 
   4754 TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
   4755   const char* context_data[][2] = {{"({", "});"},
   4756                                    {NULL, NULL}};
   4757 
   4758   const char* name_data[] = {
   4759     "implements",
   4760     "interface",
   4761     "let",
   4762     "package",
   4763     "private",
   4764     "protected",
   4765     "public",
   4766     "static",
   4767     "yield",
   4768     NULL
   4769   };
   4770 
   4771   RunParserSyncTest(context_data, name_data, kSuccess);
   4772 
   4773   const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
   4774                                           {NULL, NULL}};
   4775   RunParserSyncTest(context_strict_data, name_data, kError);
   4776 }
   4777 
   4778 
   4779 TEST(ObjectLiteralPropertyShorthandError) {
   4780   const char* context_data[][2] = {{"({", "});"},
   4781                                    {"'use strict'; ({", "});"},
   4782                                    {NULL, NULL}};
   4783 
   4784   const char* name_data[] = {
   4785     "1",
   4786     "1.2",
   4787     "0",
   4788     "0.1",
   4789     "1.0",
   4790     "1e1",
   4791     "0x1",
   4792     "\"s\"",
   4793     "'s'",
   4794     NULL
   4795   };
   4796 
   4797   RunParserSyncTest(context_data, name_data, kError);
   4798 }
   4799 
   4800 
   4801 TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
   4802   const char* context_data[][2] = {{"", ""},
   4803                                    {NULL, NULL}};
   4804 
   4805   const char* name_data[] = {
   4806     "function* g() { ({yield}); }",
   4807     NULL
   4808   };
   4809 
   4810   RunParserSyncTest(context_data, name_data, kError);
   4811 }
   4812 
   4813 
   4814 TEST(ConstParsingInForIn) {
   4815   const char* context_data[][2] = {{"'use strict';", ""},
   4816                                    {"function foo(){ 'use strict';", "}"},
   4817                                    {NULL, NULL}};
   4818 
   4819   const char* data[] = {
   4820       "for(const x = 1; ; ) {}",
   4821       "for(const x = 1, y = 2;;){}",
   4822       "for(const x in [1,2,3]) {}",
   4823       "for(const x of [1,2,3]) {}",
   4824       NULL};
   4825   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0);
   4826 }
   4827 
   4828 
   4829 TEST(StatementParsingInForIn) {
   4830   const char* context_data[][2] = {{"", ""},
   4831                                    {"'use strict';", ""},
   4832                                    {"function foo(){ 'use strict';", "}"},
   4833                                    {NULL, NULL}};
   4834 
   4835   const char* data[] = {"for(x in {}, {}) {}", "for(var x in {}, {}) {}",
   4836                         "for(let x in {}, {}) {}", "for(const x in {}, {}) {}",
   4837                         NULL};
   4838 
   4839   RunParserSyncTest(context_data, data, kSuccess);
   4840 }
   4841 
   4842 
   4843 TEST(ConstParsingInForInError) {
   4844   const char* context_data[][2] = {{"'use strict';", ""},
   4845                                    {"function foo(){ 'use strict';", "}"},
   4846                                    {NULL, NULL}};
   4847 
   4848   const char* data[] = {
   4849       "for(const x,y = 1; ; ) {}",
   4850       "for(const x = 4 in [1,2,3]) {}",
   4851       "for(const x = 4, y in [1,2,3]) {}",
   4852       "for(const x = 4 of [1,2,3]) {}",
   4853       "for(const x = 4, y of [1,2,3]) {}",
   4854       "for(const x = 1, y = 2 in []) {}",
   4855       "for(const x,y in []) {}",
   4856       "for(const x = 1, y = 2 of []) {}",
   4857       "for(const x,y of []) {}",
   4858       NULL};
   4859   RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0);
   4860 }
   4861 
   4862 
   4863 TEST(InitializedDeclarationsInStrictForInError) {
   4864   const char* context_data[][2] = {{"'use strict';", ""},
   4865                                    {"function foo(){ 'use strict';", "}"},
   4866                                    {NULL, NULL}};
   4867 
   4868   const char* data[] = {
   4869       "for (var i = 1 in {}) {}",
   4870       "for (var i = void 0 in [1, 2, 3]) {}",
   4871       "for (let i = 1 in {}) {}",
   4872       "for (let i = void 0 in [1, 2, 3]) {}",
   4873       "for (const i = 1 in {}) {}",
   4874       "for (const i = void 0 in [1, 2, 3]) {}",
   4875       NULL};
   4876   RunParserSyncTest(context_data, data, kError);
   4877 }
   4878 
   4879 
   4880 TEST(InitializedDeclarationsInStrictForOfError) {
   4881   const char* context_data[][2] = {{"'use strict';", ""},
   4882                                    {"function foo(){ 'use strict';", "}"},
   4883                                    {NULL, NULL}};
   4884 
   4885   const char* data[] = {
   4886       "for (var i = 1 of {}) {}",
   4887       "for (var i = void 0 of [1, 2, 3]) {}",
   4888       "for (let i = 1 of {}) {}",
   4889       "for (let i = void 0 of [1, 2, 3]) {}",
   4890       "for (const i = 1 of {}) {}",
   4891       "for (const i = void 0 of [1, 2, 3]) {}",
   4892       NULL};
   4893   RunParserSyncTest(context_data, data, kError);
   4894 }
   4895 
   4896 
   4897 TEST(InitializedDeclarationsInSloppyForInError) {
   4898   const char* context_data[][2] = {{"", ""},
   4899                                    {"function foo(){", "}"},
   4900                                    {NULL, NULL}};
   4901 
   4902   const char* data[] = {
   4903       "for (var i = 1 in {}) {}",
   4904       "for (var i = void 0 in [1, 2, 3]) {}",
   4905       NULL};
   4906   // TODO(caitp): This should be an error in sloppy mode.
   4907   RunParserSyncTest(context_data, data, kSuccess);
   4908 }
   4909 
   4910 
   4911 TEST(InitializedDeclarationsInSloppyForOfError) {
   4912   const char* context_data[][2] = {{"", ""},
   4913                                    {"function foo(){", "}"},
   4914                                    {NULL, NULL}};
   4915 
   4916   const char* data[] = {
   4917       "for (var i = 1 of {}) {}",
   4918       "for (var i = void 0 of [1, 2, 3]) {}",
   4919       NULL};
   4920   RunParserSyncTest(context_data, data, kError);
   4921 }
   4922 
   4923 
   4924 TEST(ForInMultipleDeclarationsError) {
   4925   const char* context_data[][2] = {{"", ""},
   4926                                    {"function foo(){", "}"},
   4927                                    {"'use strict';", ""},
   4928                                    {"function foo(){ 'use strict';", "}"},
   4929                                    {NULL, NULL}};
   4930 
   4931   const char* data[] = {
   4932       "for (var i, j in {}) {}",
   4933       "for (var i, j in [1, 2, 3]) {}",
   4934       "for (var i, j = 1 in {}) {}",
   4935       "for (var i, j = void 0 in [1, 2, 3]) {}",
   4936 
   4937       "for (let i, j in {}) {}",
   4938       "for (let i, j in [1, 2, 3]) {}",
   4939       "for (let i, j = 1 in {}) {}",
   4940       "for (let i, j = void 0 in [1, 2, 3]) {}",
   4941 
   4942       "for (const i, j in {}) {}",
   4943       "for (const i, j in [1, 2, 3]) {}",
   4944       "for (const i, j = 1 in {}) {}",
   4945       "for (const i, j = void 0 in [1, 2, 3]) {}",
   4946       NULL};
   4947   RunParserSyncTest(context_data, data, kError);
   4948 }
   4949 
   4950 
   4951 TEST(ForOfMultipleDeclarationsError) {
   4952   const char* context_data[][2] = {{"", ""},
   4953                                    {"function foo(){", "}"},
   4954                                    {"'use strict';", ""},
   4955                                    {"function foo(){ 'use strict';", "}"},
   4956                                    {NULL, NULL}};
   4957 
   4958   const char* data[] = {
   4959       "for (var i, j of {}) {}",
   4960       "for (var i, j of [1, 2, 3]) {}",
   4961       "for (var i, j = 1 of {}) {}",
   4962       "for (var i, j = void 0 of [1, 2, 3]) {}",
   4963 
   4964       "for (let i, j of {}) {}",
   4965       "for (let i, j of [1, 2, 3]) {}",
   4966       "for (let i, j = 1 of {}) {}",
   4967       "for (let i, j = void 0 of [1, 2, 3]) {}",
   4968 
   4969       "for (const i, j of {}) {}",
   4970       "for (const i, j of [1, 2, 3]) {}",
   4971       "for (const i, j = 1 of {}) {}",
   4972       "for (const i, j = void 0 of [1, 2, 3]) {}",
   4973       NULL};
   4974   RunParserSyncTest(context_data, data, kError);
   4975 }
   4976 
   4977 
   4978 TEST(ForInNoDeclarationsError) {
   4979   const char* context_data[][2] = {{"", ""},
   4980                                    {"function foo(){", "}"},
   4981                                    {"'use strict';", ""},
   4982                                    {"function foo(){ 'use strict';", "}"},
   4983                                    {NULL, NULL}};
   4984 
   4985   const char* data[] = {
   4986       "for (var in {}) {}",
   4987       "for (const in {}) {}",
   4988       NULL};
   4989   RunParserSyncTest(context_data, data, kError);
   4990 }
   4991 
   4992 
   4993 TEST(ForOfNoDeclarationsError) {
   4994   const char* context_data[][2] = {{"", ""},
   4995                                    {"function foo(){", "}"},
   4996                                    {"'use strict';", ""},
   4997                                    {"function foo(){ 'use strict';", "}"},
   4998                                    {NULL, NULL}};
   4999 
   5000   const char* data[] = {
   5001       "for (var of [1, 2, 3]) {}",
   5002       "for (const of [1, 2, 3]) {}",
   5003       NULL};
   5004   RunParserSyncTest(context_data, data, kError);
   5005 }
   5006 
   5007 
   5008 TEST(ForOfInOperator) {
   5009   const char* context_data[][2] = {{"", ""},
   5010                                    {"'use strict';", ""},
   5011                                    {"function foo(){ 'use strict';", "}"},
   5012                                    {NULL, NULL}};
   5013 
   5014   const char* data[] = {
   5015       "for(x of 'foo' in {}) {}", "for(var x of 'foo' in {}) {}",
   5016       "for(let x of 'foo' in {}) {}", "for(const x of 'foo' in {}) {}", NULL};
   5017 
   5018   RunParserSyncTest(context_data, data, kSuccess);
   5019 }
   5020 
   5021 
   5022 TEST(ForOfYieldIdentifier) {
   5023   const char* context_data[][2] = {{"", ""}, {NULL, NULL}};
   5024 
   5025   const char* data[] = {"for(x of yield) {}", "for(var x of yield) {}",
   5026                         "for(let x of yield) {}", "for(const x of yield) {}",
   5027                         NULL};
   5028 
   5029   RunParserSyncTest(context_data, data, kSuccess);
   5030 }
   5031 
   5032 
   5033 TEST(ForOfYieldExpression) {
   5034   const char* context_data[][2] = {{"", ""},
   5035                                    {"'use strict';", ""},
   5036                                    {"function foo(){ 'use strict';", "}"},
   5037                                    {NULL, NULL}};
   5038 
   5039   const char* data[] = {"function* g() { for(x of yield) {} }",
   5040                         "function* g() { for(var x of yield) {} }",
   5041                         "function* g() { for(let x of yield) {} }",
   5042                         "function* g() { for(const x of yield) {} }", NULL};
   5043 
   5044   RunParserSyncTest(context_data, data, kSuccess);
   5045 }
   5046 
   5047 
   5048 TEST(ForOfExpressionError) {
   5049   const char* context_data[][2] = {{"", ""},
   5050                                    {"'use strict';", ""},
   5051                                    {"function foo(){ 'use strict';", "}"},
   5052                                    {NULL, NULL}};
   5053 
   5054   const char* data[] = {
   5055       "for(x of [], []) {}", "for(var x of [], []) {}",
   5056       "for(let x of [], []) {}", "for(const x of [], []) {}",
   5057 
   5058       // AssignmentExpression should be validated statically:
   5059       "for(x of { y = 23 }) {}", "for(var x of { y = 23 }) {}",
   5060       "for(let x of { y = 23 }) {}", "for(const x of { y = 23 }) {}", NULL};
   5061 
   5062   RunParserSyncTest(context_data, data, kError);
   5063 }
   5064 
   5065 
   5066 TEST(InvalidUnicodeEscapes) {
   5067   const char* context_data[][2] = {{"", ""},
   5068                                    {"'use strict';", ""},
   5069                                    {NULL, NULL}};
   5070   const char* data[] = {
   5071     "var foob\\u123r = 0;",
   5072     "var \\u123roo = 0;",
   5073     "\"foob\\u123rr\"",
   5074     // No escapes allowed in regexp flags
   5075     "/regex/\\u0069g",
   5076     "/regex/\\u006g",
   5077     // Braces gone wrong
   5078     "var foob\\u{c481r = 0;",
   5079     "var foob\\uc481}r = 0;",
   5080     "var \\u{0052oo = 0;",
   5081     "var \\u0052}oo = 0;",
   5082     "\"foob\\u{c481r\"",
   5083     "var foob\\u{}ar = 0;",
   5084     // Too high value for the unicode escape
   5085     "\"\\u{110000}\"",
   5086     // Not an unicode escape
   5087     "var foob\\v1234r = 0;",
   5088     "var foob\\U1234r = 0;",
   5089     "var foob\\v{1234}r = 0;",
   5090     "var foob\\U{1234}r = 0;",
   5091     NULL};
   5092   RunParserSyncTest(context_data, data, kError);
   5093 }
   5094 
   5095 
   5096 TEST(UnicodeEscapes) {
   5097   const char* context_data[][2] = {{"", ""},
   5098                                    {"'use strict';", ""},
   5099                                    {NULL, NULL}};
   5100   const char* data[] = {
   5101     // Identifier starting with escape
   5102     "var \\u0052oo = 0;",
   5103     "var \\u{0052}oo = 0;",
   5104     "var \\u{52}oo = 0;",
   5105     "var \\u{00000000052}oo = 0;",
   5106     // Identifier with an escape but not starting with an escape
   5107     "var foob\\uc481r = 0;",
   5108     "var foob\\u{c481}r = 0;",
   5109     // String with an escape
   5110     "\"foob\\uc481r\"",
   5111     "\"foob\\{uc481}r\"",
   5112     // This character is a valid unicode character, representable as a surrogate
   5113     // pair, not representable as 4 hex digits.
   5114     "\"foo\\u{10e6d}\"",
   5115     // Max value for the unicode escape
   5116     "\"\\u{10ffff}\"",
   5117     NULL};
   5118   RunParserSyncTest(context_data, data, kSuccess);
   5119 }
   5120 
   5121 
   5122 TEST(ScanTemplateLiterals) {
   5123   const char* context_data[][2] = {{"'use strict';", ""},
   5124                                    {"function foo(){ 'use strict';"
   5125                                     "  var a, b, c; return ", "}"},
   5126                                    {NULL, NULL}};
   5127 
   5128   const char* data[] = {
   5129       "``",
   5130       "`no-subst-template`",
   5131       "`template-head${a}`",
   5132       "`${a}`",
   5133       "`${a}template-tail`",
   5134       "`template-head${a}template-tail`",
   5135       "`${a}${b}${c}`",
   5136       "`a${a}b${b}c${c}`",
   5137       "`${a}a${b}b${c}c`",
   5138       "`foo\n\nbar\r\nbaz`",
   5139       "`foo\n\n${  bar  }\r\nbaz`",
   5140       "`foo${a /* comment */}`",
   5141       "`foo${a // comment\n}`",
   5142       "`foo${a \n}`",
   5143       "`foo${a \r\n}`",
   5144       "`foo${a \r}`",
   5145       "`foo${/* comment */ a}`",
   5146       "`foo${// comment\na}`",
   5147       "`foo${\n a}`",
   5148       "`foo${\r\n a}`",
   5149       "`foo${\r a}`",
   5150       "`foo${'a' in a}`",
   5151       NULL};
   5152   RunParserSyncTest(context_data, data, kSuccess);
   5153 }
   5154 
   5155 
   5156 TEST(ScanTaggedTemplateLiterals) {
   5157   const char* context_data[][2] = {{"'use strict';", ""},
   5158                                    {"function foo(){ 'use strict';"
   5159                                     "  function tag() {}"
   5160                                     "  var a, b, c; return ", "}"},
   5161                                    {NULL, NULL}};
   5162 
   5163   const char* data[] = {
   5164       "tag ``",
   5165       "tag `no-subst-template`",
   5166       "tag`template-head${a}`",
   5167       "tag `${a}`",
   5168       "tag `${a}template-tail`",
   5169       "tag   `template-head${a}template-tail`",
   5170       "tag\n`${a}${b}${c}`",
   5171       "tag\r\n`a${a}b${b}c${c}`",
   5172       "tag    `${a}a${b}b${c}c`",
   5173       "tag\t`foo\n\nbar\r\nbaz`",
   5174       "tag\r`foo\n\n${  bar  }\r\nbaz`",
   5175       "tag`foo${a /* comment */}`",
   5176       "tag`foo${a // comment\n}`",
   5177       "tag`foo${a \n}`",
   5178       "tag`foo${a \r\n}`",
   5179       "tag`foo${a \r}`",
   5180       "tag`foo${/* comment */ a}`",
   5181       "tag`foo${// comment\na}`",
   5182       "tag`foo${\n a}`",
   5183       "tag`foo${\r\n a}`",
   5184       "tag`foo${\r a}`",
   5185       "tag`foo${'a' in a}`",
   5186       NULL};
   5187   RunParserSyncTest(context_data, data, kSuccess);
   5188 }
   5189 
   5190 
   5191 TEST(TemplateMaterializedLiterals) {
   5192   const char* context_data[][2] = {
   5193     {
   5194       "'use strict';\n"
   5195       "function tag() {}\n"
   5196       "var a, b, c;\n"
   5197       "(", ")"
   5198     },
   5199     {NULL, NULL}
   5200   };
   5201 
   5202   const char* data[] = {
   5203     "tag``",
   5204     "tag`a`",
   5205     "tag`a${1}b`",
   5206     "tag`a${1}b${2}c`",
   5207     "``",
   5208     "`a`",
   5209     "`a${1}b`",
   5210     "`a${1}b${2}c`",
   5211     NULL
   5212   };
   5213 
   5214   RunParserSyncTest(context_data, data, kSuccess);
   5215 }
   5216 
   5217 
   5218 TEST(ScanUnterminatedTemplateLiterals) {
   5219   const char* context_data[][2] = {{"'use strict';", ""},
   5220                                    {"function foo(){ 'use strict';"
   5221                                     "  var a, b, c; return ", "}"},
   5222                                    {NULL, NULL}};
   5223 
   5224   const char* data[] = {
   5225       "`no-subst-template",
   5226       "`template-head${a}",
   5227       "`${a}template-tail",
   5228       "`template-head${a}template-tail",
   5229       "`${a}${b}${c}",
   5230       "`a${a}b${b}c${c}",
   5231       "`${a}a${b}b${c}c",
   5232       "`foo\n\nbar\r\nbaz",
   5233       "`foo\n\n${  bar  }\r\nbaz",
   5234       "`foo${a /* comment } */`",
   5235       "`foo${a /* comment } `*/",
   5236       "`foo${a // comment}`",
   5237       "`foo${a \n`",
   5238       "`foo${a \r\n`",
   5239       "`foo${a \r`",
   5240       "`foo${/* comment */ a`",
   5241       "`foo${// commenta}`",
   5242       "`foo${\n a`",
   5243       "`foo${\r\n a`",
   5244       "`foo${\r a`",
   5245       "`foo${fn(}`",
   5246       "`foo${1 if}`",
   5247       NULL};
   5248   RunParserSyncTest(context_data, data, kError);
   5249 }
   5250 
   5251 
   5252 TEST(TemplateLiteralsIllegalTokens) {
   5253   const char* context_data[][2] = {{"'use strict';", ""},
   5254                                    {"function foo(){ 'use strict';"
   5255                                     "  var a, b, c; return ", "}"},
   5256                                    {NULL, NULL}};
   5257   const char* data[] = {
   5258       "`hello\\x`",
   5259       "`hello\\x${1}`",
   5260       "`hello${1}\\x`",
   5261       "`hello${1}\\x${2}`",
   5262       "`hello\\x\n`",
   5263       "`hello\\x\n${1}`",
   5264       "`hello${1}\\x\n`",
   5265       "`hello${1}\\x\n${2}`",
   5266       NULL};
   5267 
   5268   RunParserSyncTest(context_data, data, kError);
   5269 }
   5270 
   5271 
   5272 TEST(ParseRestParameters) {
   5273   const char* context_data[][2] = {{"'use strict';(function(",
   5274                                     "){ return args;})(1, [], /regexp/, 'str',"
   5275                                     "function(){});"},
   5276                                    {"(function(", "){ return args;})(1, [],"
   5277                                     "/regexp/, 'str', function(){});"},
   5278                                   {NULL, NULL}};
   5279 
   5280   const char* data[] = {"...args",
   5281                         "a, ...args",
   5282                         "...   args",
   5283                         "a, ...   args",
   5284                         "...\targs",
   5285                         "a, ...\targs",
   5286                         "...\r\nargs",
   5287                         "a, ...\r\nargs",
   5288                         "...\rargs",
   5289                         "a, ...\rargs",
   5290                         "...\t\n\t\t\n  args",
   5291                         "a, ...  \n  \n  args",
   5292                         "...{ length, 0: a, 1: b}",
   5293                         "...{}",
   5294                         "...[a, b]",
   5295                         "...[]",
   5296                         "...[...[a, b, ...c]]",
   5297                         NULL};
   5298   RunParserSyncTest(context_data, data, kSuccess);
   5299 }
   5300 
   5301 
   5302 TEST(ParseRestParametersErrors) {
   5303   const char* context_data[][2] = {{"'use strict';(function(",
   5304                                     "){ return args;}(1, [], /regexp/, 'str',"
   5305                                     "function(){});"},
   5306                                    {"(function(", "){ return args;}(1, [],"
   5307                                     "/regexp/, 'str', function(){});"},
   5308                                    {NULL, NULL}};
   5309 
   5310   const char* data[] = {
   5311       "...args, b",
   5312       "a, ...args, b",
   5313       "...args,   b",
   5314       "a, ...args,   b",
   5315       "...args,\tb",
   5316       "a,...args\t,b",
   5317       "...args\r\n, b",
   5318       "a, ... args,\r\nb",
   5319       "...args\r,b",
   5320       "a, ... args,\rb",
   5321       "...args\t\n\t\t\n,  b",
   5322       "a, ... args,  \n  \n  b",
   5323       "a, a, ...args",
   5324       "a,\ta, ...args",
   5325       "a,\ra, ...args",
   5326       "a,\na, ...args",
   5327       NULL};
   5328   RunParserSyncTest(context_data, data, kError);
   5329 }
   5330 
   5331 
   5332 TEST(RestParameterInSetterMethodError) {
   5333   const char* context_data[][2] = {
   5334       {"'use strict';({ set prop(", ") {} }).prop = 1;"},
   5335       {"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
   5336       {"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
   5337       {"({ set prop(", ") {} }).prop = 1;"},
   5338       {"(class { static set prop(", ") {} }).prop = 1;"},
   5339       {"(new (class { set prop(", ") {} })).prop = 1;"},
   5340       {nullptr, nullptr}};
   5341   const char* data[] = {"...a", "...arguments", "...eval", nullptr};
   5342 
   5343   RunParserSyncTest(context_data, data, kError);
   5344 }
   5345 
   5346 
   5347 TEST(RestParametersEvalArguments) {
   5348   // clang-format off
   5349   const char* strict_context_data[][2] =
   5350       {{"'use strict';(function(",
   5351         "){ return;})(1, [], /regexp/, 'str',function(){});"},
   5352        {NULL, NULL}};
   5353   const char* sloppy_context_data[][2] =
   5354       {{"(function(",
   5355         "){ return;})(1, [],/regexp/, 'str', function(){});"},
   5356        {NULL, NULL}};
   5357 
   5358   const char* data[] = {
   5359       "...eval",
   5360       "eval, ...args",
   5361       "...arguments",
   5362       // See https://bugs.chromium.org/p/v8/issues/detail?id=4577
   5363       // "arguments, ...args",
   5364       NULL};
   5365   // clang-format on
   5366 
   5367   // Fail in strict mode
   5368   RunParserSyncTest(strict_context_data, data, kError);
   5369 
   5370   // OK in sloppy mode
   5371   RunParserSyncTest(sloppy_context_data, data, kSuccess);
   5372 }
   5373 
   5374 
   5375 TEST(RestParametersDuplicateEvalArguments) {
   5376   const char* context_data[][2] =
   5377       {{"'use strict';(function(",
   5378         "){ return;})(1, [], /regexp/, 'str',function(){});"},
   5379        {"(function(",
   5380         "){ return;})(1, [],/regexp/, 'str', function(){});"},
   5381        {NULL, NULL}};
   5382 
   5383   const char* data[] = {
   5384       "eval, ...eval",
   5385       "eval, eval, ...args",
   5386       "arguments, ...arguments",
   5387       "arguments, arguments, ...args",
   5388       NULL};
   5389 
   5390   // In strict mode, the error is using "eval" or "arguments" as parameter names
   5391   // In sloppy mode, the error is that eval / arguments are duplicated
   5392   RunParserSyncTest(context_data, data, kError);
   5393 }
   5394 
   5395 
   5396 TEST(SpreadCall) {
   5397   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
   5398                                    {"function fn() {} fn(", ");"},
   5399                                    {NULL, NULL}};
   5400 
   5401   const char* data[] = {
   5402       "...([1, 2, 3])", "...'123', ...'456'", "...new Set([1, 2, 3]), 4",
   5403       "1, ...[2, 3], 4", "...Array(...[1,2,3,4])", "...NaN",
   5404       "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89'",
   5405       "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89', 10",
   5406       "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9",
   5407       "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9, ...[10]", NULL};
   5408 
   5409   RunParserSyncTest(context_data, data, kSuccess);
   5410 }
   5411 
   5412 
   5413 TEST(SpreadCallErrors) {
   5414   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
   5415                                    {"function fn() {} fn(", ");"},
   5416                                    {NULL, NULL}};
   5417 
   5418   const char* data[] = {"(...[1, 2, 3])", "......[1,2,3]", NULL};
   5419 
   5420   RunParserSyncTest(context_data, data, kError);
   5421 }
   5422 
   5423 
   5424 TEST(BadRestSpread) {
   5425   const char* context_data[][2] = {{"function fn() { 'use strict';", "} fn();"},
   5426                                    {"function fn() { ", "} fn();"},
   5427                                    {NULL, NULL}};
   5428   const char* data[] = {"return ...[1,2,3];",     "var ...x = [1,2,3];",
   5429                         "var [...x,] = [1,2,3];", "var [...x, y] = [1,2,3];",
   5430                         "var {...x} = [1,2,3];",  "var { x } = {x: ...[1,2,3]}",
   5431                         NULL};
   5432   RunParserSyncTest(context_data, data, kError);
   5433 }
   5434 
   5435 
   5436 TEST(LexicalScopingSloppyMode) {
   5437   const char* context_data[][2] = {
   5438       {"", ""},
   5439       {"function f() {", "}"},
   5440       {"{", "}"},
   5441       {NULL, NULL}};
   5442 
   5443   const char* good_data[] = {
   5444     "let = 1;",
   5445     "for(let = 1;;){}",
   5446     NULL};
   5447   RunParserSyncTest(context_data, good_data, kSuccess);
   5448 }
   5449 
   5450 
   5451 TEST(ComputedPropertyName) {
   5452   const char* context_data[][2] = {{"({[", "]: 1});"},
   5453                                    {"({get [", "]() {}});"},
   5454                                    {"({set [", "](_) {}});"},
   5455                                    {"({[", "]() {}});"},
   5456                                    {"({*[", "]() {}});"},
   5457                                    {"(class {get [", "]() {}});"},
   5458                                    {"(class {set [", "](_) {}});"},
   5459                                    {"(class {[", "]() {}});"},
   5460                                    {"(class {*[", "]() {}});"},
   5461                                    {NULL, NULL}};
   5462   const char* error_data[] = {
   5463     "1, 2",
   5464     "var name",
   5465     NULL};
   5466 
   5467   RunParserSyncTest(context_data, error_data, kError);
   5468 
   5469   const char* name_data[] = {
   5470     "1",
   5471     "1 + 2",
   5472     "'name'",
   5473     "\"name\"",
   5474     "[]",
   5475     "{}",
   5476     NULL};
   5477 
   5478   RunParserSyncTest(context_data, name_data, kSuccess);
   5479 }
   5480 
   5481 
   5482 TEST(ComputedPropertyNameShorthandError) {
   5483   const char* context_data[][2] = {{"({", "});"},
   5484                                    {NULL, NULL}};
   5485   const char* error_data[] = {
   5486     "a: 1, [2]",
   5487     "[1], a: 1",
   5488     NULL};
   5489 
   5490   RunParserSyncTest(context_data, error_data, kError);
   5491 }
   5492 
   5493 
   5494 TEST(BasicImportExportParsing) {
   5495   // clang-format off
   5496   const char* kSources[] = {
   5497       "export let x = 0;",
   5498       "export var y = 0;",
   5499       "export const z = 0;",
   5500       "export function func() { };",
   5501       "export class C { };",
   5502       "export { };",
   5503       "function f() {}; f(); export { f };",
   5504       "var a, b, c; export { a, b as baz, c };",
   5505       "var d, e; export { d as dreary, e, };",
   5506       "export default function f() {}",
   5507       "export default function() {}",
   5508       "export default function*() {}",
   5509       "export default class C {}",
   5510       "export default class {}"
   5511       "export default class extends C {}"
   5512       "export default 42",
   5513       "var x; export default x = 7",
   5514       "export { Q } from 'somemodule.js';",
   5515       "export * from 'somemodule.js';",
   5516       "var foo; export { foo as for };",
   5517       "export { arguments } from 'm.js';",
   5518       "export { for } from 'm.js';",
   5519       "export { yield } from 'm.js'",
   5520       "export { static } from 'm.js'",
   5521       "export { let } from 'm.js'",
   5522       "var a; export { a as b, a as c };",
   5523       "var a; export { a as await };",
   5524       "var a; export { a as enum };",
   5525 
   5526       "import 'somemodule.js';",
   5527       "import { } from 'm.js';",
   5528       "import { a } from 'm.js';",
   5529       "import { a, b as d, c, } from 'm.js';",
   5530       "import * as thing from 'm.js';",
   5531       "import thing from 'm.js';",
   5532       "import thing, * as rest from 'm.js';",
   5533       "import thing, { a, b, c } from 'm.js';",
   5534       "import { arguments as a } from 'm.js';",
   5535       "import { for as f } from 'm.js';",
   5536       "import { yield as y } from 'm.js';",
   5537       "import { static as s } from 'm.js';",
   5538       "import { let as l } from 'm.js';",
   5539   };
   5540   // clang-format on
   5541 
   5542   i::Isolate* isolate = CcTest::i_isolate();
   5543   i::Factory* factory = isolate->factory();
   5544 
   5545   v8::HandleScope handles(CcTest::isolate());
   5546   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   5547   v8::Context::Scope context_scope(context);
   5548 
   5549   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   5550                                         128 * 1024);
   5551 
   5552   for (unsigned i = 0; i < arraysize(kSources); ++i) {
   5553     i::Handle<i::String> source =
   5554         factory->NewStringFromAsciiChecked(kSources[i]);
   5555 
   5556     // Show that parsing as a module works
   5557     {
   5558       i::Handle<i::Script> script = factory->NewScript(source);
   5559       i::Zone zone(CcTest::i_isolate()->allocator());
   5560       i::ParseInfo info(&zone, script);
   5561       i::Parser parser(&info);
   5562       info.set_module();
   5563       if (!parser.Parse(&info)) {
   5564         i::Handle<i::JSObject> exception_handle(
   5565             i::JSObject::cast(isolate->pending_exception()));
   5566         i::Handle<i::String> message_string = i::Handle<i::String>::cast(
   5567             i::JSReceiver::GetProperty(isolate, exception_handle, "message")
   5568                 .ToHandleChecked());
   5569 
   5570         v8::base::OS::Print(
   5571             "Parser failed on:\n"
   5572             "\t%s\n"
   5573             "with error:\n"
   5574             "\t%s\n"
   5575             "However, we expected no error.",
   5576             source->ToCString().get(), message_string->ToCString().get());
   5577         CHECK(false);
   5578       }
   5579     }
   5580 
   5581     // And that parsing a script does not.
   5582     {
   5583       i::Handle<i::Script> script = factory->NewScript(source);
   5584       i::Zone zone(CcTest::i_isolate()->allocator());
   5585       i::ParseInfo info(&zone, script);
   5586       i::Parser parser(&info);
   5587       info.set_global();
   5588       CHECK(!parser.Parse(&info));
   5589     }
   5590   }
   5591 }
   5592 
   5593 
   5594 TEST(ImportExportParsingErrors) {
   5595   // clang-format off
   5596   const char* kErrorSources[] = {
   5597       "export {",
   5598       "var a; export { a",
   5599       "var a; export { a,",
   5600       "var a; export { a, ;",
   5601       "var a; export { a as };",
   5602       "var a, b; export { a as , b};",
   5603       "export }",
   5604       "var foo, bar; export { foo bar };",
   5605       "export { foo };",
   5606       "export { , };",
   5607       "export default;",
   5608       "export default var x = 7;",
   5609       "export default let x = 7;",
   5610       "export default const x = 7;",
   5611       "export *;",
   5612       "export * from;",
   5613       "export { Q } from;",
   5614       "export default from 'module.js';",
   5615       "export { for }",
   5616       "export { for as foo }",
   5617       "export { arguments }",
   5618       "export { arguments as foo }",
   5619       "var a; export { a, a };",
   5620       "var a, b; export { a as b, b };",
   5621       "var a, b; export { a as c, b as c };",
   5622       "export default function f(){}; export default class C {};",
   5623       "export default function f(){}; var a; export { a as default };",
   5624       "export function() {}",
   5625       "export function*() {}",
   5626       "export class {}",
   5627       "export class extends C {}",
   5628 
   5629       "import from;",
   5630       "import from 'm.js';",
   5631       "import { };",
   5632       "import {;",
   5633       "import };",
   5634       "import { , };",
   5635       "import { , } from 'm.js';",
   5636       "import { a } from;",
   5637       "import { a } 'm.js';",
   5638       "import , from 'm.js';",
   5639       "import a , from 'm.js';",
   5640       "import a { b, c } from 'm.js';",
   5641       "import arguments from 'm.js';",
   5642       "import eval from 'm.js';",
   5643       "import { arguments } from 'm.js';",
   5644       "import { eval } from 'm.js';",
   5645       "import { a as arguments } from 'm.js';",
   5646       "import { for } from 'm.js';",
   5647       "import { y as yield } from 'm.js'",
   5648       "import { s as static } from 'm.js'",
   5649       "import { l as let } from 'm.js'",
   5650       "import { a as await } from 'm.js';",
   5651       "import { a as enum } from 'm.js';",
   5652       "import { x }, def from 'm.js';",
   5653       "import def, def2 from 'm.js';",
   5654       "import * as x, def from 'm.js';",
   5655       "import * as x, * as y from 'm.js';",
   5656       "import {x}, {y} from 'm.js';",
   5657       "import * as x, {y} from 'm.js';",
   5658   };
   5659   // clang-format on
   5660 
   5661   i::Isolate* isolate = CcTest::i_isolate();
   5662   i::Factory* factory = isolate->factory();
   5663 
   5664   v8::HandleScope handles(CcTest::isolate());
   5665   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   5666   v8::Context::Scope context_scope(context);
   5667 
   5668   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   5669                                         128 * 1024);
   5670 
   5671   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
   5672     i::Handle<i::String> source =
   5673         factory->NewStringFromAsciiChecked(kErrorSources[i]);
   5674 
   5675     i::Handle<i::Script> script = factory->NewScript(source);
   5676     i::Zone zone(CcTest::i_isolate()->allocator());
   5677     i::ParseInfo info(&zone, script);
   5678     i::Parser parser(&info);
   5679     info.set_module();
   5680     CHECK(!parser.Parse(&info));
   5681   }
   5682 }
   5683 
   5684 TEST(ModuleTopLevelFunctionDecl) {
   5685   // clang-format off
   5686   const char* kErrorSources[] = {
   5687       "function f() {} function f() {}",
   5688       "var f; function f() {}",
   5689       "function f() {} var f;",
   5690       "function* f() {} function* f() {}",
   5691       "var f; function* f() {}",
   5692       "function* f() {} var f;",
   5693       "function f() {} function* f() {}",
   5694       "function* f() {} function f() {}",
   5695   };
   5696   // clang-format on
   5697 
   5698   i::Isolate* isolate = CcTest::i_isolate();
   5699   i::Factory* factory = isolate->factory();
   5700 
   5701   v8::HandleScope handles(CcTest::isolate());
   5702   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   5703   v8::Context::Scope context_scope(context);
   5704 
   5705   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   5706                                         128 * 1024);
   5707 
   5708   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
   5709     i::Handle<i::String> source =
   5710         factory->NewStringFromAsciiChecked(kErrorSources[i]);
   5711 
   5712     i::Handle<i::Script> script = factory->NewScript(source);
   5713     i::Zone zone(CcTest::i_isolate()->allocator());
   5714     i::ParseInfo info(&zone, script);
   5715     i::Parser parser(&info);
   5716     info.set_module();
   5717     CHECK(!parser.Parse(&info));
   5718   }
   5719 }
   5720 
   5721 TEST(ModuleAwaitReserved) {
   5722   // clang-format off
   5723   const char* kErrorSources[] = {
   5724       "await;",
   5725       "await: ;",
   5726       "var await;",
   5727       "var [await] = [];",
   5728       "var { await } = {};",
   5729       "var { x: await } = {};",
   5730       "{ var await; }",
   5731       "let await;",
   5732       "let [await] = [];",
   5733       "let { await } = {};",
   5734       "let { x: await } = {};",
   5735       "{ let await; }",
   5736       "const await = null;",
   5737       "const [await] = [];",
   5738       "const { await } = {};",
   5739       "const { x: await } = {};",
   5740       "{ const await = null; }",
   5741       "function await() {}",
   5742       "function f(await) {}",
   5743       "function* await() {}",
   5744       "function* g(await) {}",
   5745       "(function await() {});",
   5746       "(function (await) {});",
   5747       "(function* await() {});",
   5748       "(function* (await) {});",
   5749       "(await) => {};",
   5750       "await => {};",
   5751       "class await {}",
   5752       "class C { constructor(await) {} }",
   5753       "class C { m(await) {} }",
   5754       "class C { static m(await) {} }",
   5755       "class C { *m(await) {} }",
   5756       "class C { static *m(await) {} }",
   5757       "(class await {})",
   5758       "(class { constructor(await) {} });",
   5759       "(class { m(await) {} });",
   5760       "(class { static m(await) {} });",
   5761       "(class { *m(await) {} });",
   5762       "(class { static *m(await) {} });",
   5763       "({ m(await) {} });",
   5764       "({ *m(await) {} });",
   5765       "({ set p(await) {} });",
   5766       "try {} catch (await) {}",
   5767       "try {} catch (await) {} finally {}",
   5768       NULL
   5769   };
   5770   // clang-format on
   5771   const char* context_data[][2] = {{"", ""}, {NULL, NULL}};
   5772 
   5773   RunModuleParserSyncTest(context_data, kErrorSources, kError);
   5774 }
   5775 
   5776 TEST(ModuleAwaitReservedPreParse) {
   5777   const char* context_data[][2] = {{"", ""}, {NULL, NULL}};
   5778   const char* error_data[] = {"function f() { var await = 0; }", NULL};
   5779 
   5780   RunModuleParserSyncTest(context_data, error_data, kError);
   5781 }
   5782 
   5783 TEST(ModuleAwaitPermitted) {
   5784   // clang-format off
   5785   const char* kValidSources[] = {
   5786     "({}).await;",
   5787     "({ await: null });",
   5788     "({ await() {} });",
   5789     "({ get await() {} });",
   5790     "({ set await(x) {} });",
   5791     "(class { await() {} });",
   5792     "(class { static await() {} });",
   5793     "(class { *await() {} });",
   5794     "(class { static *await() {} });",
   5795     NULL
   5796   };
   5797   // clang-format on
   5798   const char* context_data[][2] = {{"", ""}, {NULL, NULL}};
   5799 
   5800   RunModuleParserSyncTest(context_data, kValidSources, kSuccess);
   5801 }
   5802 
   5803 TEST(EnumReserved) {
   5804   // clang-format off
   5805   const char* kErrorSources[] = {
   5806       "enum;",
   5807       "enum: ;",
   5808       "var enum;",
   5809       "var [enum] = [];",
   5810       "var { enum } = {};",
   5811       "var { x: enum } = {};",
   5812       "{ var enum; }",
   5813       "let enum;",
   5814       "let [enum] = [];",
   5815       "let { enum } = {};",
   5816       "let { x: enum } = {};",
   5817       "{ let enum; }",
   5818       "const enum = null;",
   5819       "const [enum] = [];",
   5820       "const { enum } = {};",
   5821       "const { x: enum } = {};",
   5822       "{ const enum = null; }",
   5823       "function enum() {}",
   5824       "function f(enum) {}",
   5825       "function* enum() {}",
   5826       "function* g(enum) {}",
   5827       "(function enum() {});",
   5828       "(function (enum) {});",
   5829       "(function* enum() {});",
   5830       "(function* (enum) {});",
   5831       "(enum) => {};",
   5832       "enum => {};",
   5833       "class enum {}",
   5834       "class C { constructor(enum) {} }",
   5835       "class C { m(enum) {} }",
   5836       "class C { static m(enum) {} }",
   5837       "class C { *m(enum) {} }",
   5838       "class C { static *m(enum) {} }",
   5839       "(class enum {})",
   5840       "(class { constructor(enum) {} });",
   5841       "(class { m(enum) {} });",
   5842       "(class { static m(enum) {} });",
   5843       "(class { *m(enum) {} });",
   5844       "(class { static *m(enum) {} });",
   5845       "({ m(enum) {} });",
   5846       "({ *m(enum) {} });",
   5847       "({ set p(enum) {} });",
   5848       "try {} catch (enum) {}",
   5849       "try {} catch (enum) {} finally {}",
   5850       NULL
   5851   };
   5852   // clang-format on
   5853   const char* context_data[][2] = {{"", ""}, {NULL, NULL}};
   5854 
   5855   RunModuleParserSyncTest(context_data, kErrorSources, kError);
   5856 }
   5857 
   5858 TEST(ModuleParsingInternals) {
   5859   i::Isolate* isolate = CcTest::i_isolate();
   5860   i::Factory* factory = isolate->factory();
   5861   v8::HandleScope handles(CcTest::isolate());
   5862   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   5863   v8::Context::Scope context_scope(context);
   5864   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   5865                                         128 * 1024);
   5866 
   5867   static const char kSource[] =
   5868       "let x = 5;"
   5869       "export { x as y };"
   5870       "import { q as z } from 'm.js';"
   5871       "import n from 'n.js';"
   5872       "export { a as b } from 'm.js';"
   5873       "export * from 'p.js';"
   5874       "import 'q.js'";
   5875   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
   5876   i::Handle<i::Script> script = factory->NewScript(source);
   5877   i::Zone zone(CcTest::i_isolate()->allocator());
   5878   i::ParseInfo info(&zone, script);
   5879   i::Parser parser(&info);
   5880   info.set_module();
   5881   CHECK(parser.Parse(&info));
   5882   CHECK(i::Compiler::Analyze(&info));
   5883   i::FunctionLiteral* func = info.literal();
   5884   i::Scope* module_scope = func->scope();
   5885   i::Scope* outer_scope = module_scope->outer_scope();
   5886   CHECK(outer_scope->is_script_scope());
   5887   CHECK_NULL(outer_scope->outer_scope());
   5888   CHECK(module_scope->is_module_scope());
   5889   i::ModuleDescriptor* descriptor = module_scope->module();
   5890   CHECK_NOT_NULL(descriptor);
   5891   CHECK_EQ(1, descriptor->Length());
   5892   const i::AstRawString* export_name =
   5893       info.ast_value_factory()->GetOneByteString("y");
   5894   const i::AstRawString* local_name =
   5895       descriptor->LookupLocalExport(export_name, &zone);
   5896   CHECK_NOT_NULL(local_name);
   5897   CHECK(local_name->IsOneByteEqualTo("x"));
   5898   i::ZoneList<i::Declaration*>* declarations = module_scope->declarations();
   5899   CHECK_EQ(3, declarations->length());
   5900   CHECK(declarations->at(0)->proxy()->raw_name()->IsOneByteEqualTo("x"));
   5901   i::ImportDeclaration* import_decl =
   5902       declarations->at(1)->AsImportDeclaration();
   5903   CHECK(import_decl->import_name()->IsOneByteEqualTo("q"));
   5904   CHECK(import_decl->proxy()->raw_name()->IsOneByteEqualTo("z"));
   5905   CHECK(import_decl->module_specifier()->IsOneByteEqualTo("m.js"));
   5906   import_decl = declarations->at(2)->AsImportDeclaration();
   5907   CHECK(import_decl->import_name()->IsOneByteEqualTo("default"));
   5908   CHECK(import_decl->proxy()->raw_name()->IsOneByteEqualTo("n"));
   5909   CHECK(import_decl->module_specifier()->IsOneByteEqualTo("n.js"));
   5910   // TODO(adamk): Add test for indirect exports once they're fully implemented.
   5911   // TODO(adamk): Add test for star exports once they're fully implemented.
   5912   const i::ZoneList<const i::AstRawString*>& requested_modules =
   5913       descriptor->requested_modules();
   5914   CHECK_EQ(4, requested_modules.length());
   5915   CHECK(requested_modules[0]->IsOneByteEqualTo("m.js"));
   5916   CHECK(requested_modules[1]->IsOneByteEqualTo("n.js"));
   5917   CHECK(requested_modules[2]->IsOneByteEqualTo("p.js"));
   5918   CHECK(requested_modules[3]->IsOneByteEqualTo("q.js"));
   5919 }
   5920 
   5921 
   5922 TEST(DuplicateProtoError) {
   5923   const char* context_data[][2] = {
   5924     {"({", "});"},
   5925     {"'use strict'; ({", "});"},
   5926     {NULL, NULL}
   5927   };
   5928   const char* error_data[] = {
   5929     "__proto__: {}, __proto__: {}",
   5930     "__proto__: {}, \"__proto__\": {}",
   5931     "__proto__: {}, \"__\x70roto__\": {}",
   5932     "__proto__: {}, a: 1, __proto__: {}",
   5933     NULL
   5934   };
   5935 
   5936   RunParserSyncTest(context_data, error_data, kError);
   5937 }
   5938 
   5939 
   5940 TEST(DuplicateProtoNoError) {
   5941   const char* context_data[][2] = {
   5942     {"({", "});"},
   5943     {"'use strict'; ({", "});"},
   5944     {NULL, NULL}
   5945   };
   5946   const char* error_data[] = {
   5947     "__proto__: {}, ['__proto__']: {}",
   5948     "__proto__: {}, __proto__() {}",
   5949     "__proto__: {}, get __proto__() {}",
   5950     "__proto__: {}, set __proto__(v) {}",
   5951     "__proto__: {}, __proto__",
   5952     NULL
   5953   };
   5954 
   5955   RunParserSyncTest(context_data, error_data, kSuccess);
   5956 }
   5957 
   5958 
   5959 TEST(DeclarationsError) {
   5960   const char* context_data[][2] = {{"'use strict'; if (true)", ""},
   5961                                    {"'use strict'; if (false) {} else", ""},
   5962                                    {"'use strict'; while (false)", ""},
   5963                                    {"'use strict'; for (;;)", ""},
   5964                                    {"'use strict'; for (x in y)", ""},
   5965                                    {"'use strict'; do ", " while (false)"},
   5966                                    {NULL, NULL}};
   5967 
   5968   const char* statement_data[] = {
   5969     "let x = 1;",
   5970     "const x = 1;",
   5971     "class C {}",
   5972     NULL};
   5973 
   5974   RunParserSyncTest(context_data, statement_data, kError);
   5975 }
   5976 
   5977 
   5978 void TestLanguageMode(const char* source,
   5979                       i::LanguageMode expected_language_mode) {
   5980   i::Isolate* isolate = CcTest::i_isolate();
   5981   i::Factory* factory = isolate->factory();
   5982   v8::HandleScope handles(CcTest::isolate());
   5983   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
   5984   v8::Context::Scope context_scope(context);
   5985   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   5986                                         128 * 1024);
   5987 
   5988   i::Handle<i::Script> script =
   5989       factory->NewScript(factory->NewStringFromAsciiChecked(source));
   5990   i::Zone zone(CcTest::i_isolate()->allocator());
   5991   i::ParseInfo info(&zone, script);
   5992   i::Parser parser(&info);
   5993   info.set_global();
   5994   parser.Parse(&info);
   5995   CHECK(info.literal() != NULL);
   5996   CHECK_EQ(expected_language_mode, info.literal()->language_mode());
   5997 }
   5998 
   5999 
   6000 TEST(LanguageModeDirectives) {
   6001   TestLanguageMode("\"use nothing\"", i::SLOPPY);
   6002   TestLanguageMode("\"use strict\"", i::STRICT);
   6003 
   6004   TestLanguageMode("var x = 1; \"use strict\"", i::SLOPPY);
   6005 
   6006   TestLanguageMode("\"use some future directive\"; \"use strict\";", i::STRICT);
   6007 }
   6008 
   6009 
   6010 TEST(PropertyNameEvalArguments) {
   6011   const char* context_data[][2] = {{"'use strict';", ""},
   6012                                    {NULL, NULL}};
   6013 
   6014   const char* statement_data[] = {
   6015       "({eval: 1})",
   6016       "({arguments: 1})",
   6017       "({eval() {}})",
   6018       "({arguments() {}})",
   6019       "({*eval() {}})",
   6020       "({*arguments() {}})",
   6021       "({get eval() {}})",
   6022       "({get arguments() {}})",
   6023       "({set eval(_) {}})",
   6024       "({set arguments(_) {}})",
   6025 
   6026       "class C {eval() {}}",
   6027       "class C {arguments() {}}",
   6028       "class C {*eval() {}}",
   6029       "class C {*arguments() {}}",
   6030       "class C {get eval() {}}",
   6031       "class C {get arguments() {}}",
   6032       "class C {set eval(_) {}}",
   6033       "class C {set arguments(_) {}}",
   6034 
   6035       "class C {static eval() {}}",
   6036       "class C {static arguments() {}}",
   6037       "class C {static *eval() {}}",
   6038       "class C {static *arguments() {}}",
   6039       "class C {static get eval() {}}",
   6040       "class C {static get arguments() {}}",
   6041       "class C {static set eval(_) {}}",
   6042       "class C {static set arguments(_) {}}",
   6043 
   6044       NULL};
   6045 
   6046   RunParserSyncTest(context_data, statement_data, kSuccess);
   6047 }
   6048 
   6049 
   6050 TEST(FunctionLiteralDuplicateParameters) {
   6051   const char* strict_context_data[][2] =
   6052       {{"'use strict';(function(", "){})();"},
   6053        {"(function(", ") { 'use strict'; })();"},
   6054        {"'use strict'; function fn(", ") {}; fn();"},
   6055        {"function fn(", ") { 'use strict'; }; fn();"},
   6056        {NULL, NULL}};
   6057 
   6058   const char* sloppy_context_data[][2] =
   6059       {{"(function(", "){})();"},
   6060        {"(function(", ") {})();"},
   6061        {"function fn(", ") {}; fn();"},
   6062        {"function fn(", ") {}; fn();"},
   6063        {NULL, NULL}};
   6064 
   6065   const char* data[] = {
   6066       "a, a",
   6067       "a, a, a",
   6068       "b, a, a",
   6069       "a, b, c, c",
   6070       "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, w",
   6071       NULL};
   6072 
   6073   RunParserSyncTest(strict_context_data, data, kError);
   6074   RunParserSyncTest(sloppy_context_data, data, kSuccess);
   6075 }
   6076 
   6077 
   6078 TEST(ArrowFunctionASIErrors) {
   6079   const char* context_data[][2] = {{"'use strict';", ""}, {"", ""},
   6080                                    {NULL, NULL}};
   6081 
   6082   const char* data[] = {
   6083       "(a\n=> a)(1)",
   6084       "(a/*\n*/=> a)(1)",
   6085       "((a)\n=> a)(1)",
   6086       "((a)/*\n*/=> a)(1)",
   6087       "((a, b)\n=> a + b)(1, 2)",
   6088       "((a, b)/*\n*/=> a + b)(1, 2)",
   6089       NULL};
   6090   RunParserSyncTest(context_data, data, kError);
   6091 }
   6092 
   6093 
   6094 TEST(DestructuringPositiveTests) {
   6095   const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
   6096                                    {"var ", " = {};"},
   6097                                    {"'use strict'; const ", " = {};"},
   6098                                    {"function f(", ") {}"},
   6099                                    {"function f(argument1, ", ") {}"},
   6100                                    {"var f = (", ") => {};"},
   6101                                    {"var f = (argument1,", ") => {};"},
   6102                                    {"try {} catch(", ") {}"},
   6103                                    {NULL, NULL}};
   6104 
   6105   // clang-format off
   6106   const char* data[] = {
   6107     "a",
   6108     "{ x : y }",
   6109     "{ x : y = 1 }",
   6110     "{ get, set }",
   6111     "{ get = 1, set = 2 }",
   6112     "[a]",
   6113     "[a = 1]",
   6114     "[a,b,c]",
   6115     "[a, b = 42, c]",
   6116     "{ x : x, y : y }",
   6117     "{ x : x = 1, y : y }",
   6118     "{ x : x, y : y = 42 }",
   6119     "[]",
   6120     "{}",
   6121     "[{x:x, y:y}, [a,b,c]]",
   6122     "[{x:x = 1, y:y = 2}, [a = 3, b = 4, c = 5]]",
   6123     "{x}",
   6124     "{x, y}",
   6125     "{x = 42, y = 15}",
   6126     "[a,,b]",
   6127     "{42 : x}",
   6128     "{42 : x = 42}",
   6129     "{42e-2 : x}",
   6130     "{42e-2 : x = 42}",
   6131     "{x : y, x : z}",
   6132     "{'hi' : x}",
   6133     "{'hi' : x = 42}",
   6134     "{var: x}",
   6135     "{var: x = 42}",
   6136     "{[x] : z}",
   6137     "{[1+1] : z}",
   6138     "{[foo()] : z}",
   6139     "{}",
   6140     "[...rest]",
   6141     "[a,b,...rest]",
   6142     "[a,,...rest]",
   6143     NULL};
   6144   // clang-format on
   6145   RunParserSyncTest(context_data, data, kSuccess);
   6146 }
   6147 
   6148 
   6149 TEST(DestructuringNegativeTests) {
   6150   {  // All modes.
   6151     const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
   6152                                      {"var ", " = {};"},
   6153                                      {"'use strict'; const ", " = {};"},
   6154                                      {"function f(", ") {}"},
   6155                                      {"function f(argument1, ", ") {}"},
   6156                                      {"var f = (", ") => {};"},
   6157                                      {"var f = ", " => {};"},
   6158                                      {"var f = (argument1,", ") => {};"},
   6159                                      {"try {} catch(", ") {}"},
   6160                                      {NULL, NULL}};
   6161 
   6162     // clang-format off
   6163     const char* data[] = {
   6164         "a++",
   6165         "++a",
   6166         "delete a",
   6167         "void a",
   6168         "typeof a",
   6169         "--a",
   6170         "+a",
   6171         "-a",
   6172         "~a",
   6173         "!a",
   6174         "{ x : y++ }",
   6175         "[a++]",
   6176         "(x => y)",
   6177         "a[i]", "a()",
   6178         "a.b",
   6179         "new a",
   6180         "a + a",
   6181         "a - a",
   6182         "a * a",
   6183         "a / a",
   6184         "a == a",
   6185         "a != a",
   6186         "a > a",
   6187         "a < a",
   6188         "a <<< a",
   6189         "a >>> a",
   6190         "function a() {}",
   6191         "a`bcd`",
   6192         "this",
   6193         "null",
   6194         "true",
   6195         "false",
   6196         "1",
   6197         "'abc'",
   6198         "/abc/",
   6199         "`abc`",
   6200         "class {}",
   6201         "{+2 : x}",
   6202         "{-2 : x}",
   6203         "var",
   6204         "[var]",
   6205         "{x : {y : var}}",
   6206         "{x : x = a+}",
   6207         "{x : x = (a+)}",
   6208         "{x : x += a}",
   6209         "{m() {} = 0}",
   6210         "{[1+1]}",
   6211         "[...rest, x]",
   6212         "[a,b,...rest, x]",
   6213         "[a,,...rest, x]",
   6214         "[...rest,]",
   6215         "[a,b,...rest,]",
   6216         "[a,,...rest,]",
   6217         "[...rest,...rest1]",
   6218         "[a,b,...rest,...rest1]",
   6219         "[a,,..rest,...rest1]",
   6220         "[x, y, ...z = 1]",
   6221         "[...z = 1]",
   6222         "[x, y, ...[z] = [1]]",
   6223         "[...[z] = [1]]",
   6224         "{ x : 3 }",
   6225         "{ x : 'foo' }",
   6226         "{ x : /foo/ }",
   6227         "{ x : `foo` }",
   6228         "{ get a() {} }",
   6229         "{ set a() {} }",
   6230         "{ method() {} }",
   6231         "{ *method() {} }",
   6232         NULL};
   6233     // clang-format on
   6234     RunParserSyncTest(context_data, data, kError);
   6235   }
   6236 
   6237   {  // All modes.
   6238     const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
   6239                                      {"var ", " = {};"},
   6240                                      {"'use strict'; const ", " = {};"},
   6241                                      {"function f(", ") {}"},
   6242                                      {"function f(argument1, ", ") {}"},
   6243                                      {"var f = (", ") => {};"},
   6244                                      {"var f = (argument1,", ") => {};"},
   6245                                      {NULL, NULL}};
   6246 
   6247     // clang-format off
   6248     const char* data[] = {
   6249         "x => x",
   6250         "() => x",
   6251         NULL};
   6252     // clang-format on
   6253     RunParserSyncTest(context_data, data, kError);
   6254   }
   6255 
   6256   {  // Strict mode.
   6257     const char* context_data[][2] = {
   6258         {"'use strict'; let ", " = {};"},
   6259         {"'use strict'; const ", " = {};"},
   6260         {"'use strict'; function f(", ") {}"},
   6261         {"'use strict'; function f(argument1, ", ") {}"},
   6262         {NULL, NULL}};
   6263 
   6264     // clang-format off
   6265     const char* data[] = {
   6266       "[eval]",
   6267       "{ a : arguments }",
   6268       "[public]",
   6269       "{ x : private }",
   6270       NULL};
   6271     // clang-format on
   6272     RunParserSyncTest(context_data, data, kError);
   6273   }
   6274 
   6275   {  // 'yield' in generators.
   6276     const char* context_data[][2] = {
   6277         {"function*() { var ", " = {};"},
   6278         {"function*() { 'use strict'; let ", " = {};"},
   6279         {"function*() { 'use strict'; const ", " = {};"},
   6280         {NULL, NULL}};
   6281 
   6282     // clang-format off
   6283     const char* data[] = {
   6284       "yield",
   6285       "[yield]",
   6286       "{ x : yield }",
   6287       NULL};
   6288     // clang-format on
   6289     RunParserSyncTest(context_data, data, kError);
   6290   }
   6291 
   6292   { // Declaration-specific errors
   6293     const char* context_data[][2] = {{"'use strict'; var ", ""},
   6294                                      {"'use strict'; let ", ""},
   6295                                      {"'use strict'; const ", ""},
   6296                                      {"'use strict'; for (var ", ";;) {}"},
   6297                                      {"'use strict'; for (let ", ";;) {}"},
   6298                                      {"'use strict'; for (const ", ";;) {}"},
   6299                                      {"var ", ""},
   6300                                      {"let ", ""},
   6301                                      {"const ", ""},
   6302                                      {"for (var ", ";;) {}"},
   6303                                      {"for (let ", ";;) {}"},
   6304                                      {"for (const ", ";;) {}"},
   6305                                      {NULL, NULL}};
   6306 
   6307     // clang-format off
   6308     const char* data[] = {
   6309       "{ a }",
   6310       "[ a ]",
   6311       NULL};
   6312     // clang-format on
   6313     RunParserSyncTest(context_data, data, kError);
   6314   }
   6315 }
   6316 
   6317 
   6318 TEST(DestructuringAssignmentPositiveTests) {
   6319   const char* context_data[][2] = {
   6320       {"'use strict'; let x, y, z; (", " = {});"},
   6321       {"var x, y, z; (", " = {});"},
   6322       {"'use strict'; let x, y, z; for (x in ", " = {});"},
   6323       {"'use strict'; let x, y, z; for (x of ", " = {});"},
   6324       {"var x, y, z; for (x in ", " = {});"},
   6325       {"var x, y, z; for (x of ", " = {});"},
   6326       {"var x, y, z; for (", " in {});"},
   6327       {"var x, y, z; for (", " of {});"},
   6328       {"'use strict'; var x, y, z; for (", " in {});"},
   6329       {"'use strict'; var x, y, z; for (", " of {});"},
   6330       {NULL, NULL}};
   6331 
   6332   const char* mixed_assignments_context_data[][2] = {
   6333       {"'use strict'; let x, y, z; (", " = z = {});"},
   6334       {"var x, y, z; (", " = z = {});"},
   6335       {"'use strict'; let x, y, z; (x = ", " = z = {});"},
   6336       {"var x, y, z; (x = ", " = z = {});"},
   6337       {"'use strict'; let x, y, z; for (x in ", " = z = {});"},
   6338       {"'use strict'; let x, y, z; for (x in x = ", " = z = {});"},
   6339       {"'use strict'; let x, y, z; for (x of ", " = z = {});"},
   6340       {"'use strict'; let x, y, z; for (x of x = ", " = z = {});"},
   6341       {"var x, y, z; for (x in ", " = z = {});"},
   6342       {"var x, y, z; for (x in x = ", " = z = {});"},
   6343       {"var x, y, z; for (x of ", " = z = {});"},
   6344       {"var x, y, z; for (x of x = ", " = z = {});"},
   6345       {NULL, NULL}};
   6346 
   6347   // clang-format off
   6348   const char* data[] = {
   6349     "x",
   6350 
   6351     "{ x : y }",
   6352     "{ x : foo().y }",
   6353     "{ x : foo()[y] }",
   6354     "{ x : y.z }",
   6355     "{ x : y[z] }",
   6356     "{ x : { y } }",
   6357     "{ x : { foo: y } }",
   6358     "{ x : { foo: foo().y } }",
   6359     "{ x : { foo: foo()[y] } }",
   6360     "{ x : { foo: y.z } }",
   6361     "{ x : { foo: y[z] } }",
   6362     "{ x : [ y ] }",
   6363     "{ x : [ foo().y ] }",
   6364     "{ x : [ foo()[y] ] }",
   6365     "{ x : [ y.z ] }",
   6366     "{ x : [ y[z] ] }",
   6367 
   6368     "{ x : y = 10 }",
   6369     "{ x : foo().y = 10 }",
   6370     "{ x : foo()[y] = 10 }",
   6371     "{ x : y.z = 10 }",
   6372     "{ x : y[z] = 10 }",
   6373     "{ x : { y = 10 } = {} }",
   6374     "{ x : { foo: y = 10 } = {} }",
   6375     "{ x : { foo: foo().y = 10 } = {} }",
   6376     "{ x : { foo: foo()[y] = 10 } = {} }",
   6377     "{ x : { foo: y.z = 10 } = {} }",
   6378     "{ x : { foo: y[z] = 10 } = {} }",
   6379     "{ x : [ y = 10 ] = {} }",
   6380     "{ x : [ foo().y = 10 ] = {} }",
   6381     "{ x : [ foo()[y] = 10 ] = {} }",
   6382     "{ x : [ y.z = 10 ] = {} }",
   6383     "{ x : [ y[z] = 10 ] = {} }",
   6384 
   6385     "[ x ]",
   6386     "[ foo().x ]",
   6387     "[ foo()[x] ]",
   6388     "[ x.y ]",
   6389     "[ x[y] ]",
   6390     "[ { x } ]",
   6391     "[ { x : y } ]",
   6392     "[ { x : foo().y } ]",
   6393     "[ { x : foo()[y] } ]",
   6394     "[ { x : x.y } ]",
   6395     "[ { x : x[y] } ]",
   6396     "[ [ x ] ]",
   6397     "[ [ foo().x ] ]",
   6398     "[ [ foo()[x] ] ]",
   6399     "[ [ x.y ] ]",
   6400     "[ [ x[y] ] ]",
   6401 
   6402     "[ x = 10 ]",
   6403     "[ foo().x = 10 ]",
   6404     "[ foo()[x] = 10 ]",
   6405     "[ x.y = 10 ]",
   6406     "[ x[y] = 10 ]",
   6407     "[ { x = 10 } = {} ]",
   6408     "[ { x : y = 10 } = {} ]",
   6409     "[ { x : foo().y = 10 } = {} ]",
   6410     "[ { x : foo()[y] = 10 } = {} ]",
   6411     "[ { x : x.y = 10 } = {} ]",
   6412     "[ { x : x[y] = 10 } = {} ]",
   6413     "[ [ x = 10 ] = {} ]",
   6414     "[ [ foo().x = 10 ] = {} ]",
   6415     "[ [ foo()[x] = 10 ] = {} ]",
   6416     "[ [ x.y = 10 ] = {} ]",
   6417     "[ [ x[y] = 10 ] = {} ]",
   6418     "{ x : y = 1 }",
   6419     "{ x }",
   6420     "{ x, y, z }",
   6421     "{ x = 1, y: z, z: y }",
   6422     "{x = 42, y = 15}",
   6423     "[x]",
   6424     "[x = 1]",
   6425     "[x,y,z]",
   6426     "[x, y = 42, z]",
   6427     "{ x : x, y : y }",
   6428     "{ x : x = 1, y : y }",
   6429     "{ x : x, y : y = 42 }",
   6430     "[]",
   6431     "{}",
   6432     "[{x:x, y:y}, [,x,z,]]",
   6433     "[{x:x = 1, y:y = 2}, [z = 3, z = 4, z = 5]]",
   6434     "[x,,y]",
   6435     "[(x),,(y)]",
   6436     "[(x)]",
   6437     "{42 : x}",
   6438     "{42 : x = 42}",
   6439     "{42e-2 : x}",
   6440     "{42e-2 : x = 42}",
   6441     "{'hi' : x}",
   6442     "{'hi' : x = 42}",
   6443     "{var: x}",
   6444     "{var: x = 42}",
   6445     "{var: (x) = 42}",
   6446     "{[x] : z}",
   6447     "{[1+1] : z}",
   6448     "{[1+1] : (z)}",
   6449     "{[foo()] : z}",
   6450     "{[foo()] : (z)}",
   6451     "{[foo()] : foo().bar}",
   6452     "{[foo()] : foo()['bar']}",
   6453     "{[foo()] : this.bar}",
   6454     "{[foo()] : this['bar']}",
   6455     "{[foo()] : 'foo'.bar}",
   6456     "{[foo()] : 'foo'['bar']}",
   6457     "[...x]",
   6458     "[x,y,...z]",
   6459     "[x,,...z]",
   6460     "{ x: y }",
   6461     "[x, y]",
   6462     "[((x, y) => z).x]",
   6463     "{x: ((y, z) => z).x}",
   6464     "[((x, y) => z)['x']]",
   6465     "{x: ((y, z) => z)['x']}",
   6466 
   6467     "{x: { y = 10 } }",
   6468     "[(({ x } = { x: 1 }) => x).a]",
   6469 
   6470     // v8:4662
   6471     "{ x: (y) }",
   6472     "{ x: (y) = [] }",
   6473     "{ x: (foo.bar) }",
   6474     "{ x: (foo['bar']) }",
   6475     "[ ...(a) ]",
   6476     "[ ...(foo['bar']) ]",
   6477     "[ ...(foo.bar) ]",
   6478     "[ (y) ]",
   6479     "[ (foo.bar) ]",
   6480     "[ (foo['bar']) ]",
   6481 
   6482     NULL};
   6483   // clang-format on
   6484   RunParserSyncTest(context_data, data, kSuccess);
   6485 
   6486   RunParserSyncTest(mixed_assignments_context_data, data, kSuccess);
   6487 
   6488   const char* empty_context_data[][2] = {
   6489       {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
   6490 
   6491   // CoverInitializedName ambiguity handling in various contexts
   6492   const char* ambiguity_data[] = {
   6493       "var foo = { x = 10 } = {};",
   6494       "var foo = { q } = { x = 10 } = {};",
   6495       "var foo; foo = { x = 10 } = {};",
   6496       "var foo; foo = { q } = { x = 10 } = {};",
   6497       "var x; ({ x = 10 } = {});",
   6498       "var q, x; ({ q } = { x = 10 } = {});",
   6499       "var x; [{ x = 10 } = {}]",
   6500       "var x; (true ? { x = true } = {} : { x = false } = {})",
   6501       "var q, x; (q, { x = 10 } = {});",
   6502       "var { x = 10 } = { x = 20 } = {};",
   6503       "var { x = 10 } = (o = { x = 20 } = {});",
   6504       "var x; (({ x = 10 } = { x = 20 } = {}) => x)({})",
   6505       NULL,
   6506   };
   6507   RunParserSyncTest(empty_context_data, ambiguity_data, kSuccess);
   6508 }
   6509 
   6510 
   6511 TEST(DestructuringAssignmentNegativeTests) {
   6512   const char* context_data[][2] = {
   6513       {"'use strict'; let x, y, z; (", " = {});"},
   6514       {"var x, y, z; (", " = {});"},
   6515       {"'use strict'; let x, y, z; for (x in ", " = {});"},
   6516       {"'use strict'; let x, y, z; for (x of ", " = {});"},
   6517       {"var x, y, z; for (x in ", " = {});"},
   6518       {"var x, y, z; for (x of ", " = {});"},
   6519       {NULL, NULL}};
   6520 
   6521   // clang-format off
   6522   const char* data[] = {
   6523     "{ x : ++y }",
   6524     "{ x : y * 2 }",
   6525     "{ ...x }",
   6526     "{ get x() {} }",
   6527     "{ set x() {} }",
   6528     "{ x: y() }",
   6529     "{ this }",
   6530     "{ x: this }",
   6531     "{ x: this = 1 }",
   6532     "{ super }",
   6533     "{ x: super }",
   6534     "{ x: super = 1 }",
   6535     "{ new.target }",
   6536     "{ x: new.target }",
   6537     "{ x: new.target = 1 }",
   6538     "[x--]",
   6539     "[--x = 1]",
   6540     "[x()]",
   6541     "[this]",
   6542     "[this = 1]",
   6543     "[new.target]",
   6544     "[new.target = 1]",
   6545     "[super]",
   6546     "[super = 1]",
   6547     "[function f() {}]",
   6548     "[50]",
   6549     "[(50)]",
   6550     "[(function() {})]",
   6551     "[(foo())]",
   6552     "{ x: 50 }",
   6553     "{ x: (50) }",
   6554     "['str']",
   6555     "{ x: 'str' }",
   6556     "{ x: ('str') }",
   6557     "{ x: (foo()) }",
   6558     "{ x: (function() {}) }",
   6559     "{ x: y } = 'str'",
   6560     "[x, y] = 'str'",
   6561     "[(x,y) => z]",
   6562     "{x: (y) => z}",
   6563     "[x, ...y, z]",
   6564     "[...x,]",
   6565     "[x, y, ...z = 1]",
   6566     "[...z = 1]",
   6567     "[x, y, ...[z] = [1]]",
   6568     "[...[z] = [1]]",
   6569 
   6570     // v8:4657
   6571     "({ x: x4, x: (x+=1e4) })",
   6572     "(({ x: x4, x: (x+=1e4) }))",
   6573     "({ x: x4, x: (x+=1e4) } = {})",
   6574     "(({ x: x4, x: (x+=1e4) } = {}))",
   6575     "(({ x: x4, x: (x+=1e4) }) = {})",
   6576     "({ x: y } = {})",
   6577     "(({ x: y } = {}))",
   6578     "(({ x: y }) = {})",
   6579     "([a])",
   6580     "(([a]))",
   6581     "([a] = [])",
   6582     "(([a] = []))",
   6583     "(([a]) = [])",
   6584 
   6585     // v8:4662
   6586     "{ x: ([y]) }",
   6587     "{ x: ([y] = []) }",
   6588     "{ x: ({y}) }",
   6589     "{ x: ({y} = {}) }",
   6590     "{ x: (++y) }",
   6591     "[ (...[a]) ]",
   6592     "[ ...([a]) ]",
   6593     "[ ...([a] = [])",
   6594     "[ ...[ ( [ a ] ) ] ]",
   6595     "[ ([a]) ]",
   6596     "[ (...[a]) ]",
   6597     "[ ([a] = []) ]",
   6598     "[ (++y) ]",
   6599     "[ ...(++y) ]",
   6600 
   6601     "[ x += x ]",
   6602     "{ foo: x += x }",
   6603 
   6604     NULL};
   6605   // clang-format on
   6606   RunParserSyncTest(context_data, data, kError);
   6607 
   6608   const char* empty_context_data[][2] = {
   6609       {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
   6610 
   6611   // CoverInitializedName ambiguity handling in various contexts
   6612   const char* ambiguity_data[] = {
   6613       "var foo = { x = 10 };",
   6614       "var foo = { q } = { x = 10 };",
   6615       "var foo; foo = { x = 10 };",
   6616       "var foo; foo = { q } = { x = 10 };",
   6617       "var x; ({ x = 10 });",
   6618       "var q, x; ({ q } = { x = 10 });",
   6619       "var x; [{ x = 10 }]",
   6620       "var x; (true ? { x = true } : { x = false })",
   6621       "var q, x; (q, { x = 10 });",
   6622       "var { x = 10 } = { x = 20 };",
   6623       "var { x = 10 } = (o = { x = 20 });",
   6624       "var x; (({ x = 10 } = { x = 20 }) => x)({})",
   6625 
   6626       // Not ambiguous, but uses same context data
   6627       "switch([window %= []] = []) { default: }",
   6628 
   6629       NULL,
   6630   };
   6631   RunParserSyncTest(empty_context_data, ambiguity_data, kError);
   6632 
   6633   // Strict mode errors
   6634   const char* strict_context_data[][2] = {{"'use strict'; (", " = {})"},
   6635                                           {"'use strict'; for (", " of {}) {}"},
   6636                                           {"'use strict'; for (", " in {}) {}"},
   6637                                           {NULL, NULL}};
   6638   const char* strict_data[] = {"{ eval }",
   6639                                "{ arguments }",
   6640                                "{ foo: eval }",
   6641                                "{ foo: arguments }",
   6642                                "{ eval = 0 }",
   6643                                "{ arguments = 0 }",
   6644                                "{ foo: eval = 0 }",
   6645                                "{ foo: arguments = 0 }",
   6646                                "[ eval ]",
   6647                                "[ arguments ]",
   6648                                "[ eval = 0 ]",
   6649                                "[ arguments = 0 ]",
   6650 
   6651                                // v8:4662
   6652                                "{ x: (eval) }",
   6653                                "{ x: (arguments) }",
   6654                                "{ x: (eval = 0) }",
   6655                                "{ x: (arguments = 0) }",
   6656                                "{ x: (eval) = 0 }",
   6657                                "{ x: (arguments) = 0 }",
   6658                                "[ (eval) ]",
   6659                                "[ (arguments) ]",
   6660                                "[ (eval = 0) ]",
   6661                                "[ (arguments = 0) ]",
   6662                                "[ (eval) = 0 ]",
   6663                                "[ (arguments) = 0 ]",
   6664                                "[ ...(eval) ]",
   6665                                "[ ...(arguments) ]",
   6666                                "[ ...(eval = 0) ]",
   6667                                "[ ...(arguments = 0) ]",
   6668                                "[ ...(eval) = 0 ]",
   6669                                "[ ...(arguments) = 0 ]",
   6670 
   6671                                NULL};
   6672   RunParserSyncTest(strict_context_data, strict_data, kError);
   6673 }
   6674 
   6675 
   6676 TEST(DestructuringDisallowPatternsInForVarIn) {
   6677   const char* context_data[][2] = {
   6678       {"", ""}, {"function f() {", "}"}, {NULL, NULL}};
   6679   // clang-format off
   6680   const char* error_data[] = {
   6681     "for (let x = {} in null);",
   6682     "for (let x = {} of null);",
   6683     NULL};
   6684   // clang-format on
   6685   RunParserSyncTest(context_data, error_data, kError);
   6686 
   6687   // clang-format off
   6688   const char* success_data[] = {
   6689     "for (var x = {} in null);",
   6690     NULL};
   6691   // clang-format on
   6692   RunParserSyncTest(context_data, success_data, kSuccess);
   6693 }
   6694 
   6695 
   6696 TEST(DestructuringDuplicateParams) {
   6697   const char* context_data[][2] = {{"'use strict';", ""},
   6698                                    {"function outer() { 'use strict';", "}"},
   6699                                    {nullptr, nullptr}};
   6700 
   6701 
   6702   // clang-format off
   6703   const char* error_data[] = {
   6704     "function f(x,x){}",
   6705     "function f(x, {x : x}){}",
   6706     "function f(x, {x}){}",
   6707     "function f({x,x}) {}",
   6708     "function f([x,x]) {}",
   6709     "function f(x, [y,{z:x}]) {}",
   6710     "function f([x,{y:x}]) {}",
   6711     // non-simple parameter list causes duplicates to be errors in sloppy mode.
   6712     "function f(x, x, {a}) {}",
   6713     nullptr};
   6714   // clang-format on
   6715   RunParserSyncTest(context_data, error_data, kError);
   6716 }
   6717 
   6718 
   6719 TEST(DestructuringDuplicateParamsSloppy) {
   6720   const char* context_data[][2] = {
   6721       {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
   6722 
   6723 
   6724   // clang-format off
   6725   const char* error_data[] = {
   6726     // non-simple parameter list causes duplicates to be errors in sloppy mode.
   6727     "function f(x, {x : x}){}",
   6728     "function f(x, {x}){}",
   6729     "function f({x,x}) {}",
   6730     "function f(x, x, {a}) {}",
   6731     nullptr};
   6732   // clang-format on
   6733   RunParserSyncTest(context_data, error_data, kError);
   6734 }
   6735 
   6736 
   6737 TEST(DestructuringDisallowPatternsInSingleParamArrows) {
   6738   const char* context_data[][2] = {{"'use strict';", ""},
   6739                                    {"function outer() { 'use strict';", "}"},
   6740                                    {"", ""},
   6741                                    {"function outer() { ", "}"},
   6742                                    {nullptr, nullptr}};
   6743 
   6744   // clang-format off
   6745   const char* error_data[] = {
   6746     "var f = {x} => {};",
   6747     "var f = {x,y} => {};",
   6748     nullptr};
   6749   // clang-format on
   6750   RunParserSyncTest(context_data, error_data, kError);
   6751 }
   6752 
   6753 
   6754 TEST(DefaultParametersYieldInInitializers) {
   6755   // clang-format off
   6756   const char* sloppy_function_context_data[][2] = {
   6757     {"(function f(", ") { });"},
   6758     {NULL, NULL}
   6759   };
   6760 
   6761   const char* strict_function_context_data[][2] = {
   6762     {"'use strict'; (function f(", ") { });"},
   6763     {NULL, NULL}
   6764   };
   6765 
   6766   const char* sloppy_arrow_context_data[][2] = {
   6767     {"((", ")=>{});"},
   6768     {NULL, NULL}
   6769   };
   6770 
   6771   const char* strict_arrow_context_data[][2] = {
   6772     {"'use strict'; ((", ")=>{});"},
   6773     {NULL, NULL}
   6774   };
   6775 
   6776   const char* generator_context_data[][2] = {
   6777     {"'use strict'; (function *g(", ") { });"},
   6778     {"(function *g(", ") { });"},
   6779     // Arrow function within generator has the same rules.
   6780     {"'use strict'; (function *g() { (", ") => {} });"},
   6781     {"(function *g() { (", ") => {} });"},
   6782     // And similarly for arrow functions in the parameter list.
   6783     {"'use strict'; (function *g(z = (", ") => {}) { });"},
   6784     {"(function *g(z = (", ") => {}) { });"},
   6785     {NULL, NULL}
   6786   };
   6787 
   6788   const char* parameter_data[] = {
   6789     "x=yield",
   6790     "x, y=yield",
   6791     "{x=yield}",
   6792     "[x=yield]",
   6793 
   6794     "x=(yield)",
   6795     "x, y=(yield)",
   6796     "{x=(yield)}",
   6797     "[x=(yield)]",
   6798 
   6799     "x=f(yield)",
   6800     "x, y=f(yield)",
   6801     "{x=f(yield)}",
   6802     "[x=f(yield)]",
   6803 
   6804     "{x}=yield",
   6805     "[x]=yield",
   6806 
   6807     "{x}=(yield)",
   6808     "[x]=(yield)",
   6809 
   6810     "{x}=f(yield)",
   6811     "[x]=f(yield)",
   6812     NULL
   6813   };
   6814 
   6815   // Because classes are always in strict mode, these are always errors.
   6816   const char* always_error_param_data[] = {
   6817     "x = class extends (yield) { }",
   6818     "x = class extends f(yield) { }",
   6819     "x = class extends (null, yield) { }",
   6820     "x = class extends (a ? null : yield) { }",
   6821     "[x] = [class extends (a ? null : yield) { }]",
   6822     "[x = class extends (a ? null : yield) { }]",
   6823     "[x = class extends (a ? null : yield) { }] = [null]",
   6824     "x = class { [yield]() { } }",
   6825     "x = class { static [yield]() { } }",
   6826     "x = class { [(yield, 1)]() { } }",
   6827     "x = class { [y = (yield, 1)]() { } }",
   6828     NULL
   6829   };
   6830   // clang-format on
   6831 
   6832   RunParserSyncTest(sloppy_function_context_data, parameter_data, kSuccess);
   6833   RunParserSyncTest(sloppy_arrow_context_data, parameter_data, kSuccess);
   6834 
   6835   RunParserSyncTest(strict_function_context_data, parameter_data, kError);
   6836   RunParserSyncTest(strict_arrow_context_data, parameter_data, kError);
   6837 
   6838   RunParserSyncTest(generator_context_data, parameter_data, kError);
   6839   RunParserSyncTest(generator_context_data, always_error_param_data, kError);
   6840 }
   6841 
   6842 TEST(SpreadArray) {
   6843   const char* context_data[][2] = {
   6844       {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
   6845 
   6846   // clang-format off
   6847   const char* data[] = {
   6848     "[...a]",
   6849     "[a, ...b]",
   6850     "[...a,]",
   6851     "[...a, ,]",
   6852     "[, ...a]",
   6853     "[...a, ...b]",
   6854     "[...a, , ...b]",
   6855     "[...[...a]]",
   6856     "[, ...a]",
   6857     "[, , ...a]",
   6858     NULL};
   6859   // clang-format on
   6860   RunParserSyncTest(context_data, data, kSuccess);
   6861 }
   6862 
   6863 
   6864 TEST(SpreadArrayError) {
   6865   const char* context_data[][2] = {
   6866       {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
   6867 
   6868   // clang-format off
   6869   const char* data[] = {
   6870     "[...]",
   6871     "[a, ...]",
   6872     "[..., ]",
   6873     "[..., ...]",
   6874     "[ (...a)]",
   6875     NULL};
   6876   // clang-format on
   6877   RunParserSyncTest(context_data, data, kError);
   6878 }
   6879 
   6880 
   6881 TEST(NewTarget) {
   6882   // clang-format off
   6883   const char* good_context_data[][2] = {
   6884     {"function f() {", "}"},
   6885     {"'use strict'; function f() {", "}"},
   6886     {"var f = function() {", "}"},
   6887     {"'use strict'; var f = function() {", "}"},
   6888     {"({m: function() {", "}})"},
   6889     {"'use strict'; ({m: function() {", "}})"},
   6890     {"({m() {", "}})"},
   6891     {"'use strict'; ({m() {", "}})"},
   6892     {"({get x() {", "}})"},
   6893     {"'use strict'; ({get x() {", "}})"},
   6894     {"({set x(_) {", "}})"},
   6895     {"'use strict'; ({set x(_) {", "}})"},
   6896     {"class C {m() {", "}}"},
   6897     {"class C {get x() {", "}}"},
   6898     {"class C {set x(_) {", "}}"},
   6899     {NULL}
   6900   };
   6901 
   6902   const char* bad_context_data[][2] = {
   6903     {"", ""},
   6904     {"'use strict';", ""},
   6905     {NULL}
   6906   };
   6907 
   6908   const char* data[] = {
   6909     "new.target",
   6910     "{ new.target }",
   6911     "() => { new.target }",
   6912     "() => new.target",
   6913     "if (1) { new.target }",
   6914     "if (1) {} else { new.target }",
   6915     "while (0) { new.target }",
   6916     "do { new.target } while (0)",
   6917     NULL
   6918   };
   6919 
   6920   // clang-format on
   6921 
   6922   RunParserSyncTest(good_context_data, data, kSuccess);
   6923   RunParserSyncTest(bad_context_data, data, kError);
   6924 }
   6925 
   6926 
   6927 TEST(ConstSloppy) {
   6928   // clang-format off
   6929   const char* context_data[][2] = {
   6930     {"", ""},
   6931     {"{", "}"},
   6932     {NULL, NULL}
   6933   };
   6934 
   6935   const char* data[] = {
   6936     "const x = 1",
   6937     "for (const x = 1; x < 1; x++) {}",
   6938     "for (const x in {}) {}",
   6939     "for (const x of []) {}",
   6940     NULL
   6941   };
   6942   // clang-format on
   6943   RunParserSyncTest(context_data, data, kSuccess);
   6944 }
   6945 
   6946 
   6947 TEST(LetSloppy) {
   6948   // clang-format off
   6949   const char* context_data[][2] = {
   6950     {"", ""},
   6951     {"'use strict';", ""},
   6952     {"{", "}"},
   6953     {NULL, NULL}
   6954   };
   6955 
   6956   const char* data[] = {
   6957     "let x",
   6958     "let x = 1",
   6959     "for (let x = 1; x < 1; x++) {}",
   6960     "for (let x in {}) {}",
   6961     "for (let x of []) {}",
   6962     NULL
   6963   };
   6964   // clang-format on
   6965 
   6966   RunParserSyncTest(context_data, data, kSuccess);
   6967 }
   6968 
   6969 
   6970 TEST(LanguageModeDirectivesNonSimpleParameterListErrors) {
   6971   // TC39 deemed "use strict" directives to be an error when occurring in the
   6972   // body of a function with non-simple parameter list, on 29/7/2015.
   6973   // https://goo.gl/ueA7Ln
   6974   const char* context_data[][2] = {
   6975       {"function f(", ") { 'use strict'; }"},
   6976       {"function* g(", ") { 'use strict'; }"},
   6977       {"class c { foo(", ") { 'use strict' }"},
   6978       {"var a = (", ") => { 'use strict'; }"},
   6979       {"var o = { m(", ") { 'use strict'; }"},
   6980       {"var o = { *gm(", ") { 'use strict'; }"},
   6981       {"var c = { m(", ") { 'use strict'; }"},
   6982       {"var c = { *gm(", ") { 'use strict'; }"},
   6983 
   6984       {"'use strict'; function f(", ") { 'use strict'; }"},
   6985       {"'use strict'; function* g(", ") { 'use strict'; }"},
   6986       {"'use strict'; class c { foo(", ") { 'use strict' }"},
   6987       {"'use strict'; var a = (", ") => { 'use strict'; }"},
   6988       {"'use strict'; var o = { m(", ") { 'use strict'; }"},
   6989       {"'use strict'; var o = { *gm(", ") { 'use strict'; }"},
   6990       {"'use strict'; var c = { m(", ") { 'use strict'; }"},
   6991       {"'use strict'; var c = { *gm(", ") { 'use strict'; }"},
   6992 
   6993       {NULL, NULL}};
   6994 
   6995   const char* data[] = {
   6996       // TODO(@caitp): support formal parameter initializers
   6997       "{}",
   6998       "[]",
   6999       "[{}]",
   7000       "{a}",
   7001       "a, {b}",
   7002       "a, b, {c, d, e}",
   7003       "initializer = true",
   7004       "a, b, c = 1",
   7005       "...args",
   7006       "a, b, ...rest",
   7007       "[a, b, ...rest]",
   7008       "{ bindingPattern = {} }",
   7009       "{ initializedBindingPattern } = { initializedBindingPattern: true }",
   7010       NULL};
   7011 
   7012   RunParserSyncTest(context_data, data, kError);
   7013 }
   7014 
   7015 
   7016 TEST(LetSloppyOnly) {
   7017   // clang-format off
   7018   const char* context_data[][2] = {
   7019     {"", ""},
   7020     {"{", "}"},
   7021     {"(function() {", "})()"},
   7022     {NULL, NULL}
   7023   };
   7024 
   7025   const char* data[] = {
   7026     "let",
   7027     "let = 1",
   7028     "for (let = 1; let < 1; let++) {}",
   7029     "for (let in {}) {}",
   7030     "for (var let = 1; let < 1; let++) {}",
   7031     "for (var let in {}) {}",
   7032     "for (var [let] = 1; let < 1; let++) {}",
   7033     "for (var [let] in {}) {}",
   7034     "var let",
   7035     "var [let] = []",
   7036     NULL
   7037   };
   7038   // clang-format on
   7039 
   7040   RunParserSyncTest(context_data, data, kSuccess);
   7041 
   7042   // Some things should be rejected even in sloppy mode
   7043   // This addresses BUG(v8:4403).
   7044 
   7045   // clang-format off
   7046   const char* fail_data[] = {
   7047     "let let = 1",
   7048     "for (let let = 1; let < 1; let++) {}",
   7049     "for (let let in {}) {}",
   7050     "for (let let of []) {}",
   7051     "const let = 1",
   7052     "for (const let = 1; let < 1; let++) {}",
   7053     "for (const let in {}) {}",
   7054     "for (const let of []) {}",
   7055     "let [let] = 1",
   7056     "for (let [let] = 1; let < 1; let++) {}",
   7057     "for (let [let] in {}) {}",
   7058     "for (let [let] of []) {}",
   7059     "const [let] = 1",
   7060     "for (const [let] = 1; let < 1; let++) {}",
   7061     "for (const [let] in {}) {}",
   7062     "for (const [let] of []) {}",
   7063 
   7064     // Sprinkle in the escaped version too.
   7065     "let l\\u0065t = 1",
   7066     "const l\\u0065t = 1",
   7067     "let [l\\u0065t] = 1",
   7068     "const [l\\u0065t] = 1",
   7069     "for (let l\\u0065t in {}) {}",
   7070     NULL
   7071   };
   7072   // clang-format on
   7073 
   7074   RunParserSyncTest(context_data, fail_data, kError);
   7075 }
   7076 
   7077 
   7078 TEST(EscapedKeywords) {
   7079   // clang-format off
   7080   const char* sloppy_context_data[][2] = {
   7081     {"", ""},
   7082     {NULL, NULL}
   7083   };
   7084 
   7085   const char* strict_context_data[][2] = {
   7086     {"'use strict';", ""},
   7087     {NULL, NULL}
   7088   };
   7089 
   7090   const char* fail_data[] = {
   7091     "for (var i = 0; i < 100; ++i) { br\\u0065ak; }",
   7092     "cl\\u0061ss Foo {}",
   7093     "var x = cl\\u0061ss {}",
   7094     "\\u0063onst foo = 1;",
   7095     "while (i < 10) { if (i++ & 1) c\\u006fntinue; this.x++; }",
   7096     "d\\u0065bugger;",
   7097     "d\\u0065lete this.a;",
   7098     "\\u0063o { } while(0)",
   7099     "if (d\\u006f { true }) {}",
   7100     "if (false) { this.a = 1; } \\u0065lse { this.b = 1; }",
   7101     "e\\u0078port var foo;",
   7102     "try { } catch (e) {} f\\u0069nally { }",
   7103     "f\\u006fr (var i = 0; i < 10; ++i);",
   7104     "f\\u0075nction fn() {}",
   7105     "var f = f\\u0075nction() {}",
   7106     "\\u0069f (true) { }",
   7107     "\\u0069mport blah from './foo.js';",
   7108     "n\\u0065w function f() {}",
   7109     "(function() { r\\u0065turn; })()",
   7110     "class C extends function() {} { constructor() { sup\\u0065r() } }",
   7111     "class C extends function() {} { constructor() { sup\\u0065r.a = 1 } }",
   7112     "sw\\u0069tch (this.a) {}",
   7113     "var x = th\\u0069s;",
   7114     "th\\u0069s.a = 1;",
   7115     "thr\\u006fw 'boo';",
   7116     "t\\u0072y { true } catch (e) {}",
   7117     "var x = typ\\u0065of 'blah'",
   7118     "v\\u0061r a = true",
   7119     "var v\\u0061r = true",
   7120     "(function() { return v\\u006fid 0; })()",
   7121     "wh\\u0069le (true) { }",
   7122     "w\\u0069th (this.scope) { }",
   7123     "(function*() { y\\u0069eld 1; })()",
   7124     "(function*() { var y\\u0069eld = 1; })()",
   7125 
   7126     "var \\u0065num = 1;",
   7127     "var { \\u0065num } = {}",
   7128     "(\\u0065num = 1);",
   7129 
   7130     // Null / Boolean literals
   7131     "(x === n\\u0075ll);",
   7132     "var x = n\\u0075ll;",
   7133     "var n\\u0075ll = 1;",
   7134     "var { n\\u0075ll } = { 1 };",
   7135     "n\\u0075ll = 1;",
   7136     "(x === tr\\u0075e);",
   7137     "var x = tr\\u0075e;",
   7138     "var tr\\u0075e = 1;",
   7139     "var { tr\\u0075e } = {};",
   7140     "tr\\u0075e = 1;",
   7141     "(x === f\\u0061lse);",
   7142     "var x = f\\u0061lse;",
   7143     "var f\\u0061lse = 1;",
   7144     "var { f\\u0061lse } = {};",
   7145     "f\\u0061lse = 1;",
   7146 
   7147     // TODO(caitp): consistent error messages for labeled statements and
   7148     // expressions
   7149     "switch (this.a) { c\\u0061se 6: break; }",
   7150     "try { } c\\u0061tch (e) {}",
   7151     "switch (this.a) { d\\u0065fault: break; }",
   7152     "class C \\u0065xtends function B() {} {}",
   7153     "for (var a i\\u006e this) {}",
   7154     "if ('foo' \\u0069n this) {}",
   7155     "if (this \\u0069nstanceof Array) {}",
   7156     "(n\\u0065w function f() {})",
   7157     "(typ\\u0065of 123)",
   7158     "(v\\u006fid 0)",
   7159     "do { ; } wh\\u0069le (true) { }",
   7160     "(function*() { return (n++, y\\u0069eld 1); })()",
   7161     "class C { st\\u0061tic bar() {} }",
   7162     "class C { st\\u0061tic *bar() {} }",
   7163     "class C { st\\u0061tic get bar() {} }",
   7164     "class C { st\\u0061tic set bar() {} }",
   7165 
   7166     // TODO(adamk): These should not be errors in sloppy mode.
   7167     "(y\\u0069eld);",
   7168     "var y\\u0069eld = 1;",
   7169     "var { y\\u0069eld } = {};",
   7170     NULL
   7171   };
   7172   // clang-format on
   7173 
   7174   RunParserSyncTest(sloppy_context_data, fail_data, kError);
   7175   RunParserSyncTest(strict_context_data, fail_data, kError);
   7176   RunModuleParserSyncTest(sloppy_context_data, fail_data, kError);
   7177 
   7178   // clang-format off
   7179   const char* let_data[] = {
   7180     "var l\\u0065t = 1;",
   7181     "l\\u0065t = 1;",
   7182     "(l\\u0065t === 1);",
   7183     NULL
   7184   };
   7185   // clang-format on
   7186 
   7187   RunParserSyncTest(sloppy_context_data, let_data, kSuccess);
   7188   RunParserSyncTest(strict_context_data, let_data, kError);
   7189 
   7190   // Non-errors in sloppy mode
   7191   const char* valid_data[] = {"(\\u0069mplements = 1);",
   7192                               "var impl\\u0065ments = 1;",
   7193                               "var { impl\\u0065ments  } = {};",
   7194                               "(\\u0069nterface = 1);",
   7195                               "var int\\u0065rface = 1;",
   7196                               "var { int\\u0065rface  } = {};",
   7197                               "(p\\u0061ckage = 1);",
   7198                               "var packa\\u0067e = 1;",
   7199                               "var { packa\\u0067e  } = {};",
   7200                               "(p\\u0072ivate = 1);",
   7201                               "var p\\u0072ivate;",
   7202                               "var { p\\u0072ivate } = {};",
   7203                               "(prot\\u0065cted);",
   7204                               "var prot\\u0065cted = 1;",
   7205                               "var { prot\\u0065cted  } = {};",
   7206                               "(publ\\u0069c);",
   7207                               "var publ\\u0069c = 1;",
   7208                               "var { publ\\u0069c } = {};",
   7209                               "(st\\u0061tic);",
   7210                               "var st\\u0061tic = 1;",
   7211                               "var { st\\u0061tic } = {};",
   7212                               NULL};
   7213   RunParserSyncTest(sloppy_context_data, valid_data, kSuccess);
   7214   RunParserSyncTest(strict_context_data, valid_data, kError);
   7215   RunModuleParserSyncTest(strict_context_data, valid_data, kError);
   7216 }
   7217 
   7218 
   7219 TEST(MiscSyntaxErrors) {
   7220   // clang-format off
   7221   const char* context_data[][2] = {
   7222     { "'use strict'", "" },
   7223     { "", "" },
   7224     { NULL, NULL }
   7225   };
   7226   const char* error_data[] = {
   7227     "for (();;) {}",
   7228 
   7229     // crbug.com/582626
   7230     "{ NaN ,chA((evarA=new t ( l = !.0[((... co -a0([1]))=> greturnkf",
   7231     NULL
   7232   };
   7233   // clang-format on
   7234 
   7235   RunParserSyncTest(context_data, error_data, kError);
   7236 }
   7237 
   7238 
   7239 TEST(EscapeSequenceErrors) {
   7240   // clang-format off
   7241   const char* context_data[][2] = {
   7242     { "'", "'" },
   7243     { "\"", "\"" },
   7244     { "`", "`" },
   7245     { "`${'", "'}`" },
   7246     { "`${\"", "\"}`" },
   7247     { "`${`", "`}`" },
   7248     { "f(tag`", "`);" },
   7249     { NULL, NULL }
   7250   };
   7251   const char* error_data[] = {
   7252     "\\uABCG",
   7253     "\\u{ZZ}",
   7254     "\\u{FFZ}",
   7255     "\\u{FFFFFFFFFF }",
   7256     "\\u{110000}",
   7257     "\\u{110000",
   7258     "\\u{FFFD }",
   7259     "\\xZF",
   7260     NULL
   7261   };
   7262   // clang-format on
   7263 
   7264   RunParserSyncTest(context_data, error_data, kError);
   7265 }
   7266 
   7267 
   7268 TEST(FunctionSentErrors) {
   7269   // clang-format off
   7270   const char* context_data[][2] = {
   7271     { "'use strict'", "" },
   7272     { "", "" },
   7273     { NULL, NULL }
   7274   };
   7275   const char* error_data[] = {
   7276     "var x = function.sent",
   7277     "function* g() { yield function.s\\u0065nt; }",
   7278     NULL
   7279   };
   7280   // clang-format on
   7281 
   7282   static const ParserFlag always_flags[] = {kAllowHarmonyFunctionSent};
   7283   RunParserSyncTest(context_data, error_data, kError, always_flags,
   7284                     arraysize(always_flags));
   7285 }
   7286 
   7287 TEST(NewTargetErrors) {
   7288   // clang-format off
   7289   const char* context_data[][2] = {
   7290     { "'use strict'", "" },
   7291     { "", "" },
   7292     { NULL, NULL }
   7293   };
   7294   const char* error_data[] = {
   7295     "var x = new.target",
   7296     "function f() { return new.t\\u0061rget; }",
   7297     NULL
   7298   };
   7299   // clang-format on
   7300   RunParserSyncTest(context_data, error_data, kError);
   7301 }
   7302 
   7303 TEST(FunctionDeclarationError) {
   7304   // clang-format off
   7305   const char* strict_context[][2] = {
   7306     { "'use strict';", "" },
   7307     { "'use strict'; { ", "}" },
   7308     {"(function() { 'use strict';", "})()"},
   7309     {"(function() { 'use strict'; {", "} })()"},
   7310     { NULL, NULL }
   7311   };
   7312   const char* sloppy_context[][2] = {
   7313     { "", "" },
   7314     { "{", "}" },
   7315     {"(function() {", "})()"},
   7316     {"(function() { {", "} })()"},
   7317     { NULL, NULL }
   7318   };
   7319   // Invalid in all contexts
   7320   const char* error_data[] = {
   7321     "try function foo() {} catch (e) {}",
   7322     NULL
   7323   };
   7324   // Valid in sloppy mode only, and only when the
   7325   // --harmony-restrictive-declarations flag is off
   7326   const char* unrestricted_data[] = {
   7327     "do function foo() {} while (0);",
   7328     "for (;false;) function foo() {}",
   7329     "for (var i = 0; i < 1; i++) function f() { };",
   7330     "for (var x in {a: 1}) function f() { };",
   7331     "for (var x in {}) function f() { };",
   7332     "for (var x in {}) function foo() {}",
   7333     "for (x in {a: 1}) function f() { };",
   7334     "for (x in {}) function f() { };",
   7335     "var x; for (x in {}) function foo() {}",
   7336     "with ({}) function f() { };",
   7337     "do label: function foo() {} while (0);",
   7338     "for (;false;) label: function foo() {}",
   7339     "for (var i = 0; i < 1; i++) label: function f() { };",
   7340     "for (var x in {a: 1}) label: function f() { };",
   7341     "for (var x in {}) label: function f() { };",
   7342     "for (var x in {}) label: function foo() {}",
   7343     "for (x in {a: 1}) label: function f() { };",
   7344     "for (x in {}) label: function f() { };",
   7345     "var x; for (x in {}) label: function foo() {}",
   7346     "with ({}) label: function f() { };",
   7347     "if (true) label: function f() {}",
   7348     "if (true) {} else label: function f() {}",
   7349     "if (true) function* f() { }",
   7350     "label: function* f() { }",
   7351     // TODO(littledan, v8:4806): Ban duplicate generator declarations in
   7352     // a block, maybe by tracking whether a Variable is a generator declaration
   7353     // "{ function* f() {} function* f() {} }",
   7354     // "{ function f() {} function* f() {} }",
   7355     // "{ function* f() {} function f() {} }",
   7356     NULL
   7357   };
   7358   // Valid only in sloppy mode, with or without
   7359   // --harmony-restrictive-declarations
   7360   const char* sloppy_data[] = {
   7361     "if (true) function foo() {}",
   7362     "if (false) {} else function f() { };",
   7363     "label: function f() { }",
   7364     "label: if (true) function f() { }",
   7365     "label: if (true) {} else function f() { }",
   7366     NULL
   7367   };
   7368   // clang-format on
   7369 
   7370   static const ParserFlag restrictive_flags[] = {
   7371       kAllowHarmonyRestrictiveDeclarations};
   7372 
   7373   // Nothing parses in strict mode without a SyntaxError
   7374   RunParserSyncTest(strict_context, error_data, kError);
   7375   RunParserSyncTest(strict_context, error_data, kError, NULL, 0,
   7376                     restrictive_flags, arraysize(restrictive_flags));
   7377   RunParserSyncTest(strict_context, unrestricted_data, kError);
   7378   RunParserSyncTest(strict_context, unrestricted_data, kError, NULL, 0,
   7379                     restrictive_flags, arraysize(restrictive_flags));
   7380   RunParserSyncTest(strict_context, sloppy_data, kError);
   7381   RunParserSyncTest(strict_context, sloppy_data, kError, NULL, 0,
   7382                     restrictive_flags, arraysize(restrictive_flags));
   7383 
   7384   // In sloppy mode, some things are successful, depending on the flag
   7385   RunParserSyncTest(sloppy_context, error_data, kError);
   7386   RunParserSyncTest(sloppy_context, error_data, kError, NULL, 0,
   7387                     restrictive_flags, arraysize(restrictive_flags));
   7388   RunParserSyncTest(sloppy_context, unrestricted_data, kSuccess);
   7389   RunParserSyncTest(sloppy_context, unrestricted_data, kError, NULL, 0,
   7390                     restrictive_flags, arraysize(restrictive_flags));
   7391   RunParserSyncTest(sloppy_context, sloppy_data, kSuccess);
   7392   RunParserSyncTest(sloppy_context, sloppy_data, kSuccess, restrictive_flags,
   7393                     arraysize(restrictive_flags));
   7394 }
   7395 
   7396 TEST(ExponentiationOperator) {
   7397   // clang-format off
   7398   const char* context_data[][2] = {
   7399     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
   7400     { "var O = { p: 1 }, x = 10; ; (", ")" },
   7401     { "var O = { p: 1 }, x = 10; foo(", ")" },
   7402     { NULL, NULL }
   7403   };
   7404   const char* data[] = {
   7405     "(delete O.p) ** 10",
   7406     "(delete x) ** 10",
   7407     "(~O.p) ** 10",
   7408     "(~x) ** 10",
   7409     "(!O.p) ** 10",
   7410     "(!x) ** 10",
   7411     "(+O.p) ** 10",
   7412     "(+x) ** 10",
   7413     "(-O.p) ** 10",
   7414     "(-x) ** 10",
   7415     "(typeof O.p) ** 10",
   7416     "(typeof x) ** 10",
   7417     "(void 0) ** 10",
   7418     "(void O.p) ** 10",
   7419     "(void x) ** 10",
   7420     "++O.p ** 10",
   7421     "++x ** 10",
   7422     "--O.p ** 10",
   7423     "--x ** 10",
   7424     "O.p++ ** 10",
   7425     "x++ ** 10",
   7426     "O.p-- ** 10",
   7427     "x-- ** 10",
   7428     NULL
   7429   };
   7430   // clang-format on
   7431 
   7432   static const ParserFlag always_flags[] = {
   7433       kAllowHarmonyExponentiationOperator};
   7434   RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
   7435                     arraysize(always_flags));
   7436 }
   7437 
   7438 TEST(ExponentiationOperatorErrors) {
   7439   // clang-format off
   7440   const char* context_data[][2] = {
   7441     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
   7442     { "var O = { p: 1 }, x = 10; ; (", ")" },
   7443     { "var O = { p: 1 }, x = 10; foo(", ")" },
   7444     { NULL, NULL }
   7445   };
   7446   const char* error_data[] = {
   7447     "delete O.p ** 10",
   7448     "delete x ** 10",
   7449     "~O.p ** 10",
   7450     "~x ** 10",
   7451     "!O.p ** 10",
   7452     "!x ** 10",
   7453     "+O.p ** 10",
   7454     "+x ** 10",
   7455     "-O.p ** 10",
   7456     "-x ** 10",
   7457     "typeof O.p ** 10",
   7458     "typeof x ** 10",
   7459     "void ** 10",
   7460     "void O.p ** 10",
   7461     "void x ** 10",
   7462     "++delete O.p ** 10",
   7463     "--delete O.p ** 10",
   7464     "++~O.p ** 10",
   7465     "++~x ** 10",
   7466     "--!O.p ** 10",
   7467     "--!x ** 10",
   7468     "++-O.p ** 10",
   7469     "++-x ** 10",
   7470     "--+O.p ** 10",
   7471     "--+x ** 10",
   7472     "[ x ] **= [ 2 ]",
   7473     "[ x **= 2 ] = [ 2 ]",
   7474     "{ x } **= { x: 2 }",
   7475     "{ x: x **= 2 ] = { x: 2 }",
   7476     // TODO(caitp): a Call expression as LHS should be an early ReferenceError!
   7477     // "Array() **= 10",
   7478     NULL
   7479   };
   7480   // clang-format on
   7481 
   7482   static const ParserFlag always_flags[] = {
   7483       kAllowHarmonyExponentiationOperator};
   7484   RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
   7485                     arraysize(always_flags));
   7486 }
   7487 
   7488 TEST(AsyncAwait) {
   7489   // clang-format off
   7490   const char* context_data[][2] = {
   7491     { "'use strict';", "" },
   7492     { "", "" },
   7493     { NULL, NULL }
   7494   };
   7495 
   7496   const char* data[] = {
   7497     "var asyncFn = async function() { await 1; };",
   7498     "var asyncFn = async function withName() { await 1; };",
   7499     "var asyncFn = async () => await 'test';",
   7500     "var asyncFn = async x => await x + 'test';",
   7501     "async function asyncFn() { await 1; }",
   7502     "var O = { async method() { await 1; } }",
   7503     "var O = { async ['meth' + 'od']() { await 1; } }",
   7504     "var O = { async 'method'() { await 1; } }",
   7505     "var O = { async 0() { await 1; } }",
   7506     "async function await() {}",
   7507 
   7508     "var asyncFn = async({ foo = 1 }) => foo;",
   7509     "var asyncFn = async({ foo = 1 } = {}) => foo;",
   7510     NULL
   7511   };
   7512   // clang-format on
   7513 
   7514   static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
   7515   RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
   7516                     arraysize(always_flags));
   7517 
   7518   // clang-format off
   7519   const char* async_body_context_data[][2] = {
   7520     { "async function f() {", "}" },
   7521     { "var f = async function() {", "}" },
   7522     { "var f = async() => {", "}" },
   7523     { "var O = { async method() {", "} }" },
   7524     { "'use strict'; async function f() {", "}" },
   7525     { "'use strict'; var f = async function() {", "}" },
   7526     { "'use strict'; var f = async() => {", "}" },
   7527     { "'use strict'; var O = { async method() {", "} }" },
   7528     { NULL, NULL }
   7529   };
   7530 
   7531   const char* body_context_data[][2] = {
   7532     { "function f() {", "}" },
   7533     { "function* g() {", "}" },
   7534     { "var f = function() {", "}" },
   7535     { "var g = function*() {", "}" },
   7536     { "var O = { method() {", "} }" },
   7537     { "var O = { *method() {", "} }" },
   7538     { "var f = () => {", "}" },
   7539     { "'use strict'; function f() {", "}" },
   7540     { "'use strict'; function* g() {", "}" },
   7541     { "'use strict'; var f = function() {", "}" },
   7542     { "'use strict'; var g = function*() {", "}" },
   7543     { "'use strict'; var O = { method() {", "} }" },
   7544     { "'use strict'; var O = { *method() {", "} }" },
   7545     { "'use strict'; var f = () => {", "}" },
   7546     { NULL, NULL }
   7547   };
   7548 
   7549   const char* body_data[] = {
   7550     "var async = 1; return async;",
   7551     "let async = 1; return async;",
   7552     "const async = 1; return async;",
   7553     "function async() {} return async();",
   7554     "var async = async => async; return async();",
   7555     "function foo() { var await = 1; return await; }",
   7556     "function foo(await) { return await; }",
   7557     "function* foo() { var await = 1; return await; }",
   7558     "function* foo(await) { return await; }",
   7559     "var f = (await) => await;",
   7560     "var f = () => { var await = 1; return await; }",
   7561     "var O = { method() { var await = 1; return await; } };",
   7562     "var O = { method(await) { return await; } };",
   7563     "var O = { *method() { var await = 1; return await; } };",
   7564     "var O = { *method(await) { return await; } };",
   7565 
   7566     "(function await() {})",
   7567     NULL
   7568   };
   7569   // clang-format on
   7570 
   7571   RunParserSyncTest(async_body_context_data, body_data, kSuccess, NULL, 0,
   7572                     always_flags, arraysize(always_flags));
   7573   RunParserSyncTest(body_context_data, body_data, kSuccess, NULL, 0,
   7574                     always_flags, arraysize(always_flags));
   7575 }
   7576 
   7577 TEST(AsyncAwaitErrors) {
   7578   // clang-format off
   7579   const char* context_data[][2] = {
   7580     { "'use strict';", "" },
   7581     { "", "" },
   7582     { NULL, NULL }
   7583   };
   7584 
   7585   const char* strict_context_data[][2] = {
   7586     { "'use strict';", "" },
   7587     { NULL, NULL }
   7588   };
   7589 
   7590   const char* error_data[] = {
   7591     "var asyncFn = async function() { var await = 1; };",
   7592     "var asyncFn = async function() { var { await } = 1; };",
   7593     "var asyncFn = async function() { var [ await ] = 1; };",
   7594     "var asyncFn = async function await() {};",
   7595     "var asyncFn = async () => var await = 'test';",
   7596     "var asyncFn = async await => await + 'test';",
   7597     "var asyncFn = async function(await) {};",
   7598     "var asyncFn = async function() { return async (await) => {}; }",
   7599     "var asyncFn = async (await) => 'test';",
   7600     "var asyncFn = async x => { var await = 1; }",
   7601     "var asyncFn = async x => { var { await } = 1; }",
   7602     "var asyncFn = async x => { var [ await ] = 1; }",
   7603     "async function f(await) {}",
   7604     "async function f() { var await = 1; }",
   7605     "async function f() { var { await } = 1; }",
   7606     "async function f() { var [ await ] = 1; }",
   7607 
   7608     "var O = { async method(a, a) {} }",
   7609     "var O = { async ['meth' + 'od'](a, a) {} }",
   7610     "var O = { async 'method'(a, a) {} }",
   7611     "var O = { async 0(a, a) {} }",
   7612 
   7613     "async function f() { var O = { async [await](a, a) {} } }",
   7614 
   7615     "var asyncFn = async function() { await; }",
   7616     "async function f() { await; }",
   7617     "var O = { async method() { await; } };",
   7618     "var f = async() => await;",
   7619     "var f = async() => { await; };",
   7620 
   7621     "var asyncFn = async function*() {}",
   7622     "async function* f() {}",
   7623     "var O = { *async method() {} };",
   7624     "var O = { async *method() {} };",
   7625     "var O = { async method*() {} };",
   7626 
   7627     "var asyncFn = async function(x = await 1) { return x; }",
   7628     "async function f(x = await 1) { return x; }",
   7629     "var f = async(x = await 1) => x;",
   7630     "var O = { async method(x = await 1) { return x; } };",
   7631 
   7632     "var f = async(x = await) => 1;",
   7633 
   7634     "class C { async constructor() {} }",
   7635     "class C {}; class C2 extends C { async constructor() {} }",
   7636     "class C { static async prototype() {} }",
   7637     "class C {}; class C2 extends C { static async prototype() {} }",
   7638 
   7639     "var f = async() => ((async(x = await 1) => x)();",
   7640 
   7641     "var asyncFn = async function() { function await() {} }",
   7642     "var asyncFn = async() => { function await() {} }",
   7643     "var O = { async method() { function await() {} } }",
   7644     "async function foo() { function await() {} }",
   7645 
   7646     // Henrique Ferreiro's bug (tm)
   7647     "(async function foo() { } foo => 1)",
   7648     "(async function foo() { } () => 1)",
   7649     "(async function foo() { } => 1)",
   7650     "(async function() { } foo => 1)",
   7651     "(async function() { } () => 1)",
   7652     "(async function() { } => 1)",
   7653     "(async.foo => 1)",
   7654     "(async.foo foo => 1)",
   7655     "(async.foo () => 1)",
   7656     "(async().foo => 1)",
   7657     "(async().foo foo => 1)",
   7658     "(async().foo () => 1)",
   7659     "(async['foo'] => 1)",
   7660     "(async['foo'] foo => 1)",
   7661     "(async['foo'] () => 1)",
   7662     "(async()['foo'] => 1)",
   7663     "(async()['foo'] foo => 1)",
   7664     "(async()['foo'] () => 1)",
   7665     "(async`foo` => 1)",
   7666     "(async`foo` foo => 1)",
   7667     "(async`foo` () => 1)",
   7668     "(async`foo`.bar => 1)",
   7669     "(async`foo`.bar foo => 1)",
   7670     "(async`foo`.bar () => 1)",
   7671 
   7672     // v8:5148 assert that errors are still thrown for calls that may have been
   7673     // async functions
   7674     "async({ foo = 1 })",
   7675     NULL
   7676   };
   7677 
   7678   const char* strict_error_data[] = {
   7679     "var O = { async method(eval) {} }",
   7680     "var O = { async ['meth' + 'od'](eval) {} }",
   7681     "var O = { async 'method'(eval) {} }",
   7682     "var O = { async 0(eval) {} }",
   7683 
   7684     "var O = { async method(arguments) {} }",
   7685     "var O = { async ['meth' + 'od'](arguments) {} }",
   7686     "var O = { async 'method'(arguments) {} }",
   7687     "var O = { async 0(arguments) {} }",
   7688 
   7689     "var O = { async method(dupe, dupe) {} }",
   7690 
   7691     // TODO(caitp): preparser needs to report duplicate parameter errors, too.
   7692     // "var f = async(dupe, dupe) => {}",
   7693 
   7694     NULL
   7695   };
   7696 
   7697   const char* formal_parameters_data[] = {
   7698     "var f = async({ await }) => 1;",
   7699     "var f = async({ await = 1 }) => 1;",
   7700     "var f = async({ await } = {}) => 1;",
   7701     "var f = async({ await = 1 } = {}) => 1;",
   7702     "var f = async([await]) => 1;",
   7703     "var f = async([await] = []) => 1;",
   7704     "var f = async([await = 1]) => 1;",
   7705     "var f = async([await = 1] = []) => 1;",
   7706     "var f = async(...await) => 1;",
   7707     "var f = async(await) => 1;",
   7708     "var f = async(await = 1) => 1;",
   7709     "var f = async(...[await]) => 1;",
   7710     NULL
   7711   };
   7712   // clang-format on
   7713 
   7714   static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
   7715   RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
   7716                     arraysize(always_flags));
   7717   RunParserSyncTest(strict_context_data, strict_error_data, kError, NULL, 0,
   7718                     always_flags, arraysize(always_flags));
   7719 
   7720   RunParserSyncTest(context_data, formal_parameters_data, kError, NULL, 0,
   7721                     always_flags, arraysize(always_flags));
   7722 }
   7723 
   7724 TEST(AsyncAwaitModule) {
   7725   // clang-format off
   7726   const char* context_data[][2] = {
   7727     { "", "" },
   7728     { NULL, NULL }
   7729   };
   7730 
   7731   const char* data[] = {
   7732     "export default async function() { await 1; }",
   7733     "export default async function async() { await 1; }",
   7734     "export async function async() { await 1; }",
   7735     NULL
   7736   };
   7737   // clang-format on
   7738 
   7739   static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
   7740   RunModuleParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
   7741                           arraysize(always_flags), NULL, 0, false);
   7742 }
   7743 
   7744 TEST(AsyncAwaitModuleErrors) {
   7745   // clang-format off
   7746   const char* context_data[][2] = {
   7747     { "", "" },
   7748     { NULL, NULL }
   7749   };
   7750 
   7751   const char* error_data[] = {
   7752     "export default (async function await() {})",
   7753     "export default async function await() {}",
   7754     "export async function await() {}",
   7755     "export async function() {}",
   7756     "export async",
   7757     NULL
   7758   };
   7759   // clang-format on
   7760 
   7761   static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
   7762   RunModuleParserSyncTest(context_data, error_data, kError, NULL, 0,
   7763                           always_flags, arraysize(always_flags), NULL, 0,
   7764                           false);
   7765 }
   7766 
   7767 TEST(RestrictiveForInErrors) {
   7768   // clang-format off
   7769   const char* context_data[][2] = {
   7770     { "'use strict'", "" },
   7771     { "", "" },
   7772     { NULL, NULL }
   7773   };
   7774   const char* error_data[] = {
   7775     "for (var x = 0 in {});",
   7776     "for (const x = 0 in {});",
   7777     "for (let x = 0 in {});",
   7778     NULL
   7779   };
   7780   // clang-format on
   7781 
   7782   static const ParserFlag always_flags[] = {kAllowHarmonyForIn};
   7783   RunParserSyncTest(context_data, error_data, kError, nullptr, 0, always_flags,
   7784                     arraysize(always_flags));
   7785 }
   7786 
   7787 TEST(NoDuplicateGeneratorsInBlock) {
   7788   const char* block_context_data[][2] = {
   7789       {"'use strict'; {", "}"},
   7790       {"{", "}"},
   7791       {"(function() { {", "} })()"},
   7792       {"(function() {'use strict'; {", "} })()"},
   7793       {NULL, NULL}};
   7794   const char* top_level_context_data[][2] = {
   7795       {"'use strict';", ""},
   7796       {"", ""},
   7797       {"(function() {", "})()"},
   7798       {"(function() {'use strict';", "})()"},
   7799       {NULL, NULL}};
   7800   const char* error_data[] = {"function* x() {} function* x() {}",
   7801                               "function x() {} function* x() {}",
   7802                               "function* x() {} function x() {}", NULL};
   7803   static const ParserFlag always_flags[] = {kAllowHarmonyRestrictiveGenerators};
   7804   // The preparser doesn't enforce the restriction, so turn it off.
   7805   bool test_preparser = false;
   7806   RunParserSyncTest(block_context_data, error_data, kError, NULL, 0,
   7807                     always_flags, arraysize(always_flags), NULL, 0, false,
   7808                     test_preparser);
   7809   RunParserSyncTest(top_level_context_data, error_data, kSuccess, NULL, 0,
   7810                     always_flags, arraysize(always_flags));
   7811 }
   7812 
   7813 TEST(NoDuplicateAsyncFunctionInBlock) {
   7814   const char* block_context_data[][2] = {
   7815       {"'use strict'; {", "}"},
   7816       {"{", "}"},
   7817       {"(function() { {", "} })()"},
   7818       {"(function() {'use strict'; {", "} })()"},
   7819       {NULL, NULL}};
   7820   const char* top_level_context_data[][2] = {
   7821       {"'use strict';", ""},
   7822       {"", ""},
   7823       {"(function() {", "})()"},
   7824       {"(function() {'use strict';", "})()"},
   7825       {NULL, NULL}};
   7826   const char* error_data[] = {"async function x() {} async function x() {}",
   7827                               "function x() {} async function x() {}",
   7828                               "async function x() {} function x() {}",
   7829                               "function* x() {} async function x() {}",
   7830                               "function* x() {} async function x() {}",
   7831                               "async function x() {} function* x() {}",
   7832                               "function* x() {} async function x() {}",
   7833                               NULL};
   7834   static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
   7835   // The preparser doesn't enforce the restriction, so turn it off.
   7836   bool test_preparser = false;
   7837   RunParserSyncTest(block_context_data, error_data, kError, NULL, 0,
   7838                     always_flags, arraysize(always_flags), NULL, 0, false,
   7839                     test_preparser);
   7840   RunParserSyncTest(top_level_context_data, error_data, kSuccess, NULL, 0,
   7841                     always_flags, arraysize(always_flags));
   7842 }
   7843