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-value-factory.h"
     35 #include "src/compiler.h"
     36 #include "src/execution.h"
     37 #include "src/isolate.h"
     38 #include "src/objects.h"
     39 #include "src/parser.h"
     40 #include "src/preparser.h"
     41 #include "src/rewriter.h"
     42 #include "src/scanner-character-streams.h"
     43 #include "src/token.h"
     44 #include "src/utils.h"
     45 
     46 #include "test/cctest/cctest.h"
     47 
     48 TEST(ScanKeywords) {
     49   struct KeywordToken {
     50     const char* keyword;
     51     i::Token::Value token;
     52   };
     53 
     54   static const KeywordToken keywords[] = {
     55 #define KEYWORD(t, s, d) { s, i::Token::t },
     56       TOKEN_LIST(IGNORE_TOKEN, KEYWORD)
     57 #undef KEYWORD
     58       { NULL, i::Token::IDENTIFIER }
     59   };
     60 
     61   KeywordToken key_token;
     62   i::UnicodeCache unicode_cache;
     63   i::byte buffer[32];
     64   for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
     65     const i::byte* keyword =
     66         reinterpret_cast<const i::byte*>(key_token.keyword);
     67     int length = i::StrLength(key_token.keyword);
     68     CHECK(static_cast<int>(sizeof(buffer)) >= length);
     69     {
     70       i::Utf8ToUtf16CharacterStream stream(keyword, length);
     71       i::Scanner scanner(&unicode_cache);
     72       // The scanner should parse Harmony keywords for this test.
     73       scanner.SetHarmonyScoping(true);
     74       scanner.SetHarmonyModules(true);
     75       scanner.SetHarmonyClasses(true);
     76       scanner.Initialize(&stream);
     77       CHECK_EQ(key_token.token, scanner.Next());
     78       CHECK_EQ(i::Token::EOS, scanner.Next());
     79     }
     80     // Removing characters will make keyword matching fail.
     81     {
     82       i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
     83       i::Scanner scanner(&unicode_cache);
     84       scanner.Initialize(&stream);
     85       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     86       CHECK_EQ(i::Token::EOS, scanner.Next());
     87     }
     88     // Adding characters will make keyword matching fail.
     89     static const char chars_to_append[] = { 'z', '0', '_' };
     90     for (int j = 0; j < static_cast<int>(arraysize(chars_to_append)); ++j) {
     91       i::MemMove(buffer, keyword, length);
     92       buffer[length] = chars_to_append[j];
     93       i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
     94       i::Scanner scanner(&unicode_cache);
     95       scanner.Initialize(&stream);
     96       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     97       CHECK_EQ(i::Token::EOS, scanner.Next());
     98     }
     99     // Replacing characters will make keyword matching fail.
    100     {
    101       i::MemMove(buffer, keyword, length);
    102       buffer[length - 1] = '_';
    103       i::Utf8ToUtf16CharacterStream stream(buffer, length);
    104       i::Scanner scanner(&unicode_cache);
    105       scanner.Initialize(&stream);
    106       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
    107       CHECK_EQ(i::Token::EOS, scanner.Next());
    108     }
    109   }
    110 }
    111 
    112 
    113 TEST(ScanHTMLEndComments) {
    114   v8::V8::Initialize();
    115   v8::Isolate* isolate = CcTest::isolate();
    116   v8::HandleScope handles(isolate);
    117 
    118   // Regression test. See:
    119   //    http://code.google.com/p/chromium/issues/detail?id=53548
    120   // Tests that --> is correctly interpreted as comment-to-end-of-line if there
    121   // is only whitespace before it on the line (with comments considered as
    122   // whitespace, even a multiline-comment containing a newline).
    123   // This was not the case if it occurred before the first real token
    124   // in the input.
    125   const char* tests[] = {
    126       // Before first real token.
    127       "--> is eol-comment\nvar y = 37;\n",
    128       "\n --> is eol-comment\nvar y = 37;\n",
    129       "/* precomment */ --> is eol-comment\nvar y = 37;\n",
    130       "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    131       // After first real token.
    132       "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
    133       "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    134       NULL
    135   };
    136 
    137   const char* fail_tests[] = {
    138       "x --> is eol-comment\nvar y = 37;\n",
    139       "\"\\n\" --> is eol-comment\nvar y = 37;\n",
    140       "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
    141       "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    142       "var x = 42; --> is eol-comment\nvar y = 37;\n",
    143       "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    144       NULL
    145   };
    146 
    147   // Parser/Scanner needs a stack limit.
    148   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    149       i::GetCurrentStackPosition() - 128 * 1024);
    150   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    151   for (int i = 0; tests[i]; i++) {
    152     const i::byte* source =
    153         reinterpret_cast<const i::byte*>(tests[i]);
    154     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i]));
    155     i::CompleteParserRecorder log;
    156     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    157     scanner.Initialize(&stream);
    158     i::PreParser preparser(&scanner, &log, stack_limit);
    159     preparser.set_allow_lazy(true);
    160     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    161     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    162     CHECK(!log.HasError());
    163   }
    164 
    165   for (int i = 0; fail_tests[i]; i++) {
    166     const i::byte* source =
    167         reinterpret_cast<const i::byte*>(fail_tests[i]);
    168     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i]));
    169     i::CompleteParserRecorder log;
    170     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    171     scanner.Initialize(&stream);
    172     i::PreParser preparser(&scanner, &log, stack_limit);
    173     preparser.set_allow_lazy(true);
    174     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    175     // Even in the case of a syntax error, kPreParseSuccess is returned.
    176     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    177     CHECK(log.HasError());
    178   }
    179 }
    180 
    181 
    182 class ScriptResource : public v8::String::ExternalOneByteStringResource {
    183  public:
    184   ScriptResource(const char* data, size_t length)
    185       : data_(data), length_(length) { }
    186 
    187   const char* data() const { return data_; }
    188   size_t length() const { return length_; }
    189 
    190  private:
    191   const char* data_;
    192   size_t length_;
    193 };
    194 
    195 
    196 TEST(UsingCachedData) {
    197   v8::Isolate* isolate = CcTest::isolate();
    198   v8::HandleScope handles(isolate);
    199   v8::Local<v8::Context> context = v8::Context::New(isolate);
    200   v8::Context::Scope context_scope(context);
    201   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    202       i::GetCurrentStackPosition() - 128 * 1024);
    203 
    204   // Source containing functions that might be lazily compiled  and all types
    205   // of symbols (string, propertyName, regexp).
    206   const char* source =
    207       "var x = 42;"
    208       "function foo(a) { return function nolazy(b) { return a + b; } }"
    209       "function bar(a) { if (a) return function lazy(b) { return b; } }"
    210       "var z = {'string': 'string literal', bareword: 'propertyName', "
    211       "         42: 'number literal', for: 'keyword as propertyName', "
    212       "         f\\u006fr: 'keyword propertyname with escape'};"
    213       "var v = /RegExp Literal/;"
    214       "var w = /RegExp Literal\\u0020With Escape/gin;"
    215       "var y = { get getter() { return 42; }, "
    216       "          set setter(v) { this.value = v; }};"
    217       "var f = a => function (b) { return a + b; };"
    218       "var g = a => b => a + b;";
    219   int source_length = i::StrLength(source);
    220 
    221   // ScriptResource will be deleted when the corresponding String is GCd.
    222   v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
    223       isolate, new ScriptResource(source, source_length)));
    224   i::FLAG_harmony_arrow_functions = true;
    225   i::FLAG_min_preparse_length = 0;
    226   v8::ScriptCompiler::Compile(isolate, &script_source,
    227                               v8::ScriptCompiler::kProduceParserCache);
    228   CHECK(script_source.GetCachedData());
    229 
    230   // Compile the script again, using the cached data.
    231   bool lazy_flag = i::FLAG_lazy;
    232   i::FLAG_lazy = true;
    233   v8::ScriptCompiler::Compile(isolate, &script_source,
    234                               v8::ScriptCompiler::kConsumeParserCache);
    235   i::FLAG_lazy = false;
    236   v8::ScriptCompiler::CompileUnbound(isolate, &script_source,
    237                                      v8::ScriptCompiler::kConsumeParserCache);
    238   i::FLAG_lazy = lazy_flag;
    239 }
    240 
    241 
    242 TEST(PreparseFunctionDataIsUsed) {
    243   // This tests that we actually do use the function data generated by the
    244   // preparser.
    245 
    246   // Make preparsing work for short scripts.
    247   i::FLAG_min_preparse_length = 0;
    248   i::FLAG_harmony_arrow_functions = true;
    249 
    250   v8::Isolate* isolate = CcTest::isolate();
    251   v8::HandleScope handles(isolate);
    252   v8::Local<v8::Context> context = v8::Context::New(isolate);
    253   v8::Context::Scope context_scope(context);
    254   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    255       i::GetCurrentStackPosition() - 128 * 1024);
    256 
    257   const char* good_code[] = {
    258       "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
    259       "var this_is_lazy = () => { var a; }; var foo = () => 25; foo();",
    260   };
    261 
    262   // Insert a syntax error inside the lazy function.
    263   const char* bad_code[] = {
    264       "function this_is_lazy() { if (   } function foo() { return 25; } foo();",
    265       "var this_is_lazy = () => { if (   }; var foo = () => 25; foo();",
    266   };
    267 
    268   for (unsigned i = 0; i < arraysize(good_code); i++) {
    269     v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
    270     v8::ScriptCompiler::Compile(isolate, &good_source,
    271                                 v8::ScriptCompiler::kProduceDataToCache);
    272 
    273     const v8::ScriptCompiler::CachedData* cached_data =
    274         good_source.GetCachedData();
    275     CHECK(cached_data->data != NULL);
    276     CHECK_GT(cached_data->length, 0);
    277 
    278     // Now compile the erroneous code with the good preparse data. If the
    279     // preparse data is used, the lazy function is skipped and it should
    280     // compile fine.
    281     v8::ScriptCompiler::Source bad_source(
    282         v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
    283                                  cached_data->data, cached_data->length));
    284     v8::Local<v8::Value> result =
    285         v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
    286     CHECK(result->IsInt32());
    287     CHECK_EQ(25, result->Int32Value());
    288   }
    289 }
    290 
    291 
    292 TEST(StandAlonePreParser) {
    293   v8::V8::Initialize();
    294 
    295   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    296       i::GetCurrentStackPosition() - 128 * 1024);
    297 
    298   const char* programs[] = {
    299       "{label: 42}",
    300       "var x = 42;",
    301       "function foo(x, y) { return x + y; }",
    302       "%ArgleBargle(glop);",
    303       "var x = new new Function('this.x = 42');",
    304       "var f = (x, y) => x + y;",
    305       NULL
    306   };
    307 
    308   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    309   for (int i = 0; programs[i]; i++) {
    310     const char* program = programs[i];
    311     i::Utf8ToUtf16CharacterStream stream(
    312         reinterpret_cast<const i::byte*>(program),
    313         static_cast<unsigned>(strlen(program)));
    314     i::CompleteParserRecorder log;
    315     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    316     scanner.Initialize(&stream);
    317 
    318     i::PreParser preparser(&scanner, &log, stack_limit);
    319     preparser.set_allow_lazy(true);
    320     preparser.set_allow_natives_syntax(true);
    321     preparser.set_allow_arrow_functions(true);
    322     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    323     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    324     CHECK(!log.HasError());
    325   }
    326 }
    327 
    328 
    329 TEST(StandAlonePreParserNoNatives) {
    330   v8::V8::Initialize();
    331 
    332   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    333       i::GetCurrentStackPosition() - 128 * 1024);
    334 
    335   const char* programs[] = {
    336       "%ArgleBargle(glop);",
    337       "var x = %_IsSmi(42);",
    338       NULL
    339   };
    340 
    341   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    342   for (int i = 0; programs[i]; i++) {
    343     const char* program = programs[i];
    344     i::Utf8ToUtf16CharacterStream stream(
    345         reinterpret_cast<const i::byte*>(program),
    346         static_cast<unsigned>(strlen(program)));
    347     i::CompleteParserRecorder log;
    348     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    349     scanner.Initialize(&stream);
    350 
    351     // Preparser defaults to disallowing natives syntax.
    352     i::PreParser preparser(&scanner, &log, stack_limit);
    353     preparser.set_allow_lazy(true);
    354     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    355     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    356     CHECK(log.HasError());
    357   }
    358 }
    359 
    360 
    361 TEST(PreparsingObjectLiterals) {
    362   // Regression test for a bug where the symbol stream produced by PreParser
    363   // didn't match what Parser wanted to consume.
    364   v8::Isolate* isolate = CcTest::isolate();
    365   v8::HandleScope handles(isolate);
    366   v8::Local<v8::Context> context = v8::Context::New(isolate);
    367   v8::Context::Scope context_scope(context);
    368   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    369       i::GetCurrentStackPosition() - 128 * 1024);
    370 
    371   {
    372     const char* source = "var myo = {if: \"foo\"}; myo.if;";
    373     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    374     CHECK(result->IsString());
    375     v8::String::Utf8Value utf8(result);
    376     CHECK_EQ("foo", *utf8);
    377   }
    378 
    379   {
    380     const char* source = "var myo = {\"bar\": \"foo\"}; myo[\"bar\"];";
    381     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    382     CHECK(result->IsString());
    383     v8::String::Utf8Value utf8(result);
    384     CHECK_EQ("foo", *utf8);
    385   }
    386 
    387   {
    388     const char* source = "var myo = {1: \"foo\"}; myo[1];";
    389     v8::Local<v8::Value> result = ParserCacheCompileRun(source);
    390     CHECK(result->IsString());
    391     v8::String::Utf8Value utf8(result);
    392     CHECK_EQ("foo", *utf8);
    393   }
    394 }
    395 
    396 
    397 TEST(RegressChromium62639) {
    398   v8::V8::Initialize();
    399   i::Isolate* isolate = CcTest::i_isolate();
    400 
    401   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    402                                         128 * 1024);
    403 
    404   const char* program = "var x = 'something';\n"
    405                         "escape: function() {}";
    406   // Fails parsing expecting an identifier after "function".
    407   // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
    408   // and then used the invalid currently scanned literal. This always
    409   // failed in debug mode, and sometimes crashed in release mode.
    410 
    411   i::Utf8ToUtf16CharacterStream stream(
    412       reinterpret_cast<const i::byte*>(program),
    413       static_cast<unsigned>(strlen(program)));
    414   i::CompleteParserRecorder log;
    415   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    416   scanner.Initialize(&stream);
    417   i::PreParser preparser(&scanner, &log,
    418                          CcTest::i_isolate()->stack_guard()->real_climit());
    419   preparser.set_allow_lazy(true);
    420   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    421   // Even in the case of a syntax error, kPreParseSuccess is returned.
    422   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    423   CHECK(log.HasError());
    424 }
    425 
    426 
    427 TEST(Regress928) {
    428   v8::V8::Initialize();
    429   i::Isolate* isolate = CcTest::i_isolate();
    430   i::Factory* factory = isolate->factory();
    431 
    432   // Preparsing didn't consider the catch clause of a try statement
    433   // as with-content, which made it assume that a function inside
    434   // the block could be lazily compiled, and an extra, unexpected,
    435   // entry was added to the data.
    436   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    437                                         128 * 1024);
    438 
    439   const char* program =
    440       "try { } catch (e) { var foo = function () { /* first */ } }"
    441       "var bar = function () { /* second */ }";
    442 
    443   v8::HandleScope handles(CcTest::isolate());
    444   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(program);
    445   i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
    446   i::CompleteParserRecorder log;
    447   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    448   scanner.Initialize(&stream);
    449   i::PreParser preparser(&scanner, &log,
    450                          CcTest::i_isolate()->stack_guard()->real_climit());
    451   preparser.set_allow_lazy(true);
    452   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    453   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    454   i::ScriptData* sd = log.GetScriptData();
    455   i::ParseData pd(sd);
    456   pd.Initialize();
    457 
    458   int first_function =
    459       static_cast<int>(strstr(program, "function") - program);
    460   int first_lbrace = first_function + i::StrLength("function () ");
    461   CHECK_EQ('{', program[first_lbrace]);
    462   i::FunctionEntry entry1 = pd.GetFunctionEntry(first_lbrace);
    463   CHECK(!entry1.is_valid());
    464 
    465   int second_function =
    466       static_cast<int>(strstr(program + first_lbrace, "function") - program);
    467   int second_lbrace =
    468       second_function + i::StrLength("function () ");
    469   CHECK_EQ('{', program[second_lbrace]);
    470   i::FunctionEntry entry2 = pd.GetFunctionEntry(second_lbrace);
    471   CHECK(entry2.is_valid());
    472   CHECK_EQ('}', program[entry2.end_pos() - 1]);
    473   delete sd;
    474 }
    475 
    476 
    477 TEST(PreParseOverflow) {
    478   v8::V8::Initialize();
    479 
    480   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    481       i::GetCurrentStackPosition() - 128 * 1024);
    482 
    483   size_t kProgramSize = 1024 * 1024;
    484   i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1));
    485   memset(program.get(), '(', kProgramSize);
    486   program[kProgramSize] = '\0';
    487 
    488   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    489 
    490   i::Utf8ToUtf16CharacterStream stream(
    491       reinterpret_cast<const i::byte*>(program.get()),
    492       static_cast<unsigned>(kProgramSize));
    493   i::CompleteParserRecorder log;
    494   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    495   scanner.Initialize(&stream);
    496 
    497   i::PreParser preparser(&scanner, &log, stack_limit);
    498   preparser.set_allow_lazy(true);
    499   preparser.set_allow_arrow_functions(true);
    500   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    501   CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
    502 }
    503 
    504 
    505 class TestExternalResource: public v8::String::ExternalStringResource {
    506  public:
    507   explicit TestExternalResource(uint16_t* data, int length)
    508       : data_(data), length_(static_cast<size_t>(length)) { }
    509 
    510   ~TestExternalResource() { }
    511 
    512   const uint16_t* data() const {
    513     return data_;
    514   }
    515 
    516   size_t length() const {
    517     return length_;
    518   }
    519  private:
    520   uint16_t* data_;
    521   size_t length_;
    522 };
    523 
    524 
    525 #define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
    526 
    527 void TestCharacterStream(const char* one_byte_source, unsigned length,
    528                          unsigned start = 0, unsigned end = 0) {
    529   if (end == 0) end = length;
    530   unsigned sub_length = end - start;
    531   i::Isolate* isolate = CcTest::i_isolate();
    532   i::Factory* factory = isolate->factory();
    533   i::HandleScope test_scope(isolate);
    534   i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
    535   for (unsigned i = 0; i < length; i++) {
    536     uc16_buffer[i] = static_cast<i::uc16>(one_byte_source[i]);
    537   }
    538   i::Vector<const char> one_byte_vector(one_byte_source,
    539                                         static_cast<int>(length));
    540   i::Handle<i::String> one_byte_string =
    541       factory->NewStringFromAscii(one_byte_vector).ToHandleChecked();
    542   TestExternalResource resource(uc16_buffer.get(), length);
    543   i::Handle<i::String> uc16_string(
    544       factory->NewExternalStringFromTwoByte(&resource).ToHandleChecked());
    545 
    546   i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
    547       i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
    548   i::GenericStringUtf16CharacterStream string_stream(one_byte_string, start,
    549                                                      end);
    550   i::Utf8ToUtf16CharacterStream utf8_stream(
    551       reinterpret_cast<const i::byte*>(one_byte_source), end);
    552   utf8_stream.SeekForward(start);
    553 
    554   unsigned i = start;
    555   while (i < end) {
    556     // Read streams one char at a time
    557     CHECK_EQU(i, uc16_stream.pos());
    558     CHECK_EQU(i, string_stream.pos());
    559     CHECK_EQU(i, utf8_stream.pos());
    560     int32_t c0 = one_byte_source[i];
    561     int32_t c1 = uc16_stream.Advance();
    562     int32_t c2 = string_stream.Advance();
    563     int32_t c3 = utf8_stream.Advance();
    564     i++;
    565     CHECK_EQ(c0, c1);
    566     CHECK_EQ(c0, c2);
    567     CHECK_EQ(c0, c3);
    568     CHECK_EQU(i, uc16_stream.pos());
    569     CHECK_EQU(i, string_stream.pos());
    570     CHECK_EQU(i, utf8_stream.pos());
    571   }
    572   while (i > start + sub_length / 4) {
    573     // Pushback, re-read, pushback again.
    574     int32_t c0 = one_byte_source[i - 1];
    575     CHECK_EQU(i, uc16_stream.pos());
    576     CHECK_EQU(i, string_stream.pos());
    577     CHECK_EQU(i, utf8_stream.pos());
    578     uc16_stream.PushBack(c0);
    579     string_stream.PushBack(c0);
    580     utf8_stream.PushBack(c0);
    581     i--;
    582     CHECK_EQU(i, uc16_stream.pos());
    583     CHECK_EQU(i, string_stream.pos());
    584     CHECK_EQU(i, utf8_stream.pos());
    585     int32_t c1 = uc16_stream.Advance();
    586     int32_t c2 = string_stream.Advance();
    587     int32_t c3 = utf8_stream.Advance();
    588     i++;
    589     CHECK_EQU(i, uc16_stream.pos());
    590     CHECK_EQU(i, string_stream.pos());
    591     CHECK_EQU(i, utf8_stream.pos());
    592     CHECK_EQ(c0, c1);
    593     CHECK_EQ(c0, c2);
    594     CHECK_EQ(c0, c3);
    595     uc16_stream.PushBack(c0);
    596     string_stream.PushBack(c0);
    597     utf8_stream.PushBack(c0);
    598     i--;
    599     CHECK_EQU(i, uc16_stream.pos());
    600     CHECK_EQU(i, string_stream.pos());
    601     CHECK_EQU(i, utf8_stream.pos());
    602   }
    603   unsigned halfway = start + sub_length / 2;
    604   uc16_stream.SeekForward(halfway - i);
    605   string_stream.SeekForward(halfway - i);
    606   utf8_stream.SeekForward(halfway - i);
    607   i = halfway;
    608   CHECK_EQU(i, uc16_stream.pos());
    609   CHECK_EQU(i, string_stream.pos());
    610   CHECK_EQU(i, utf8_stream.pos());
    611 
    612   while (i < end) {
    613     // Read streams one char at a time
    614     CHECK_EQU(i, uc16_stream.pos());
    615     CHECK_EQU(i, string_stream.pos());
    616     CHECK_EQU(i, utf8_stream.pos());
    617     int32_t c0 = one_byte_source[i];
    618     int32_t c1 = uc16_stream.Advance();
    619     int32_t c2 = string_stream.Advance();
    620     int32_t c3 = utf8_stream.Advance();
    621     i++;
    622     CHECK_EQ(c0, c1);
    623     CHECK_EQ(c0, c2);
    624     CHECK_EQ(c0, c3);
    625     CHECK_EQU(i, uc16_stream.pos());
    626     CHECK_EQU(i, string_stream.pos());
    627     CHECK_EQU(i, utf8_stream.pos());
    628   }
    629 
    630   int32_t c1 = uc16_stream.Advance();
    631   int32_t c2 = string_stream.Advance();
    632   int32_t c3 = utf8_stream.Advance();
    633   CHECK_LT(c1, 0);
    634   CHECK_LT(c2, 0);
    635   CHECK_LT(c3, 0);
    636 }
    637 
    638 
    639 TEST(CharacterStreams) {
    640   v8::Isolate* isolate = CcTest::isolate();
    641   v8::HandleScope handles(isolate);
    642   v8::Local<v8::Context> context = v8::Context::New(isolate);
    643   v8::Context::Scope context_scope(context);
    644 
    645   TestCharacterStream("abc\0\n\r\x7f", 7);
    646   static const unsigned kBigStringSize = 4096;
    647   char buffer[kBigStringSize + 1];
    648   for (unsigned i = 0; i < kBigStringSize; i++) {
    649     buffer[i] = static_cast<char>(i & 0x7f);
    650   }
    651   TestCharacterStream(buffer, kBigStringSize);
    652 
    653   TestCharacterStream(buffer, kBigStringSize, 576, 3298);
    654 
    655   TestCharacterStream("\0", 1);
    656   TestCharacterStream("", 0);
    657 }
    658 
    659 
    660 TEST(Utf8CharacterStream) {
    661   static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar;
    662   static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU);
    663 
    664   static const int kAllUtf8CharsSize =
    665       (unibrow::Utf8::kMaxOneByteChar + 1) +
    666       (unibrow::Utf8::kMaxTwoByteChar - unibrow::Utf8::kMaxOneByteChar) * 2 +
    667       (unibrow::Utf8::kMaxThreeByteChar - unibrow::Utf8::kMaxTwoByteChar) * 3;
    668   static const unsigned kAllUtf8CharsSizeU =
    669       static_cast<unsigned>(kAllUtf8CharsSize);
    670 
    671   char buffer[kAllUtf8CharsSizeU];
    672   unsigned cursor = 0;
    673   for (int i = 0; i <= kMaxUC16Char; i++) {
    674     cursor += unibrow::Utf8::Encode(buffer + cursor,
    675                                     i,
    676                                     unibrow::Utf16::kNoPreviousCharacter);
    677   }
    678   DCHECK(cursor == kAllUtf8CharsSizeU);
    679 
    680   i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
    681                                        kAllUtf8CharsSizeU);
    682   for (int i = 0; i <= kMaxUC16Char; i++) {
    683     CHECK_EQU(i, stream.pos());
    684     int32_t c = stream.Advance();
    685     CHECK_EQ(i, c);
    686     CHECK_EQU(i + 1, stream.pos());
    687   }
    688   for (int i = kMaxUC16Char; i >= 0; i--) {
    689     CHECK_EQU(i + 1, stream.pos());
    690     stream.PushBack(i);
    691     CHECK_EQU(i, stream.pos());
    692   }
    693   int i = 0;
    694   while (stream.pos() < kMaxUC16CharU) {
    695     CHECK_EQU(i, stream.pos());
    696     unsigned progress = stream.SeekForward(12);
    697     i += progress;
    698     int32_t c = stream.Advance();
    699     if (i <= kMaxUC16Char) {
    700       CHECK_EQ(i, c);
    701     } else {
    702       CHECK_EQ(-1, c);
    703     }
    704     i += 1;
    705     CHECK_EQU(i, stream.pos());
    706   }
    707 }
    708 
    709 #undef CHECK_EQU
    710 
    711 void TestStreamScanner(i::Utf16CharacterStream* stream,
    712                        i::Token::Value* expected_tokens,
    713                        int skip_pos = 0,  // Zero means not skipping.
    714                        int skip_to = 0) {
    715   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    716   scanner.Initialize(stream);
    717 
    718   int i = 0;
    719   do {
    720     i::Token::Value expected = expected_tokens[i];
    721     i::Token::Value actual = scanner.Next();
    722     CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
    723     if (scanner.location().end_pos == skip_pos) {
    724       scanner.SeekForward(skip_to);
    725     }
    726     i++;
    727   } while (expected_tokens[i] != i::Token::ILLEGAL);
    728 }
    729 
    730 
    731 TEST(StreamScanner) {
    732   v8::V8::Initialize();
    733 
    734   const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
    735   i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
    736                                         static_cast<unsigned>(strlen(str1)));
    737   i::Token::Value expectations1[] = {
    738       i::Token::LBRACE,
    739       i::Token::IDENTIFIER,
    740       i::Token::IDENTIFIER,
    741       i::Token::FOR,
    742       i::Token::COLON,
    743       i::Token::MUL,
    744       i::Token::DIV,
    745       i::Token::LT,
    746       i::Token::SUB,
    747       i::Token::IDENTIFIER,
    748       i::Token::EOS,
    749       i::Token::ILLEGAL
    750   };
    751   TestStreamScanner(&stream1, expectations1, 0, 0);
    752 
    753   const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
    754   i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
    755                                         static_cast<unsigned>(strlen(str2)));
    756   i::Token::Value expectations2[] = {
    757       i::Token::CASE,
    758       i::Token::DEFAULT,
    759       i::Token::CONST,
    760       i::Token::LBRACE,
    761       // Skipped part here
    762       i::Token::RBRACE,
    763       i::Token::DO,
    764       i::Token::EOS,
    765       i::Token::ILLEGAL
    766   };
    767   DCHECK_EQ('{', str2[19]);
    768   DCHECK_EQ('}', str2[37]);
    769   TestStreamScanner(&stream2, expectations2, 20, 37);
    770 
    771   const char* str3 = "{}}}}";
    772   i::Token::Value expectations3[] = {
    773       i::Token::LBRACE,
    774       i::Token::RBRACE,
    775       i::Token::RBRACE,
    776       i::Token::RBRACE,
    777       i::Token::RBRACE,
    778       i::Token::EOS,
    779       i::Token::ILLEGAL
    780   };
    781   // Skip zero-four RBRACEs.
    782   for (int i = 0; i <= 4; i++) {
    783      expectations3[6 - i] = i::Token::ILLEGAL;
    784      expectations3[5 - i] = i::Token::EOS;
    785      i::Utf8ToUtf16CharacterStream stream3(
    786          reinterpret_cast<const i::byte*>(str3),
    787          static_cast<unsigned>(strlen(str3)));
    788      TestStreamScanner(&stream3, expectations3, 1, 1 + i);
    789   }
    790 }
    791 
    792 
    793 void TestScanRegExp(const char* re_source, const char* expected) {
    794   i::Utf8ToUtf16CharacterStream stream(
    795        reinterpret_cast<const i::byte*>(re_source),
    796        static_cast<unsigned>(strlen(re_source)));
    797   i::HandleScope scope(CcTest::i_isolate());
    798   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    799   scanner.Initialize(&stream);
    800 
    801   i::Token::Value start = scanner.peek();
    802   CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
    803   CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
    804   scanner.Next();  // Current token is now the regexp literal.
    805   i::Zone zone(CcTest::i_isolate());
    806   i::AstValueFactory ast_value_factory(&zone,
    807                                        CcTest::i_isolate()->heap()->HashSeed());
    808   ast_value_factory.Internalize(CcTest::i_isolate());
    809   i::Handle<i::String> val =
    810       scanner.CurrentSymbol(&ast_value_factory)->string();
    811   i::DisallowHeapAllocation no_alloc;
    812   i::String::FlatContent content = val->GetFlatContent();
    813   CHECK(content.IsOneByte());
    814   i::Vector<const uint8_t> actual = content.ToOneByteVector();
    815   for (int i = 0; i < actual.length(); i++) {
    816     CHECK_NE('\0', expected[i]);
    817     CHECK_EQ(expected[i], actual[i]);
    818   }
    819 }
    820 
    821 
    822 TEST(RegExpScanning) {
    823   v8::V8::Initialize();
    824 
    825   // RegExp token with added garbage at the end. The scanner should only
    826   // scan the RegExp until the terminating slash just before "flipperwald".
    827   TestScanRegExp("/b/flipperwald", "b");
    828   // Incomplete escape sequences doesn't hide the terminating slash.
    829   TestScanRegExp("/\\x/flipperwald", "\\x");
    830   TestScanRegExp("/\\u/flipperwald", "\\u");
    831   TestScanRegExp("/\\u1/flipperwald", "\\u1");
    832   TestScanRegExp("/\\u12/flipperwald", "\\u12");
    833   TestScanRegExp("/\\u123/flipperwald", "\\u123");
    834   TestScanRegExp("/\\c/flipperwald", "\\c");
    835   TestScanRegExp("/\\c//flipperwald", "\\c");
    836   // Slashes inside character classes are not terminating.
    837   TestScanRegExp("/[/]/flipperwald", "[/]");
    838   TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
    839   // Incomplete escape sequences inside a character class doesn't hide
    840   // the end of the character class.
    841   TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
    842   TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
    843   TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
    844   TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
    845   TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
    846   TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
    847   TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
    848   TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
    849   // Escaped ']'s wont end the character class.
    850   TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
    851   // Escaped slashes are not terminating.
    852   TestScanRegExp("/\\//flipperwald", "\\/");
    853   // Starting with '=' works too.
    854   TestScanRegExp("/=/", "=");
    855   TestScanRegExp("/=?/", "=?");
    856 }
    857 
    858 
    859 static int Utf8LengthHelper(const char* s) {
    860   int len = i::StrLength(s);
    861   int character_length = len;
    862   for (int i = 0; i < len; i++) {
    863     unsigned char c = s[i];
    864     int input_offset = 0;
    865     int output_adjust = 0;
    866     if (c > 0x7f) {
    867       if (c < 0xc0) continue;
    868       if (c >= 0xf0) {
    869         if (c >= 0xf8) {
    870           // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
    871           // byte.
    872           continue;  // Handle first UTF-8 byte.
    873         }
    874         if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
    875           // This 4 byte sequence could have been coded as a 3 byte sequence.
    876           // Record a single kBadChar for the first byte and continue.
    877           continue;
    878         }
    879         input_offset = 3;
    880         // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
    881         character_length -= 2;
    882       } else if (c >= 0xe0) {
    883         if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
    884           // This 3 byte sequence could have been coded as a 2 byte sequence.
    885           // Record a single kBadChar for the first byte and continue.
    886           continue;
    887         }
    888         input_offset = 2;
    889         // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
    890         output_adjust = 2;
    891       } else {
    892         if ((c & 0x1e) == 0) {
    893           // This 2 byte sequence could have been coded as a 1 byte sequence.
    894           // Record a single kBadChar for the first byte and continue.
    895           continue;
    896         }
    897         input_offset = 1;
    898         // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
    899         output_adjust = 1;
    900       }
    901       bool bad = false;
    902       for (int j = 1; j <= input_offset; j++) {
    903         if ((s[i + j] & 0xc0) != 0x80) {
    904           // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
    905           // which is a single UTF-16 code unit.
    906           bad = true;
    907           break;
    908         }
    909       }
    910       if (!bad) {
    911         i += input_offset;
    912         character_length -= output_adjust;
    913       }
    914     }
    915   }
    916   return character_length;
    917 }
    918 
    919 
    920 TEST(ScopePositions) {
    921   v8::internal::FLAG_harmony_scoping = true;
    922 
    923   // Test the parser for correctly setting the start and end positions
    924   // of a scope. We check the scope positions of exactly one scope
    925   // nested in the global scope of a program. 'inner source' is the
    926   // source code that determines the part of the source belonging
    927   // to the nested scope. 'outer_prefix' and 'outer_suffix' are
    928   // parts of the source that belong to the global scope.
    929   struct SourceData {
    930     const char* outer_prefix;
    931     const char* inner_source;
    932     const char* outer_suffix;
    933     i::ScopeType scope_type;
    934     i::StrictMode strict_mode;
    935   };
    936 
    937   const SourceData source_data[] = {
    938     { "  with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::SLOPPY },
    939     { "  with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::SLOPPY },
    940     { "  with ({}) ", "{\n"
    941       "    block;\n"
    942       "  }", "\n"
    943       "  more;", i::WITH_SCOPE, i::SLOPPY },
    944     { "  with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::SLOPPY },
    945     { "  with ({}) ", "statement", "\n"
    946       "  more;", i::WITH_SCOPE, i::SLOPPY },
    947     { "  with ({})\n"
    948       "    ", "statement;", "\n"
    949       "  more;", i::WITH_SCOPE, i::SLOPPY },
    950     { "  try {} catch ", "(e) { block; }", " more;",
    951       i::CATCH_SCOPE, i::SLOPPY },
    952     { "  try {} catch ", "(e) { block; }", "; more;",
    953       i::CATCH_SCOPE, i::SLOPPY },
    954     { "  try {} catch ", "(e) {\n"
    955       "    block;\n"
    956       "  }", "\n"
    957       "  more;", i::CATCH_SCOPE, i::SLOPPY },
    958     { "  try {} catch ", "(e) { block; }", " finally { block; } more;",
    959       i::CATCH_SCOPE, i::SLOPPY },
    960     { "  start;\n"
    961       "  ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::STRICT },
    962     { "  start;\n"
    963       "  ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::STRICT },
    964     { "  start;\n"
    965       "  ", "{\n"
    966       "    let block;\n"
    967       "  }", "\n"
    968       "  more;", i::BLOCK_SCOPE, i::STRICT },
    969     { "  start;\n"
    970       "  function fun", "(a,b) { infunction; }", " more;",
    971       i::FUNCTION_SCOPE, i::SLOPPY },
    972     { "  start;\n"
    973       "  function fun", "(a,b) {\n"
    974       "    infunction;\n"
    975       "  }", "\n"
    976       "  more;", i::FUNCTION_SCOPE, i::SLOPPY },
    977     // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
    978     { "  start;\n", "(a,b) => a + b", "; more;",
    979       i::FUNCTION_SCOPE, i::SLOPPY },
    980     { "  start;\n", "(a,b) => { return a+b; }", "\nmore;",
    981       i::FUNCTION_SCOPE, i::SLOPPY },
    982     { "  start;\n"
    983       "  (function fun", "(a,b) { infunction; }", ")();",
    984       i::FUNCTION_SCOPE, i::SLOPPY },
    985     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
    986       i::BLOCK_SCOPE, i::STRICT },
    987     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
    988       i::BLOCK_SCOPE, i::STRICT },
    989     { "  for ", "(let x = 1 ; x < 10; ++ x) {\n"
    990       "    block;\n"
    991       "  }", "\n"
    992       "  more;", i::BLOCK_SCOPE, i::STRICT },
    993     { "  for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
    994       i::BLOCK_SCOPE, i::STRICT },
    995     { "  for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
    996       "  more;", i::BLOCK_SCOPE, i::STRICT },
    997     { "  for ", "(let x = 1 ; x < 10; ++ x)\n"
    998       "    statement;", "\n"
    999       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1000     { "  for ", "(let x in {}) { block; }", " more;",
   1001       i::BLOCK_SCOPE, i::STRICT },
   1002     { "  for ", "(let x in {}) { block; }", "; more;",
   1003       i::BLOCK_SCOPE, i::STRICT },
   1004     { "  for ", "(let x in {}) {\n"
   1005       "    block;\n"
   1006       "  }", "\n"
   1007       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1008     { "  for ", "(let x in {}) statement;", " more;",
   1009       i::BLOCK_SCOPE, i::STRICT },
   1010     { "  for ", "(let x in {}) statement", "\n"
   1011       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1012     { "  for ", "(let x in {})\n"
   1013       "    statement;", "\n"
   1014       "  more;", i::BLOCK_SCOPE, i::STRICT },
   1015     // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
   1016     // the preparser off in terms of byte offsets.
   1017     // 6 byte encoding.
   1018     { "  'foo\355\240\201\355\260\211';\n"
   1019       "  (function fun", "(a,b) { infunction; }", ")();",
   1020       i::FUNCTION_SCOPE, i::SLOPPY },
   1021     // 4 byte encoding.
   1022     { "  'foo\360\220\220\212';\n"
   1023       "  (function fun", "(a,b) { infunction; }", ")();",
   1024       i::FUNCTION_SCOPE, i::SLOPPY },
   1025     // 3 byte encoding of \u0fff.
   1026     { "  'foo\340\277\277';\n"
   1027       "  (function fun", "(a,b) { infunction; }", ")();",
   1028       i::FUNCTION_SCOPE, i::SLOPPY },
   1029     // Broken 6 byte encoding with missing last byte.
   1030     { "  'foo\355\240\201\355\211';\n"
   1031       "  (function fun", "(a,b) { infunction; }", ")();",
   1032       i::FUNCTION_SCOPE, i::SLOPPY },
   1033     // Broken 3 byte encoding of \u0fff with missing last byte.
   1034     { "  'foo\340\277';\n"
   1035       "  (function fun", "(a,b) { infunction; }", ")();",
   1036       i::FUNCTION_SCOPE, i::SLOPPY },
   1037     // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
   1038     { "  'foo\340';\n"
   1039       "  (function fun", "(a,b) { infunction; }", ")();",
   1040       i::FUNCTION_SCOPE, i::SLOPPY },
   1041     // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
   1042     { "  'foo\340\203\277';\n"
   1043       "  (function fun", "(a,b) { infunction; }", ")();",
   1044       i::FUNCTION_SCOPE, i::SLOPPY },
   1045     // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
   1046     { "  'foo\340\201\277';\n"
   1047       "  (function fun", "(a,b) { infunction; }", ")();",
   1048       i::FUNCTION_SCOPE, i::SLOPPY },
   1049     // Unpaired lead surrogate.
   1050     { "  'foo\355\240\201';\n"
   1051       "  (function fun", "(a,b) { infunction; }", ")();",
   1052       i::FUNCTION_SCOPE, i::SLOPPY },
   1053     // Unpaired lead surrogate where following code point is a 3 byte sequence.
   1054     { "  'foo\355\240\201\340\277\277';\n"
   1055       "  (function fun", "(a,b) { infunction; }", ")();",
   1056       i::FUNCTION_SCOPE, i::SLOPPY },
   1057     // Unpaired lead surrogate where following code point is a 4 byte encoding
   1058     // of a trail surrogate.
   1059     { "  'foo\355\240\201\360\215\260\211';\n"
   1060       "  (function fun", "(a,b) { infunction; }", ")();",
   1061       i::FUNCTION_SCOPE, i::SLOPPY },
   1062     // Unpaired trail surrogate.
   1063     { "  'foo\355\260\211';\n"
   1064       "  (function fun", "(a,b) { infunction; }", ")();",
   1065       i::FUNCTION_SCOPE, i::SLOPPY },
   1066     // 2 byte encoding of \u00ff.
   1067     { "  'foo\303\277';\n"
   1068       "  (function fun", "(a,b) { infunction; }", ")();",
   1069       i::FUNCTION_SCOPE, i::SLOPPY },
   1070     // Broken 2 byte encoding of \u00ff with missing last byte.
   1071     { "  'foo\303';\n"
   1072       "  (function fun", "(a,b) { infunction; }", ")();",
   1073       i::FUNCTION_SCOPE, i::SLOPPY },
   1074     // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
   1075     { "  'foo\301\277';\n"
   1076       "  (function fun", "(a,b) { infunction; }", ")();",
   1077       i::FUNCTION_SCOPE, i::SLOPPY },
   1078     // Illegal 5 byte encoding.
   1079     { "  'foo\370\277\277\277\277';\n"
   1080       "  (function fun", "(a,b) { infunction; }", ")();",
   1081       i::FUNCTION_SCOPE, i::SLOPPY },
   1082     // Illegal 6 byte encoding.
   1083     { "  'foo\374\277\277\277\277\277';\n"
   1084       "  (function fun", "(a,b) { infunction; }", ")();",
   1085       i::FUNCTION_SCOPE, i::SLOPPY },
   1086     // Illegal 0xfe byte
   1087     { "  'foo\376\277\277\277\277\277\277';\n"
   1088       "  (function fun", "(a,b) { infunction; }", ")();",
   1089       i::FUNCTION_SCOPE, i::SLOPPY },
   1090     // Illegal 0xff byte
   1091     { "  'foo\377\277\277\277\277\277\277\277';\n"
   1092       "  (function fun", "(a,b) { infunction; }", ")();",
   1093       i::FUNCTION_SCOPE, i::SLOPPY },
   1094     { "  'foo';\n"
   1095       "  (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
   1096       i::FUNCTION_SCOPE, i::SLOPPY },
   1097     { "  'foo';\n"
   1098       "  (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
   1099       i::FUNCTION_SCOPE, i::SLOPPY },
   1100     { NULL, NULL, NULL, i::EVAL_SCOPE, i::SLOPPY }
   1101   };
   1102 
   1103   i::Isolate* isolate = CcTest::i_isolate();
   1104   i::Factory* factory = isolate->factory();
   1105 
   1106   v8::HandleScope handles(CcTest::isolate());
   1107   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1108   v8::Context::Scope context_scope(context);
   1109 
   1110   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
   1111                                         128 * 1024);
   1112 
   1113   for (int i = 0; source_data[i].outer_prefix; i++) {
   1114     int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
   1115     int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
   1116     int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
   1117     int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
   1118     int kInnerByteLen = i::StrLength(source_data[i].inner_source);
   1119     int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
   1120     int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
   1121     int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
   1122     i::ScopedVector<char> program(kProgramByteSize + 1);
   1123     i::SNPrintF(program, "%s%s%s",
   1124                          source_data[i].outer_prefix,
   1125                          source_data[i].inner_source,
   1126                          source_data[i].outer_suffix);
   1127 
   1128     // Parse program source.
   1129     i::Handle<i::String> source = factory->NewStringFromUtf8(
   1130         i::CStrVector(program.start())).ToHandleChecked();
   1131     CHECK_EQ(source->length(), kProgramSize);
   1132     i::Handle<i::Script> script = factory->NewScript(source);
   1133     i::CompilationInfoWithZone info(script);
   1134     i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
   1135                                        isolate->heap()->HashSeed(),
   1136                                        isolate->unicode_cache()};
   1137     i::Parser parser(&info, &parse_info);
   1138     parser.set_allow_lazy(true);
   1139     parser.set_allow_harmony_scoping(true);
   1140     parser.set_allow_arrow_functions(true);
   1141     info.MarkAsGlobal();
   1142     info.SetStrictMode(source_data[i].strict_mode);
   1143     parser.Parse();
   1144     CHECK(info.function() != NULL);
   1145 
   1146     // Check scope types and positions.
   1147     i::Scope* scope = info.function()->scope();
   1148     CHECK(scope->is_global_scope());
   1149     CHECK_EQ(scope->start_position(), 0);
   1150     CHECK_EQ(scope->end_position(), kProgramSize);
   1151     CHECK_EQ(scope->inner_scopes()->length(), 1);
   1152 
   1153     i::Scope* inner_scope = scope->inner_scopes()->at(0);
   1154     CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type);
   1155     CHECK_EQ(inner_scope->start_position(), kPrefixLen);
   1156     // The end position of a token is one position after the last
   1157     // character belonging to that token.
   1158     CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
   1159   }
   1160 }
   1161 
   1162 
   1163 const char* ReadString(unsigned* start) {
   1164   int length = start[0];
   1165   char* result = i::NewArray<char>(length + 1);
   1166   for (int i = 0; i < length; i++) {
   1167     result[i] = start[i + 1];
   1168   }
   1169   result[length] = '\0';
   1170   return result;
   1171 }
   1172 
   1173 
   1174 i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
   1175   i::Isolate* isolate = CcTest::i_isolate();
   1176   i::Factory* factory = isolate->factory();
   1177   const char* message =
   1178       ReadString(&data[i::PreparseDataConstants::kMessageTextPos]);
   1179   i::Handle<i::String> format = v8::Utils::OpenHandle(
   1180       *v8::String::NewFromUtf8(CcTest::isolate(), message));
   1181   int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
   1182   const char* arg = NULL;
   1183   i::Handle<i::JSArray> args_array;
   1184   if (arg_count == 1) {
   1185     // Position after text found by skipping past length field and
   1186     // length field content words.
   1187     int pos = i::PreparseDataConstants::kMessageTextPos + 1 +
   1188               data[i::PreparseDataConstants::kMessageTextPos];
   1189     arg = ReadString(&data[pos]);
   1190     args_array = factory->NewJSArray(1);
   1191     i::JSArray::SetElement(args_array, 0, v8::Utils::OpenHandle(*v8_str(arg)),
   1192                            NONE, i::SLOPPY).Check();
   1193   } else {
   1194     CHECK_EQ(0, arg_count);
   1195     args_array = factory->NewJSArray(0);
   1196   }
   1197 
   1198   i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
   1199   i::Handle<i::Object> format_fun = i::Object::GetProperty(
   1200       isolate, builtins, "FormatMessage").ToHandleChecked();
   1201   i::Handle<i::Object> arg_handles[] = { format, args_array };
   1202   i::Handle<i::Object> result = i::Execution::Call(
   1203       isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
   1204   CHECK(result->IsString());
   1205   i::DeleteArray(message);
   1206   i::DeleteArray(arg);
   1207   data.Dispose();
   1208   return i::Handle<i::String>::cast(result);
   1209 }
   1210 
   1211 
   1212 enum ParserFlag {
   1213   kAllowLazy,
   1214   kAllowNativesSyntax,
   1215   kAllowHarmonyScoping,
   1216   kAllowModules,
   1217   kAllowHarmonyNumericLiterals,
   1218   kAllowArrowFunctions,
   1219   kAllowClasses,
   1220   kAllowHarmonyObjectLiterals
   1221 };
   1222 
   1223 
   1224 enum ParserSyncTestResult {
   1225   kSuccessOrError,
   1226   kSuccess,
   1227   kError
   1228 };
   1229 
   1230 template <typename Traits>
   1231 void SetParserFlags(i::ParserBase<Traits>* parser,
   1232                     i::EnumSet<ParserFlag> flags) {
   1233   parser->set_allow_lazy(flags.Contains(kAllowLazy));
   1234   parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax));
   1235   parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
   1236   parser->set_allow_modules(flags.Contains(kAllowModules));
   1237   parser->set_allow_harmony_numeric_literals(
   1238       flags.Contains(kAllowHarmonyNumericLiterals));
   1239   parser->set_allow_harmony_object_literals(
   1240       flags.Contains(kAllowHarmonyObjectLiterals));
   1241   parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
   1242   parser->set_allow_classes(flags.Contains(kAllowClasses));
   1243 }
   1244 
   1245 
   1246 void TestParserSyncWithFlags(i::Handle<i::String> source,
   1247                              i::EnumSet<ParserFlag> flags,
   1248                              ParserSyncTestResult result) {
   1249   i::Isolate* isolate = CcTest::i_isolate();
   1250   i::Factory* factory = isolate->factory();
   1251 
   1252   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
   1253 
   1254   // Preparse the data.
   1255   i::CompleteParserRecorder log;
   1256   {
   1257     i::Scanner scanner(isolate->unicode_cache());
   1258     i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
   1259     i::PreParser preparser(&scanner, &log, stack_limit);
   1260     SetParserFlags(&preparser, flags);
   1261     scanner.Initialize(&stream);
   1262     i::PreParser::PreParseResult result = preparser.PreParseProgram();
   1263     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
   1264   }
   1265 
   1266   bool preparse_error = log.HasError();
   1267 
   1268   // Parse the data
   1269   i::FunctionLiteral* function;
   1270   {
   1271     i::Handle<i::Script> script = factory->NewScript(source);
   1272     i::CompilationInfoWithZone info(script);
   1273     i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
   1274                                        isolate->heap()->HashSeed(),
   1275                                        isolate->unicode_cache()};
   1276     i::Parser parser(&info, &parse_info);
   1277     SetParserFlags(&parser, flags);
   1278     info.MarkAsGlobal();
   1279     parser.Parse();
   1280     function = info.function();
   1281   }
   1282 
   1283   // Check that preparsing fails iff parsing fails.
   1284   if (function == NULL) {
   1285     // Extract exception from the parser.
   1286     CHECK(isolate->has_pending_exception());
   1287     i::Handle<i::JSObject> exception_handle(
   1288         i::JSObject::cast(isolate->pending_exception()));
   1289     i::Handle<i::String> message_string =
   1290         i::Handle<i::String>::cast(i::Object::GetProperty(
   1291             isolate, exception_handle, "message").ToHandleChecked());
   1292 
   1293     if (result == kSuccess) {
   1294       v8::base::OS::Print(
   1295           "Parser failed on:\n"
   1296           "\t%s\n"
   1297           "with error:\n"
   1298           "\t%s\n"
   1299           "However, we expected no error.",
   1300           source->ToCString().get(), message_string->ToCString().get());
   1301       CHECK(false);
   1302     }
   1303 
   1304     if (!preparse_error) {
   1305       v8::base::OS::Print(
   1306           "Parser failed on:\n"
   1307           "\t%s\n"
   1308           "with error:\n"
   1309           "\t%s\n"
   1310           "However, the preparser succeeded",
   1311           source->ToCString().get(), message_string->ToCString().get());
   1312       CHECK(false);
   1313     }
   1314     // Check that preparser and parser produce the same error.
   1315     i::Handle<i::String> preparser_message =
   1316         FormatMessage(log.ErrorMessageData());
   1317     if (!i::String::Equals(message_string, preparser_message)) {
   1318       v8::base::OS::Print(
   1319           "Expected parser and preparser to produce the same error on:\n"
   1320           "\t%s\n"
   1321           "However, found the following error messages\n"
   1322           "\tparser:    %s\n"
   1323           "\tpreparser: %s\n",
   1324           source->ToCString().get(),
   1325           message_string->ToCString().get(),
   1326           preparser_message->ToCString().get());
   1327       CHECK(false);
   1328     }
   1329   } else if (preparse_error) {
   1330     v8::base::OS::Print(
   1331         "Preparser failed on:\n"
   1332         "\t%s\n"
   1333         "with error:\n"
   1334         "\t%s\n"
   1335         "However, the parser succeeded",
   1336         source->ToCString().get(),
   1337         FormatMessage(log.ErrorMessageData())->ToCString().get());
   1338     CHECK(false);
   1339   } else if (result == kError) {
   1340     v8::base::OS::Print(
   1341         "Expected error on:\n"
   1342         "\t%s\n"
   1343         "However, parser and preparser succeeded",
   1344         source->ToCString().get());
   1345     CHECK(false);
   1346   }
   1347 }
   1348 
   1349 
   1350 void TestParserSync(const char* source,
   1351                     const ParserFlag* varying_flags,
   1352                     size_t varying_flags_length,
   1353                     ParserSyncTestResult result = kSuccessOrError,
   1354                     const ParserFlag* always_true_flags = NULL,
   1355                     size_t always_true_flags_length = 0) {
   1356   i::Handle<i::String> str =
   1357       CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
   1358   for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
   1359     i::EnumSet<ParserFlag> flags;
   1360     for (size_t flag_index = 0; flag_index < varying_flags_length;
   1361          ++flag_index) {
   1362       if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
   1363     }
   1364     for (size_t flag_index = 0; flag_index < always_true_flags_length;
   1365          ++flag_index) {
   1366       flags.Add(always_true_flags[flag_index]);
   1367     }
   1368     TestParserSyncWithFlags(str, flags, result);
   1369   }
   1370 }
   1371 
   1372 
   1373 TEST(ParserSync) {
   1374   const char* context_data[][2] = {
   1375     { "", "" },
   1376     { "{", "}" },
   1377     { "if (true) ", " else {}" },
   1378     { "if (true) {} else ", "" },
   1379     { "if (true) ", "" },
   1380     { "do ", " while (false)" },
   1381     { "while (false) ", "" },
   1382     { "for (;;) ", "" },
   1383     { "with ({})", "" },
   1384     { "switch (12) { case 12: ", "}" },
   1385     { "switch (12) { default: ", "}" },
   1386     { "switch (12) { ", "case 12: }" },
   1387     { "label2: ", "" },
   1388     { NULL, NULL }
   1389   };
   1390 
   1391   const char* statement_data[] = {
   1392     "{}",
   1393     "var x",
   1394     "var x = 1",
   1395     "const x",
   1396     "const x = 1",
   1397     ";",
   1398     "12",
   1399     "if (false) {} else ;",
   1400     "if (false) {} else {}",
   1401     "if (false) {} else 12",
   1402     "if (false) ;"
   1403     "if (false) {}",
   1404     "if (false) 12",
   1405     "do {} while (false)",
   1406     "for (;;) ;",
   1407     "for (;;) {}",
   1408     "for (;;) 12",
   1409     "continue",
   1410     "continue label",
   1411     "continue\nlabel",
   1412     "break",
   1413     "break label",
   1414     "break\nlabel",
   1415     // TODO(marja): activate once parsing 'return' is merged into ParserBase.
   1416     // "return",
   1417     // "return  12",
   1418     // "return\n12",
   1419     "with ({}) ;",
   1420     "with ({}) {}",
   1421     "with ({}) 12",
   1422     "switch ({}) { default: }"
   1423     "label3: "
   1424     "throw",
   1425     "throw  12",
   1426     "throw\n12",
   1427     "try {} catch(e) {}",
   1428     "try {} finally {}",
   1429     "try {} catch(e) {} finally {}",
   1430     "debugger",
   1431     NULL
   1432   };
   1433 
   1434   const char* termination_data[] = {
   1435     "",
   1436     ";",
   1437     "\n",
   1438     ";\n",
   1439     "\n;",
   1440     NULL
   1441   };
   1442 
   1443   v8::HandleScope handles(CcTest::isolate());
   1444   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1445   v8::Context::Scope context_scope(context);
   1446 
   1447   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1448       i::GetCurrentStackPosition() - 128 * 1024);
   1449 
   1450   static const ParserFlag flags1[] = {
   1451     kAllowArrowFunctions,
   1452     kAllowClasses,
   1453     kAllowHarmonyNumericLiterals,
   1454     kAllowHarmonyObjectLiterals,
   1455     kAllowHarmonyScoping,
   1456     kAllowLazy,
   1457     kAllowModules,
   1458   };
   1459 
   1460   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1461     for (int j = 0; statement_data[j] != NULL; ++j) {
   1462       for (int k = 0; termination_data[k] != NULL; ++k) {
   1463         int kPrefixLen = i::StrLength(context_data[i][0]);
   1464         int kStatementLen = i::StrLength(statement_data[j]);
   1465         int kTerminationLen = i::StrLength(termination_data[k]);
   1466         int kSuffixLen = i::StrLength(context_data[i][1]);
   1467         int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
   1468             + kSuffixLen + i::StrLength("label: for (;;) {  }");
   1469 
   1470         // Plug the source code pieces together.
   1471         i::ScopedVector<char> program(kProgramSize + 1);
   1472         int length = i::SNPrintF(program,
   1473             "label: for (;;) { %s%s%s%s }",
   1474             context_data[i][0],
   1475             statement_data[j],
   1476             termination_data[k],
   1477             context_data[i][1]);
   1478         CHECK(length == kProgramSize);
   1479         TestParserSync(program.start(), flags1, arraysize(flags1));
   1480       }
   1481     }
   1482   }
   1483 
   1484   // Neither Harmony numeric literals nor our natives syntax have any
   1485   // interaction with the flags above, so test these separately to reduce
   1486   // the combinatorial explosion.
   1487   static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals };
   1488   TestParserSync("0o1234", flags2, arraysize(flags2));
   1489   TestParserSync("0b1011", flags2, arraysize(flags2));
   1490 
   1491   static const ParserFlag flags3[] = { kAllowNativesSyntax };
   1492   TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3));
   1493 }
   1494 
   1495 
   1496 TEST(StrictOctal) {
   1497   // Test that syntax error caused by octal literal is reported correctly as
   1498   // such (issue 2220).
   1499   v8::V8::Initialize();
   1500   v8::HandleScope scope(CcTest::isolate());
   1501   v8::Context::Scope context_scope(
   1502       v8::Context::New(CcTest::isolate()));
   1503   v8::TryCatch try_catch;
   1504   const char* script =
   1505       "\"use strict\";       \n"
   1506       "a = function() {      \n"
   1507       "  b = function() {    \n"
   1508       "    01;               \n"
   1509       "  };                  \n"
   1510       "};                    \n";
   1511   v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script));
   1512   CHECK(try_catch.HasCaught());
   1513   v8::String::Utf8Value exception(try_catch.Exception());
   1514   CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
   1515            *exception);
   1516 }
   1517 
   1518 
   1519 void RunParserSyncTest(const char* context_data[][2],
   1520                        const char* statement_data[],
   1521                        ParserSyncTestResult result,
   1522                        const ParserFlag* flags = NULL,
   1523                        int flags_len = 0,
   1524                        const ParserFlag* always_true_flags = NULL,
   1525                        int always_true_flags_len = 0) {
   1526   v8::HandleScope handles(CcTest::isolate());
   1527   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1528   v8::Context::Scope context_scope(context);
   1529 
   1530   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1531       i::GetCurrentStackPosition() - 128 * 1024);
   1532 
   1533   static const ParserFlag default_flags[] = {
   1534     kAllowArrowFunctions,
   1535     kAllowClasses,
   1536     kAllowHarmonyNumericLiterals,
   1537     kAllowHarmonyObjectLiterals,
   1538     kAllowHarmonyScoping,
   1539     kAllowLazy,
   1540     kAllowModules,
   1541     kAllowNativesSyntax,
   1542   };
   1543   ParserFlag* generated_flags = NULL;
   1544   if (flags == NULL) {
   1545     flags = default_flags;
   1546     flags_len = arraysize(default_flags);
   1547     if (always_true_flags != NULL) {
   1548       // Remove always_true_flags from default_flags.
   1549       CHECK(always_true_flags_len < flags_len);
   1550       generated_flags = new ParserFlag[flags_len - always_true_flags_len];
   1551       int flag_index = 0;
   1552       for (int i = 0; i < flags_len; ++i) {
   1553         bool use_flag = true;
   1554         for (int j = 0; j < always_true_flags_len; ++j) {
   1555           if (flags[i] == always_true_flags[j]) {
   1556             use_flag = false;
   1557             break;
   1558           }
   1559         }
   1560         if (use_flag) generated_flags[flag_index++] = flags[i];
   1561       }
   1562       CHECK(flag_index == flags_len - always_true_flags_len);
   1563       flags_len = flag_index;
   1564       flags = generated_flags;
   1565     }
   1566   }
   1567   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1568     for (int j = 0; statement_data[j] != NULL; ++j) {
   1569       int kPrefixLen = i::StrLength(context_data[i][0]);
   1570       int kStatementLen = i::StrLength(statement_data[j]);
   1571       int kSuffixLen = i::StrLength(context_data[i][1]);
   1572       int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
   1573 
   1574       // Plug the source code pieces together.
   1575       i::ScopedVector<char> program(kProgramSize + 1);
   1576       int length = i::SNPrintF(program,
   1577                                "%s%s%s",
   1578                                context_data[i][0],
   1579                                statement_data[j],
   1580                                context_data[i][1]);
   1581       CHECK(length == kProgramSize);
   1582       TestParserSync(program.start(),
   1583                      flags,
   1584                      flags_len,
   1585                      result,
   1586                      always_true_flags,
   1587                      always_true_flags_len);
   1588     }
   1589   }
   1590   delete[] generated_flags;
   1591 }
   1592 
   1593 
   1594 TEST(ErrorsEvalAndArguments) {
   1595   // Tests that both preparsing and parsing produce the right kind of errors for
   1596   // using "eval" and "arguments" as identifiers. Without the strict mode, it's
   1597   // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
   1598   // isn't.
   1599   const char* context_data[][2] = {
   1600     { "\"use strict\";", "" },
   1601     { "var eval; function test_func() {\"use strict\"; ", "}"},
   1602     { NULL, NULL }
   1603   };
   1604 
   1605   const char* statement_data[] = {
   1606     "var eval;",
   1607     "var arguments",
   1608     "var foo, eval;",
   1609     "var foo, arguments;",
   1610     "try { } catch (eval) { }",
   1611     "try { } catch (arguments) { }",
   1612     "function eval() { }",
   1613     "function arguments() { }",
   1614     "function foo(eval) { }",
   1615     "function foo(arguments) { }",
   1616     "function foo(bar, eval) { }",
   1617     "function foo(bar, arguments) { }",
   1618     "(eval) => { }",
   1619     "(arguments) => { }",
   1620     "(foo, eval) => { }",
   1621     "(foo, arguments) => { }",
   1622     "eval = 1;",
   1623     "arguments = 1;",
   1624     "var foo = eval = 1;",
   1625     "var foo = arguments = 1;",
   1626     "++eval;",
   1627     "++arguments;",
   1628     "eval++;",
   1629     "arguments++;",
   1630     NULL
   1631   };
   1632 
   1633   RunParserSyncTest(context_data, statement_data, kError);
   1634 }
   1635 
   1636 
   1637 TEST(NoErrorsEvalAndArgumentsSloppy) {
   1638   // Tests that both preparsing and parsing accept "eval" and "arguments" as
   1639   // identifiers when needed.
   1640   const char* context_data[][2] = {
   1641     { "", "" },
   1642     { "function test_func() {", "}"},
   1643     { NULL, NULL }
   1644   };
   1645 
   1646   const char* statement_data[] = {
   1647     "var eval;",
   1648     "var arguments",
   1649     "var foo, eval;",
   1650     "var foo, arguments;",
   1651     "try { } catch (eval) { }",
   1652     "try { } catch (arguments) { }",
   1653     "function eval() { }",
   1654     "function arguments() { }",
   1655     "function foo(eval) { }",
   1656     "function foo(arguments) { }",
   1657     "function foo(bar, eval) { }",
   1658     "function foo(bar, arguments) { }",
   1659     "eval = 1;",
   1660     "arguments = 1;",
   1661     "var foo = eval = 1;",
   1662     "var foo = arguments = 1;",
   1663     "++eval;",
   1664     "++arguments;",
   1665     "eval++;",
   1666     "arguments++;",
   1667     NULL
   1668   };
   1669 
   1670   RunParserSyncTest(context_data, statement_data, kSuccess);
   1671 }
   1672 
   1673 
   1674 TEST(NoErrorsEvalAndArgumentsStrict) {
   1675   const char* context_data[][2] = {
   1676     { "\"use strict\";", "" },
   1677     { "function test_func() { \"use strict\";", "}" },
   1678     { "() => { \"use strict\"; ", "}" },
   1679     { NULL, NULL }
   1680   };
   1681 
   1682   const char* statement_data[] = {
   1683     "eval;",
   1684     "arguments;",
   1685     "var foo = eval;",
   1686     "var foo = arguments;",
   1687     "var foo = { eval: 1 };",
   1688     "var foo = { arguments: 1 };",
   1689     "var foo = { }; foo.eval = {};",
   1690     "var foo = { }; foo.arguments = {};",
   1691     NULL
   1692   };
   1693 
   1694   static const ParserFlag always_flags[] = {kAllowArrowFunctions};
   1695   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   1696                     always_flags, arraysize(always_flags));
   1697 }
   1698 
   1699 
   1700 TEST(ErrorsFutureStrictReservedWords) {
   1701   // Tests that both preparsing and parsing produce the right kind of errors for
   1702   // using future strict reserved words as identifiers. Without the strict mode,
   1703   // it's ok to use future strict reserved words as identifiers. With the strict
   1704   // mode, it isn't.
   1705   const char* context_data[][2] = {
   1706     { "\"use strict\";", "" },
   1707     { "function test_func() {\"use strict\"; ", "}"},
   1708     { "() => { \"use strict\"; ", "}" },
   1709     { NULL, NULL }
   1710   };
   1711 
   1712   const char* statement_data[] = {
   1713     "var interface;",
   1714     "var foo, interface;",
   1715     "try { } catch (interface) { }",
   1716     "function interface() { }",
   1717     "function foo(interface) { }",
   1718     "function foo(bar, interface) { }",
   1719     "interface = 1;",
   1720     "var foo = interface = 1;",
   1721     "++interface;",
   1722     "interface++;",
   1723     "var yield = 13;",
   1724     NULL
   1725   };
   1726 
   1727   static const ParserFlag always_flags[] = {kAllowArrowFunctions};
   1728   RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags,
   1729                     arraysize(always_flags));
   1730 }
   1731 
   1732 
   1733 TEST(NoErrorsFutureStrictReservedWords) {
   1734   const char* context_data[][2] = {
   1735     { "", "" },
   1736     { "function test_func() {", "}"},
   1737     { "() => {", "}" },
   1738     { NULL, NULL }
   1739   };
   1740 
   1741   const char* statement_data[] = {
   1742     "var interface;",
   1743     "var foo, interface;",
   1744     "try { } catch (interface) { }",
   1745     "function interface() { }",
   1746     "function foo(interface) { }",
   1747     "function foo(bar, interface) { }",
   1748     "interface = 1;",
   1749     "var foo = interface = 1;",
   1750     "++interface;",
   1751     "interface++;",
   1752     "var yield = 13;",
   1753     NULL
   1754   };
   1755 
   1756   static const ParserFlag always_flags[] = {kAllowArrowFunctions};
   1757   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   1758                     always_flags, arraysize(always_flags));
   1759 }
   1760 
   1761 
   1762 TEST(ErrorsReservedWords) {
   1763   // Tests that both preparsing and parsing produce the right kind of errors for
   1764   // using future reserved words as identifiers. These tests don't depend on the
   1765   // strict mode.
   1766   const char* context_data[][2] = {
   1767     { "", "" },
   1768     { "\"use strict\";", "" },
   1769     { "var eval; function test_func() {", "}"},
   1770     { "var eval; function test_func() {\"use strict\"; ", "}"},
   1771     { "var eval; () => {", "}"},
   1772     { "var eval; () => {\"use strict\"; ", "}"},
   1773     { NULL, NULL }
   1774   };
   1775 
   1776   const char* statement_data[] = {
   1777     "var super;",
   1778     "var foo, super;",
   1779     "try { } catch (super) { }",
   1780     "function super() { }",
   1781     "function foo(super) { }",
   1782     "function foo(bar, super) { }",
   1783     "(super) => { }",
   1784     "(bar, super) => { }",
   1785     "super = 1;",
   1786     "var foo = super = 1;",
   1787     "++super;",
   1788     "super++;",
   1789     "function foo super",
   1790     NULL
   1791   };
   1792 
   1793   RunParserSyncTest(context_data, statement_data, kError);
   1794 }
   1795 
   1796 
   1797 TEST(NoErrorsLetSloppyAllModes) {
   1798   // In sloppy mode, it's okay to use "let" as identifier.
   1799   const char* context_data[][2] = {
   1800     { "", "" },
   1801     { "function f() {", "}" },
   1802     { "(function f() {", "})" },
   1803     { NULL, NULL }
   1804   };
   1805 
   1806   const char* statement_data[] = {
   1807     "var let;",
   1808     "var foo, let;",
   1809     "try { } catch (let) { }",
   1810     "function let() { }",
   1811     "(function let() { })",
   1812     "function foo(let) { }",
   1813     "function foo(bar, let) { }",
   1814     "let = 1;",
   1815     "var foo = let = 1;",
   1816     "let * 2;",
   1817     "++let;",
   1818     "let++;",
   1819     "let: 34",
   1820     "function let(let) { let: let(let + let(0)); }",
   1821     "({ let: 1 })",
   1822     "({ get let() { 1 } })",
   1823     "let(100)",
   1824     NULL
   1825   };
   1826 
   1827   RunParserSyncTest(context_data, statement_data, kSuccess);
   1828 }
   1829 
   1830 
   1831 TEST(NoErrorsYieldSloppyAllModes) {
   1832   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
   1833   // generator (see other test).
   1834   const char* context_data[][2] = {
   1835     { "", "" },
   1836     { "function not_gen() {", "}" },
   1837     { "(function not_gen() {", "})" },
   1838     { NULL, NULL }
   1839   };
   1840 
   1841   const char* statement_data[] = {
   1842     "var yield;",
   1843     "var foo, yield;",
   1844     "try { } catch (yield) { }",
   1845     "function yield() { }",
   1846     "(function yield() { })",
   1847     "function foo(yield) { }",
   1848     "function foo(bar, yield) { }",
   1849     "yield = 1;",
   1850     "var foo = yield = 1;",
   1851     "yield * 2;",
   1852     "++yield;",
   1853     "yield++;",
   1854     "yield: 34",
   1855     "function yield(yield) { yield: yield (yield + yield(0)); }",
   1856     "({ yield: 1 })",
   1857     "({ get yield() { 1 } })",
   1858     "yield(100)",
   1859     "yield[100]",
   1860     NULL
   1861   };
   1862 
   1863   RunParserSyncTest(context_data, statement_data, kSuccess);
   1864 }
   1865 
   1866 
   1867 TEST(NoErrorsYieldSloppyGeneratorsEnabled) {
   1868   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
   1869   // generator (see next test).
   1870   const char* context_data[][2] = {
   1871     { "", "" },
   1872     { "function not_gen() {", "}" },
   1873     { "function * gen() { function not_gen() {", "} }" },
   1874     { "(function not_gen() {", "})" },
   1875     { "(function * gen() { (function not_gen() {", "}) })" },
   1876     { NULL, NULL }
   1877   };
   1878 
   1879   const char* statement_data[] = {
   1880     "var yield;",
   1881     "var foo, yield;",
   1882     "try { } catch (yield) { }",
   1883     "function yield() { }",
   1884     "(function yield() { })",
   1885     "function foo(yield) { }",
   1886     "function foo(bar, yield) { }",
   1887     "function * yield() { }",
   1888     "(function * yield() { })",
   1889     "yield = 1;",
   1890     "var foo = yield = 1;",
   1891     "yield * 2;",
   1892     "++yield;",
   1893     "yield++;",
   1894     "yield: 34",
   1895     "function yield(yield) { yield: yield (yield + yield(0)); }",
   1896     "({ yield: 1 })",
   1897     "({ get yield() { 1 } })",
   1898     "yield(100)",
   1899     "yield[100]",
   1900     NULL
   1901   };
   1902 
   1903   RunParserSyncTest(context_data, statement_data, kSuccess);
   1904 }
   1905 
   1906 
   1907 TEST(ErrorsYieldStrict) {
   1908   const char* context_data[][2] = {
   1909     { "\"use strict\";", "" },
   1910     { "\"use strict\"; function not_gen() {", "}" },
   1911     { "function test_func() {\"use strict\"; ", "}"},
   1912     { "\"use strict\"; function * gen() { function not_gen() {", "} }" },
   1913     { "\"use strict\"; (function not_gen() {", "})" },
   1914     { "\"use strict\"; (function * gen() { (function not_gen() {", "}) })" },
   1915     { "() => {\"use strict\"; ", "}" },
   1916     { NULL, NULL }
   1917   };
   1918 
   1919   const char* statement_data[] = {
   1920     "var yield;",
   1921     "var foo, yield;",
   1922     "try { } catch (yield) { }",
   1923     "function yield() { }",
   1924     "(function yield() { })",
   1925     "function foo(yield) { }",
   1926     "function foo(bar, yield) { }",
   1927     "function * yield() { }",
   1928     "(function * yield() { })",
   1929     "yield = 1;",
   1930     "var foo = yield = 1;",
   1931     "++yield;",
   1932     "yield++;",
   1933     "yield: 34;",
   1934     NULL
   1935   };
   1936 
   1937   RunParserSyncTest(context_data, statement_data, kError);
   1938 }
   1939 
   1940 
   1941 TEST(NoErrorsGenerator) {
   1942   const char* context_data[][2] = {
   1943     { "function * gen() {", "}" },
   1944     { "(function * gen() {", "})" },
   1945     { "(function * () {", "})" },
   1946     { NULL, NULL }
   1947   };
   1948 
   1949   const char* statement_data[] = {
   1950     // A generator without a body is valid.
   1951     ""
   1952     // Valid yield expressions inside generators.
   1953     "yield 2;",
   1954     "yield * 2;",
   1955     "yield * \n 2;",
   1956     "yield yield 1;",
   1957     "yield * yield * 1;",
   1958     "yield 3 + (yield 4);",
   1959     "yield * 3 + (yield * 4);",
   1960     "(yield * 3) + (yield * 4);",
   1961     "yield 3; yield 4;",
   1962     "yield * 3; yield * 4;",
   1963     "(function (yield) { })",
   1964     "yield { yield: 12 }",
   1965     "yield /* comment */ { yield: 12 }",
   1966     "yield * \n { yield: 12 }",
   1967     "yield /* comment */ * \n { yield: 12 }",
   1968     // You can return in a generator.
   1969     "yield 1; return",
   1970     "yield * 1; return",
   1971     "yield 1; return 37",
   1972     "yield * 1; return 37",
   1973     "yield 1; return 37; yield 'dead';",
   1974     "yield * 1; return 37; yield * 'dead';",
   1975     // Yield is still a valid key in object literals.
   1976     "({ yield: 1 })",
   1977     "({ get yield() { } })",
   1978     // Yield without RHS.
   1979     "yield;",
   1980     "yield",
   1981     "yield\n",
   1982     "yield /* comment */"
   1983     "yield // comment\n"
   1984     "(yield)",
   1985     "[yield]",
   1986     "{yield}",
   1987     "yield, yield",
   1988     "yield; yield",
   1989     "(yield) ? yield : yield",
   1990     "(yield) \n ? yield : yield",
   1991     // If there is a newline before the next token, we don't look for RHS.
   1992     "yield\nfor (;;) {}",
   1993     NULL
   1994   };
   1995 
   1996   RunParserSyncTest(context_data, statement_data, kSuccess);
   1997 }
   1998 
   1999 
   2000 TEST(ErrorsYieldGenerator) {
   2001   const char* context_data[][2] = {
   2002     { "function * gen() {", "}" },
   2003     { "\"use strict\"; function * gen() {", "}" },
   2004     { NULL, NULL }
   2005   };
   2006 
   2007   const char* statement_data[] = {
   2008     // Invalid yield expressions inside generators.
   2009     "var yield;",
   2010     "var foo, yield;",
   2011     "try { } catch (yield) { }",
   2012     "function yield() { }",
   2013     // The name of the NFE is let-bound in the generator, which does not permit
   2014     // yield to be an identifier.
   2015     "(function yield() { })",
   2016     "(function * yield() { })",
   2017     // Yield isn't valid as a formal parameter for generators.
   2018     "function * foo(yield) { }",
   2019     "(function * foo(yield) { })",
   2020     "yield = 1;",
   2021     "var foo = yield = 1;",
   2022     "++yield;",
   2023     "yield++;",
   2024     "yield *",
   2025     "(yield *)",
   2026     // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
   2027     // is invalid.
   2028     "yield 3 + yield 4;",
   2029     "yield: 34",
   2030     "yield ? 1 : 2",
   2031     // Parses as yield (/ yield): invalid.
   2032     "yield / yield",
   2033     "+ yield",
   2034     "+ yield 3",
   2035     // Invalid (no newline allowed between yield and *).
   2036     "yield\n*3",
   2037     // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
   2038     // object literal, and yield is not a valid label).
   2039     "yield\n{yield: 42}",
   2040     "yield /* comment */\n {yield: 42}",
   2041     "yield //comment\n {yield: 42}",
   2042     NULL
   2043   };
   2044 
   2045   RunParserSyncTest(context_data, statement_data, kError);
   2046 }
   2047 
   2048 
   2049 TEST(ErrorsNameOfStrictFunction) {
   2050   // Tests that illegal tokens as names of a strict function produce the correct
   2051   // errors.
   2052   const char* context_data[][2] = {
   2053     { "function ", ""},
   2054     { "\"use strict\"; function", ""},
   2055     { "function * ", ""},
   2056     { "\"use strict\"; function * ", ""},
   2057     { NULL, NULL }
   2058   };
   2059 
   2060   const char* statement_data[] = {
   2061     "eval() {\"use strict\";}",
   2062     "arguments() {\"use strict\";}",
   2063     "interface() {\"use strict\";}",
   2064     "yield() {\"use strict\";}",
   2065     // Future reserved words are always illegal
   2066     "function super() { }",
   2067     "function super() {\"use strict\";}",
   2068     NULL
   2069   };
   2070 
   2071   RunParserSyncTest(context_data, statement_data, kError);
   2072 }
   2073 
   2074 
   2075 TEST(NoErrorsNameOfStrictFunction) {
   2076   const char* context_data[][2] = {
   2077     { "function ", ""},
   2078     { NULL, NULL }
   2079   };
   2080 
   2081   const char* statement_data[] = {
   2082     "eval() { }",
   2083     "arguments() { }",
   2084     "interface() { }",
   2085     "yield() { }",
   2086     NULL
   2087   };
   2088 
   2089   RunParserSyncTest(context_data, statement_data, kSuccess);
   2090 }
   2091 
   2092 
   2093 TEST(NoErrorsNameOfStrictGenerator) {
   2094   const char* context_data[][2] = {
   2095     { "function * ", ""},
   2096     { NULL, NULL }
   2097   };
   2098 
   2099   const char* statement_data[] = {
   2100     "eval() { }",
   2101     "arguments() { }",
   2102     "interface() { }",
   2103     "yield() { }",
   2104     NULL
   2105   };
   2106 
   2107   RunParserSyncTest(context_data, statement_data, kSuccess);
   2108 }
   2109 
   2110 
   2111 TEST(ErrorsIllegalWordsAsLabelsSloppy) {
   2112   // Using future reserved words as labels is always an error.
   2113   const char* context_data[][2] = {
   2114     { "", ""},
   2115     { "function test_func() {", "}" },
   2116     { "() => {", "}" },
   2117     { NULL, NULL }
   2118   };
   2119 
   2120   const char* statement_data[] = {
   2121     "super: while(true) { break super; }",
   2122     NULL
   2123   };
   2124 
   2125   RunParserSyncTest(context_data, statement_data, kError);
   2126 }
   2127 
   2128 
   2129 TEST(ErrorsIllegalWordsAsLabelsStrict) {
   2130   // Tests that illegal tokens as labels produce the correct errors.
   2131   const char* context_data[][2] = {
   2132     { "\"use strict\";", "" },
   2133     { "function test_func() {\"use strict\"; ", "}"},
   2134     { "() => {\"use strict\"; ", "}" },
   2135     { NULL, NULL }
   2136   };
   2137 
   2138   const char* statement_data[] = {
   2139     "super: while(true) { break super; }",
   2140     "interface: while(true) { break interface; }",
   2141     "yield: while(true) { break yield; }",
   2142     NULL
   2143   };
   2144 
   2145   RunParserSyncTest(context_data, statement_data, kError);
   2146 }
   2147 
   2148 
   2149 TEST(NoErrorsIllegalWordsAsLabels) {
   2150   // Using eval and arguments as labels is legal even in strict mode.
   2151   const char* context_data[][2] = {
   2152     { "", ""},
   2153     { "function test_func() {", "}" },
   2154     { "() => {", "}" },
   2155     { "\"use strict\";", "" },
   2156     { "\"use strict\"; function test_func() {", "}" },
   2157     { "\"use strict\"; () => {", "}" },
   2158     { NULL, NULL }
   2159   };
   2160 
   2161   const char* statement_data[] = {
   2162     "mylabel: while(true) { break mylabel; }",
   2163     "eval: while(true) { break eval; }",
   2164     "arguments: while(true) { break arguments; }",
   2165     NULL
   2166   };
   2167 
   2168   static const ParserFlag always_flags[] = {kAllowArrowFunctions};
   2169   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   2170                     always_flags, arraysize(always_flags));
   2171 }
   2172 
   2173 
   2174 TEST(ErrorsParenthesizedLabels) {
   2175   // Parenthesized identifiers shouldn't be recognized as labels.
   2176   const char* context_data[][2] = {
   2177     { "", ""},
   2178     { "function test_func() {", "}" },
   2179     { "() => {", "}" },
   2180     { NULL, NULL }
   2181   };
   2182 
   2183   const char* statement_data[] = {
   2184     "(mylabel): while(true) { break mylabel; }",
   2185     NULL
   2186   };
   2187 
   2188   RunParserSyncTest(context_data, statement_data, kError);
   2189 }
   2190 
   2191 
   2192 TEST(NoErrorsParenthesizedDirectivePrologue) {
   2193   // Parenthesized directive prologue shouldn't be recognized.
   2194   const char* context_data[][2] = {
   2195     { "", ""},
   2196     { NULL, NULL }
   2197   };
   2198 
   2199   const char* statement_data[] = {
   2200     "(\"use strict\"); var eval;",
   2201     NULL
   2202   };
   2203 
   2204   RunParserSyncTest(context_data, statement_data, kSuccess);
   2205 }
   2206 
   2207 
   2208 TEST(ErrorsNotAnIdentifierName) {
   2209   const char* context_data[][2] = {
   2210     { "", ""},
   2211     { "\"use strict\";", ""},
   2212     { NULL, NULL }
   2213   };
   2214 
   2215   const char* statement_data[] = {
   2216     "var foo = {}; foo.{;",
   2217     "var foo = {}; foo.};",
   2218     "var foo = {}; foo.=;",
   2219     "var foo = {}; foo.888;",
   2220     "var foo = {}; foo.-;",
   2221     "var foo = {}; foo.--;",
   2222     NULL
   2223   };
   2224 
   2225   RunParserSyncTest(context_data, statement_data, kError);
   2226 }
   2227 
   2228 
   2229 TEST(NoErrorsIdentifierNames) {
   2230   // Keywords etc. are valid as property names.
   2231   const char* context_data[][2] = {
   2232     { "", ""},
   2233     { "\"use strict\";", ""},
   2234     { NULL, NULL }
   2235   };
   2236 
   2237   const char* statement_data[] = {
   2238     "var foo = {}; foo.if;",
   2239     "var foo = {}; foo.yield;",
   2240     "var foo = {}; foo.super;",
   2241     "var foo = {}; foo.interface;",
   2242     "var foo = {}; foo.eval;",
   2243     "var foo = {}; foo.arguments;",
   2244     NULL
   2245   };
   2246 
   2247   RunParserSyncTest(context_data, statement_data, kSuccess);
   2248 }
   2249 
   2250 
   2251 TEST(DontRegressPreParserDataSizes) {
   2252   // These tests make sure that Parser doesn't start producing less "preparse
   2253   // data" (data which the embedder can cache).
   2254   v8::V8::Initialize();
   2255   v8::Isolate* isolate = CcTest::isolate();
   2256   v8::HandleScope handles(isolate);
   2257 
   2258   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   2259       i::GetCurrentStackPosition() - 128 * 1024);
   2260 
   2261   struct TestCase {
   2262     const char* program;
   2263     int functions;
   2264   } test_cases[] = {
   2265     // No functions.
   2266     {"var x = 42;", 0},
   2267     // Functions.
   2268     {"function foo() {}", 1}, {"function foo() {} function bar() {}", 2},
   2269     // Getter / setter functions are recorded as functions if they're on the top
   2270     // level.
   2271     {"var x = {get foo(){} };", 1},
   2272     // Functions insize lazy functions are not recorded.
   2273     {"function lazy() { function a() {} function b() {} function c() {} }", 1},
   2274     {"function lazy() { var x = {get foo(){} } }", 1},
   2275     {NULL, 0}
   2276   };
   2277 
   2278   for (int i = 0; test_cases[i].program; i++) {
   2279     const char* program = test_cases[i].program;
   2280     i::Factory* factory = CcTest::i_isolate()->factory();
   2281     i::Handle<i::String> source =
   2282         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   2283     i::Handle<i::Script> script = factory->NewScript(source);
   2284     i::CompilationInfoWithZone info(script);
   2285     i::ScriptData* sd = NULL;
   2286     info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache);
   2287     i::Parser::Parse(&info, true);
   2288     i::ParseData pd(sd);
   2289 
   2290     if (pd.FunctionCount() != test_cases[i].functions) {
   2291       v8::base::OS::Print(
   2292           "Expected preparse data for program:\n"
   2293           "\t%s\n"
   2294           "to contain %d functions, however, received %d functions.\n",
   2295           program, test_cases[i].functions, pd.FunctionCount());
   2296       CHECK(false);
   2297     }
   2298     delete sd;
   2299   }
   2300 }
   2301 
   2302 
   2303 TEST(FunctionDeclaresItselfStrict) {
   2304   // Tests that we produce the right kinds of errors when a function declares
   2305   // itself strict (we cannot produce there errors as soon as we see the
   2306   // offending identifiers, because we don't know at that point whether the
   2307   // function is strict or not).
   2308   const char* context_data[][2] = {
   2309     {"function eval() {", "}"},
   2310     {"function arguments() {", "}"},
   2311     {"function yield() {", "}"},
   2312     {"function interface() {", "}"},
   2313     {"function foo(eval) {", "}"},
   2314     {"function foo(arguments) {", "}"},
   2315     {"function foo(yield) {", "}"},
   2316     {"function foo(interface) {", "}"},
   2317     {"function foo(bar, eval) {", "}"},
   2318     {"function foo(bar, arguments) {", "}"},
   2319     {"function foo(bar, yield) {", "}"},
   2320     {"function foo(bar, interface) {", "}"},
   2321     {"function foo(bar, bar) {", "}"},
   2322     { NULL, NULL }
   2323   };
   2324 
   2325   const char* strict_statement_data[] = {
   2326     "\"use strict\";",
   2327     NULL
   2328   };
   2329 
   2330   const char* non_strict_statement_data[] = {
   2331     ";",
   2332     NULL
   2333   };
   2334 
   2335   RunParserSyncTest(context_data, strict_statement_data, kError);
   2336   RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
   2337 }
   2338 
   2339 
   2340 TEST(ErrorsTryWithoutCatchOrFinally) {
   2341   const char* context_data[][2] = {
   2342     {"", ""},
   2343     { NULL, NULL }
   2344   };
   2345 
   2346   const char* statement_data[] = {
   2347     "try { }",
   2348     "try { } foo();",
   2349     "try { } catch (e) foo();",
   2350     "try { } catch { }",
   2351     "try { } finally foo();",
   2352     NULL
   2353   };
   2354 
   2355   RunParserSyncTest(context_data, statement_data, kError);
   2356 }
   2357 
   2358 
   2359 TEST(NoErrorsTryCatchFinally) {
   2360   const char* context_data[][2] = {
   2361     {"", ""},
   2362     { NULL, NULL }
   2363   };
   2364 
   2365   const char* statement_data[] = {
   2366     "try { } catch (e) { }",
   2367     "try { } catch (e) { } finally { }",
   2368     "try { } finally { }",
   2369     NULL
   2370   };
   2371 
   2372   RunParserSyncTest(context_data, statement_data, kSuccess);
   2373 }
   2374 
   2375 
   2376 TEST(ErrorsRegexpLiteral) {
   2377   const char* context_data[][2] = {
   2378     {"var r = ", ""},
   2379     { NULL, NULL }
   2380   };
   2381 
   2382   const char* statement_data[] = {
   2383     "/unterminated",
   2384     NULL
   2385   };
   2386 
   2387   RunParserSyncTest(context_data, statement_data, kError);
   2388 }
   2389 
   2390 
   2391 TEST(NoErrorsRegexpLiteral) {
   2392   const char* context_data[][2] = {
   2393     {"var r = ", ""},
   2394     { NULL, NULL }
   2395   };
   2396 
   2397   const char* statement_data[] = {
   2398     "/foo/",
   2399     "/foo/g",
   2400     "/foo/whatever",  // This is an error but not detected by the parser.
   2401     NULL
   2402   };
   2403 
   2404   RunParserSyncTest(context_data, statement_data, kSuccess);
   2405 }
   2406 
   2407 
   2408 TEST(Intrinsics) {
   2409   const char* context_data[][2] = {
   2410     {"", ""},
   2411     { NULL, NULL }
   2412   };
   2413 
   2414   const char* statement_data[] = {
   2415     "%someintrinsic(arg)",
   2416     NULL
   2417   };
   2418 
   2419   // This test requires kAllowNativesSyntax to succeed.
   2420   static const ParserFlag always_true_flags[] = {
   2421     kAllowNativesSyntax
   2422   };
   2423 
   2424   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   2425                     always_true_flags, 1);
   2426 }
   2427 
   2428 
   2429 TEST(NoErrorsNewExpression) {
   2430   const char* context_data[][2] = {
   2431     {"", ""},
   2432     {"var f =", ""},
   2433     { NULL, NULL }
   2434   };
   2435 
   2436   const char* statement_data[] = {
   2437     "new foo",
   2438     "new foo();",
   2439     "new foo(1);",
   2440     "new foo(1, 2);",
   2441     // The first () will be processed as a part of the NewExpression and the
   2442     // second () will be processed as part of LeftHandSideExpression.
   2443     "new foo()();",
   2444     // The first () will be processed as a part of the inner NewExpression and
   2445     // the second () will be processed as a part of the outer NewExpression.
   2446     "new new foo()();",
   2447     "new foo.bar;",
   2448     "new foo.bar();",
   2449     "new foo.bar.baz;",
   2450     "new foo.bar().baz;",
   2451     "new foo[bar];",
   2452     "new foo[bar]();",
   2453     "new foo[bar][baz];",
   2454     "new foo[bar]()[baz];",
   2455     "new foo[bar].baz(baz)()[bar].baz;",
   2456     "new \"foo\"",  // Runtime error
   2457     "new 1",  // Runtime error
   2458     // This even runs:
   2459     "(new new Function(\"this.x = 1\")).x;",
   2460     "new new Test_Two(String, 2).v(0123).length;",
   2461     NULL
   2462   };
   2463 
   2464   RunParserSyncTest(context_data, statement_data, kSuccess);
   2465 }
   2466 
   2467 
   2468 TEST(ErrorsNewExpression) {
   2469   const char* context_data[][2] = {
   2470     {"", ""},
   2471     {"var f =", ""},
   2472     { NULL, NULL }
   2473   };
   2474 
   2475   const char* statement_data[] = {
   2476     "new foo bar",
   2477     "new ) foo",
   2478     "new ++foo",
   2479     "new foo ++",
   2480     NULL
   2481   };
   2482 
   2483   RunParserSyncTest(context_data, statement_data, kError);
   2484 }
   2485 
   2486 
   2487 TEST(StrictObjectLiteralChecking) {
   2488   const char* strict_context_data[][2] = {
   2489     {"\"use strict\"; var myobject = {", "};"},
   2490     {"\"use strict\"; var myobject = {", ",};"},
   2491     { NULL, NULL }
   2492   };
   2493   const char* non_strict_context_data[][2] = {
   2494     {"var myobject = {", "};"},
   2495     {"var myobject = {", ",};"},
   2496     { NULL, NULL }
   2497   };
   2498 
   2499   // These are only errors in strict mode.
   2500   const char* statement_data[] = {
   2501     "foo: 1, foo: 2",
   2502     "\"foo\": 1, \"foo\": 2",
   2503     "foo: 1, \"foo\": 2",
   2504     "1: 1, 1: 2",
   2505     "1: 1, \"1\": 2",
   2506     "get: 1, get: 2",  // Not a getter for real, just a property called get.
   2507     "set: 1, set: 2",  // Not a setter for real, just a property called set.
   2508     NULL
   2509   };
   2510 
   2511   RunParserSyncTest(non_strict_context_data, statement_data, kSuccess);
   2512   RunParserSyncTest(strict_context_data, statement_data, kError);
   2513 }
   2514 
   2515 
   2516 TEST(ErrorsObjectLiteralChecking) {
   2517   const char* context_data[][2] = {
   2518     {"\"use strict\"; var myobject = {", "};"},
   2519     {"var myobject = {", "};"},
   2520     { NULL, NULL }
   2521   };
   2522 
   2523   const char* statement_data[] = {
   2524       ",",
   2525       "foo: 1, get foo() {}",
   2526       "foo: 1, set foo(v) {}",
   2527       "\"foo\": 1, get \"foo\"() {}",
   2528       "\"foo\": 1, set \"foo\"(v) {}",
   2529       "1: 1, get 1() {}",
   2530       "1: 1, set 1() {}",
   2531       "get foo() {}, get foo() {}",
   2532       "set foo(_) {}, set foo(_) {}",
   2533       // It's counter-intuitive, but these collide too (even in classic
   2534       // mode). Note that we can have "foo" and foo as properties in classic
   2535       // mode,
   2536       // but we cannot have "foo" and get foo, or foo and get "foo".
   2537       "foo: 1, get \"foo\"() {}",
   2538       "foo: 1, set \"foo\"(v) {}",
   2539       "\"foo\": 1, get foo() {}",
   2540       "\"foo\": 1, set foo(v) {}",
   2541       "1: 1, get \"1\"() {}",
   2542       "1: 1, set \"1\"() {}",
   2543       "\"1\": 1, get 1() {}"
   2544       "\"1\": 1, set 1(v) {}"
   2545       // Wrong number of parameters
   2546       "get bar(x) {}",
   2547       "get bar(x, y) {}",
   2548       "set bar() {}",
   2549       "set bar(x, y) {}",
   2550       // Parsing FunctionLiteral for getter or setter fails
   2551       "get foo( +",
   2552       "get foo() \"error\"",
   2553       NULL};
   2554 
   2555   RunParserSyncTest(context_data, statement_data, kError);
   2556 }
   2557 
   2558 
   2559 TEST(NoErrorsObjectLiteralChecking) {
   2560   const char* context_data[][2] = {
   2561     {"var myobject = {", "};"},
   2562     {"var myobject = {", ",};"},
   2563     {"\"use strict\"; var myobject = {", "};"},
   2564     {"\"use strict\"; var myobject = {", ",};"},
   2565     { NULL, NULL }
   2566   };
   2567 
   2568   const char* statement_data[] = {
   2569     "foo: 1, bar: 2",
   2570     "\"foo\": 1, \"bar\": 2",
   2571     "1: 1, 2: 2",
   2572     // Syntax: IdentifierName ':' AssignmentExpression
   2573     "foo: bar = 5 + baz",
   2574     // Syntax: 'get' PropertyName '(' ')' '{' FunctionBody '}'
   2575     "get foo() {}",
   2576     "get \"foo\"() {}",
   2577     "get 1() {}",
   2578     // Syntax: 'set' PropertyName '(' PropertySetParameterList ')'
   2579     //     '{' FunctionBody '}'
   2580     "set foo(v) {}",
   2581     "set \"foo\"(v) {}",
   2582     "set 1(v) {}",
   2583     // Non-colliding getters and setters -> no errors
   2584     "foo: 1, get bar() {}",
   2585     "foo: 1, set bar(v) {}",
   2586     "\"foo\": 1, get \"bar\"() {}",
   2587     "\"foo\": 1, set \"bar\"(v) {}",
   2588     "1: 1, get 2() {}",
   2589     "1: 1, set 2(v) {}",
   2590     "get: 1, get foo() {}",
   2591     "set: 1, set foo(_) {}",
   2592     // Keywords, future reserved and strict future reserved are also allowed as
   2593     // property names.
   2594     "if: 4",
   2595     "interface: 5",
   2596     "super: 6",
   2597     "eval: 7",
   2598     "arguments: 8",
   2599     NULL
   2600   };
   2601 
   2602   RunParserSyncTest(context_data, statement_data, kSuccess);
   2603 }
   2604 
   2605 
   2606 TEST(TooManyArguments) {
   2607   const char* context_data[][2] = {
   2608     {"foo(", "0)"},
   2609     { NULL, NULL }
   2610   };
   2611 
   2612   using v8::internal::Code;
   2613   char statement[Code::kMaxArguments * 2 + 1];
   2614   for (int i = 0; i < Code::kMaxArguments; ++i) {
   2615     statement[2 * i] = '0';
   2616     statement[2 * i + 1] = ',';
   2617   }
   2618   statement[Code::kMaxArguments * 2] = 0;
   2619 
   2620   const char* statement_data[] = {
   2621     statement,
   2622     NULL
   2623   };
   2624 
   2625   // The test is quite slow, so run it with a reduced set of flags.
   2626   static const ParserFlag empty_flags[] = {kAllowLazy};
   2627   RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
   2628 }
   2629 
   2630 
   2631 TEST(StrictDelete) {
   2632   // "delete <Identifier>" is not allowed in strict mode.
   2633   const char* strict_context_data[][2] = {
   2634     {"\"use strict\"; ", ""},
   2635     { NULL, NULL }
   2636   };
   2637 
   2638   const char* sloppy_context_data[][2] = {
   2639     {"", ""},
   2640     { NULL, NULL }
   2641   };
   2642 
   2643   // These are errors in the strict mode.
   2644   const char* sloppy_statement_data[] = {
   2645     "delete foo;",
   2646     "delete foo + 1;",
   2647     "delete (foo);",
   2648     "delete eval;",
   2649     "delete interface;",
   2650     NULL
   2651   };
   2652 
   2653   // These are always OK
   2654   const char* good_statement_data[] = {
   2655     "delete this;",
   2656     "delete 1;",
   2657     "delete 1 + 2;",
   2658     "delete foo();",
   2659     "delete foo.bar;",
   2660     "delete foo[bar];",
   2661     "delete foo--;",
   2662     "delete --foo;",
   2663     "delete new foo();",
   2664     "delete new foo(bar);",
   2665     NULL
   2666   };
   2667 
   2668   // These are always errors
   2669   const char* bad_statement_data[] = {
   2670     "delete if;",
   2671     NULL
   2672   };
   2673 
   2674   RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
   2675   RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
   2676 
   2677   RunParserSyncTest(strict_context_data, good_statement_data, kSuccess);
   2678   RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess);
   2679 
   2680   RunParserSyncTest(strict_context_data, bad_statement_data, kError);
   2681   RunParserSyncTest(sloppy_context_data, bad_statement_data, kError);
   2682 }
   2683 
   2684 
   2685 TEST(InvalidLeftHandSide) {
   2686   const char* assignment_context_data[][2] = {
   2687     {"", " = 1;"},
   2688     {"\"use strict\"; ", " = 1;"},
   2689     { NULL, NULL }
   2690   };
   2691 
   2692   const char* prefix_context_data[][2] = {
   2693     {"++", ";"},
   2694     {"\"use strict\"; ++", ";"},
   2695     {NULL, NULL},
   2696   };
   2697 
   2698   const char* postfix_context_data[][2] = {
   2699     {"", "++;"},
   2700     {"\"use strict\"; ", "++;"},
   2701     { NULL, NULL }
   2702   };
   2703 
   2704   // Good left hand sides for assigment or prefix / postfix operations.
   2705   const char* good_statement_data[] = {
   2706     "foo",
   2707     "foo.bar",
   2708     "foo[bar]",
   2709     "foo()[bar]",
   2710     "foo().bar",
   2711     "this.foo",
   2712     "this[foo]",
   2713     "new foo()[bar]",
   2714     "new foo().bar",
   2715     "foo()",
   2716     "foo(bar)",
   2717     "foo[bar]()",
   2718     "foo.bar()",
   2719     "this()",
   2720     "this.foo()",
   2721     "this[foo].bar()",
   2722     "this.foo[foo].bar(this)(bar)[foo]()",
   2723     NULL
   2724   };
   2725 
   2726   // Bad left hand sides for assigment or prefix / postfix operations.
   2727   const char* bad_statement_data_common[] = {
   2728     "2",
   2729     "new foo",
   2730     "new foo()",
   2731     "null",
   2732     "if",  // Unexpected token
   2733     "{x: 1}",  // Unexpected token
   2734     "this",
   2735     "\"bar\"",
   2736     "(foo + bar)",
   2737     "new new foo()[bar]",  // means: new (new foo()[bar])
   2738     "new new foo().bar",  // means: new (new foo()[bar])
   2739     NULL
   2740   };
   2741 
   2742   // These are not okay for assignment, but okay for prefix / postix.
   2743   const char* bad_statement_data_for_assignment[] = {
   2744     "++foo",
   2745     "foo++",
   2746     "foo + bar",
   2747     NULL
   2748   };
   2749 
   2750   RunParserSyncTest(assignment_context_data, good_statement_data, kSuccess);
   2751   RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
   2752   RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
   2753                     kError);
   2754 
   2755   RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
   2756   RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
   2757 
   2758   RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
   2759   RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
   2760 }
   2761 
   2762 
   2763 TEST(FuncNameInferrerBasic) {
   2764   // Tests that function names are inferred properly.
   2765   i::FLAG_allow_natives_syntax = true;
   2766   v8::Isolate* isolate = CcTest::isolate();
   2767   v8::HandleScope scope(isolate);
   2768   LocalContext env;
   2769   CompileRun("var foo1 = function() {}; "
   2770              "var foo2 = function foo3() {}; "
   2771              "function not_ctor() { "
   2772              "  var foo4 = function() {}; "
   2773              "  return %FunctionGetInferredName(foo4); "
   2774              "} "
   2775              "function Ctor() { "
   2776              "  var foo5 = function() {}; "
   2777              "  return %FunctionGetInferredName(foo5); "
   2778              "} "
   2779              "var obj1 = { foo6: function() {} }; "
   2780              "var obj2 = { 'foo7': function() {} }; "
   2781              "var obj3 = {}; "
   2782              "obj3[1] = function() {}; "
   2783              "var obj4 = {}; "
   2784              "obj4[1] = function foo8() {}; "
   2785              "var obj5 = {}; "
   2786              "obj5['foo9'] = function() {}; "
   2787              "var obj6 = { obj7 : { foo10: function() {} } };");
   2788   ExpectString("%FunctionGetInferredName(foo1)", "foo1");
   2789   // foo2 is not unnamed -> its name is not inferred.
   2790   ExpectString("%FunctionGetInferredName(foo2)", "");
   2791   ExpectString("not_ctor()", "foo4");
   2792   ExpectString("Ctor()", "Ctor.foo5");
   2793   ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
   2794   ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
   2795   ExpectString("%FunctionGetInferredName(obj3[1])",
   2796                "obj3.(anonymous function)");
   2797   ExpectString("%FunctionGetInferredName(obj4[1])", "");
   2798   ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
   2799   ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
   2800 }
   2801 
   2802 
   2803 TEST(FuncNameInferrerTwoByte) {
   2804   // Tests function name inferring in cases where some parts of the inferred
   2805   // function name are two-byte strings.
   2806   i::FLAG_allow_natives_syntax = true;
   2807   v8::Isolate* isolate = CcTest::isolate();
   2808   v8::HandleScope scope(isolate);
   2809   LocalContext env;
   2810   uint16_t* two_byte_source = AsciiToTwoByteString(
   2811       "var obj1 = { oXj2 : { foo1: function() {} } }; "
   2812       "%FunctionGetInferredName(obj1.oXj2.foo1)");
   2813   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   2814   // Make it really non-Latin1 (replace the Xs with a non-Latin1 character).
   2815   two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010d;
   2816   v8::Local<v8::String> source =
   2817       v8::String::NewFromTwoByte(isolate, two_byte_source);
   2818   v8::Local<v8::Value> result = CompileRun(source);
   2819   CHECK(result->IsString());
   2820   v8::Local<v8::String> expected_name =
   2821       v8::String::NewFromTwoByte(isolate, two_byte_name);
   2822   CHECK(result->Equals(expected_name));
   2823   i::DeleteArray(two_byte_source);
   2824   i::DeleteArray(two_byte_name);
   2825 }
   2826 
   2827 
   2828 TEST(FuncNameInferrerEscaped) {
   2829   // The same as FuncNameInferrerTwoByte, except that we express the two-byte
   2830   // character as a unicode escape.
   2831   i::FLAG_allow_natives_syntax = true;
   2832   v8::Isolate* isolate = CcTest::isolate();
   2833   v8::HandleScope scope(isolate);
   2834   LocalContext env;
   2835   uint16_t* two_byte_source = AsciiToTwoByteString(
   2836       "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
   2837       "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
   2838   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   2839   // Fix to correspond to the non-ASCII name in two_byte_source.
   2840   two_byte_name[6] = 0x010d;
   2841   v8::Local<v8::String> source =
   2842       v8::String::NewFromTwoByte(isolate, two_byte_source);
   2843   v8::Local<v8::Value> result = CompileRun(source);
   2844   CHECK(result->IsString());
   2845   v8::Local<v8::String> expected_name =
   2846       v8::String::NewFromTwoByte(isolate, two_byte_name);
   2847   CHECK(result->Equals(expected_name));
   2848   i::DeleteArray(two_byte_source);
   2849   i::DeleteArray(two_byte_name);
   2850 }
   2851 
   2852 
   2853 TEST(RegressionLazyFunctionWithErrorWithArg) {
   2854   // The bug occurred when a lazy function had an error which requires a
   2855   // parameter (such as "unknown label" here). The error message was processed
   2856   // before the AstValueFactory containing the error message string was
   2857   // internalized.
   2858   v8::Isolate* isolate = CcTest::isolate();
   2859   v8::HandleScope scope(isolate);
   2860   LocalContext env;
   2861   i::FLAG_lazy = true;
   2862   i::FLAG_min_preparse_length = 0;
   2863   CompileRun("function this_is_lazy() {\n"
   2864              "  break p;\n"
   2865              "}\n"
   2866              "this_is_lazy();\n");
   2867 }
   2868 
   2869 
   2870 TEST(SerializationOfMaybeAssignmentFlag) {
   2871   i::Isolate* isolate = CcTest::i_isolate();
   2872   i::Factory* factory = isolate->factory();
   2873   i::HandleScope scope(isolate);
   2874   LocalContext env;
   2875 
   2876   const char* src =
   2877       "function h() {"
   2878       "  var result = [];"
   2879       "  function f() {"
   2880       "    result.push(2);"
   2881       "  }"
   2882       "  function assertResult(r) {"
   2883       "    f();"
   2884       "    result = [];"
   2885       "  }"
   2886       "  assertResult([2]);"
   2887       "  assertResult([2]);"
   2888       "  return f;"
   2889       "};"
   2890       "h();";
   2891 
   2892   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
   2893   i::SNPrintF(program, "%s", src);
   2894   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
   2895   source->PrintOn(stdout);
   2896   printf("\n");
   2897   i::Zone zone(isolate);
   2898   v8::Local<v8::Value> v = CompileRun(src);
   2899   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
   2900   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
   2901   i::Context* context = f->context();
   2902   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   2903   avf.Internalize(isolate);
   2904   const i::AstRawString* name = avf.GetOneByteString("result");
   2905   i::Handle<i::String> str = name->string();
   2906   CHECK(str->IsInternalizedString());
   2907   i::Scope* global_scope =
   2908       new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
   2909   global_scope->Initialize();
   2910   i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
   2911   DCHECK(s != global_scope);
   2912   DCHECK(name != NULL);
   2913 
   2914   // Get result from h's function context (that is f's context)
   2915   i::Variable* var = s->Lookup(name);
   2916 
   2917   CHECK(var != NULL);
   2918   // Maybe assigned should survive deserialization
   2919   CHECK(var->maybe_assigned() == i::kMaybeAssigned);
   2920   // TODO(sigurds) Figure out if is_used should survive context serialization.
   2921 }
   2922 
   2923 
   2924 TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
   2925   i::Isolate* isolate = CcTest::i_isolate();
   2926   i::Factory* factory = isolate->factory();
   2927   i::HandleScope scope(isolate);
   2928   LocalContext env;
   2929 
   2930 
   2931   const char* src =
   2932       "function f(x) {"
   2933       "    var a = arguments;"
   2934       "    function g(i) {"
   2935       "      ++a[0];"
   2936       "    };"
   2937       "    return g;"
   2938       "  }"
   2939       "f(0);";
   2940 
   2941   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
   2942   i::SNPrintF(program, "%s", src);
   2943   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
   2944   source->PrintOn(stdout);
   2945   printf("\n");
   2946   i::Zone zone(isolate);
   2947   v8::Local<v8::Value> v = CompileRun(src);
   2948   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
   2949   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
   2950   i::Context* context = f->context();
   2951   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   2952   avf.Internalize(isolate);
   2953 
   2954   i::Scope* global_scope =
   2955       new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
   2956   global_scope->Initialize();
   2957   i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
   2958   DCHECK(s != global_scope);
   2959   const i::AstRawString* name_x = avf.GetOneByteString("x");
   2960 
   2961   // Get result from f's function context (that is g's outer context)
   2962   i::Variable* var_x = s->Lookup(name_x);
   2963   CHECK(var_x != NULL);
   2964   CHECK(var_x->maybe_assigned() == i::kMaybeAssigned);
   2965 }
   2966 
   2967 
   2968 TEST(ExportsMaybeAssigned) {
   2969   i::FLAG_use_strict = true;
   2970   i::FLAG_harmony_scoping = true;
   2971   i::FLAG_harmony_modules = true;
   2972 
   2973   i::Isolate* isolate = CcTest::i_isolate();
   2974   i::Factory* factory = isolate->factory();
   2975   i::HandleScope scope(isolate);
   2976   LocalContext env;
   2977 
   2978   const char* src =
   2979       "module A {"
   2980       "  export var x = 1;"
   2981       "  export function f() { return x };"
   2982       "  export const y = 2;"
   2983       "  module B {}"
   2984       "  export module C {}"
   2985       "};"
   2986       "A.f";
   2987 
   2988   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
   2989   i::SNPrintF(program, "%s", src);
   2990   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
   2991   source->PrintOn(stdout);
   2992   printf("\n");
   2993   i::Zone zone(isolate);
   2994   v8::Local<v8::Value> v = CompileRun(src);
   2995   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
   2996   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
   2997   i::Context* context = f->context();
   2998   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   2999   avf.Internalize(isolate);
   3000 
   3001   i::Scope* global_scope =
   3002       new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
   3003   global_scope->Initialize();
   3004   i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
   3005   DCHECK(s != global_scope);
   3006   const i::AstRawString* name_x = avf.GetOneByteString("x");
   3007   const i::AstRawString* name_f = avf.GetOneByteString("f");
   3008   const i::AstRawString* name_y = avf.GetOneByteString("y");
   3009   const i::AstRawString* name_B = avf.GetOneByteString("B");
   3010   const i::AstRawString* name_C = avf.GetOneByteString("C");
   3011 
   3012   // Get result from h's function context (that is f's context)
   3013   i::Variable* var_x = s->Lookup(name_x);
   3014   CHECK(var_x != NULL);
   3015   CHECK(var_x->maybe_assigned() == i::kMaybeAssigned);
   3016   i::Variable* var_f = s->Lookup(name_f);
   3017   CHECK(var_f != NULL);
   3018   CHECK(var_f->maybe_assigned() == i::kMaybeAssigned);
   3019   i::Variable* var_y = s->Lookup(name_y);
   3020   CHECK(var_y != NULL);
   3021   CHECK(var_y->maybe_assigned() == i::kNotAssigned);
   3022   i::Variable* var_B = s->Lookup(name_B);
   3023   CHECK(var_B != NULL);
   3024   CHECK(var_B->maybe_assigned() == i::kNotAssigned);
   3025   i::Variable* var_C = s->Lookup(name_C);
   3026   CHECK(var_C != NULL);
   3027   CHECK(var_C->maybe_assigned() == i::kNotAssigned);
   3028 }
   3029 
   3030 
   3031 TEST(InnerAssignment) {
   3032   i::Isolate* isolate = CcTest::i_isolate();
   3033   i::Factory* factory = isolate->factory();
   3034   i::HandleScope scope(isolate);
   3035   LocalContext env;
   3036 
   3037   const char* prefix = "function f() {";
   3038   const char* midfix = " function g() {";
   3039   const char* suffix = "}}";
   3040   struct { const char* source; bool assigned; bool strict; } outers[] = {
   3041     // Actual assignments.
   3042     { "var x; var x = 5;", true, false },
   3043     { "var x; { var x = 5; }", true, false },
   3044     { "'use strict'; let x; x = 6;", true, true },
   3045     { "var x = 5; function x() {}", true, false },
   3046     // Actual non-assignments.
   3047     { "var x;", false, false },
   3048     { "var x = 5;", false, false },
   3049     { "'use strict'; let x;", false, true },
   3050     { "'use strict'; let x = 6;", false, true },
   3051     { "'use strict'; var x = 0; { let x = 6; }", false, true },
   3052     { "'use strict'; var x = 0; { let x; x = 6; }", false, true },
   3053     { "'use strict'; let x = 0; { let x = 6; }", false, true },
   3054     { "'use strict'; let x = 0; { let x; x = 6; }", false, true },
   3055     { "var x; try {} catch (x) { x = 5; }", false, false },
   3056     { "function x() {}", false, false },
   3057     // Eval approximation.
   3058     { "var x; eval('');", true, false },
   3059     { "eval(''); var x;", true, false },
   3060     { "'use strict'; let x; eval('');", true, true },
   3061     { "'use strict'; eval(''); let x;", true, true },
   3062     // Non-assignments not recognized, because the analysis is approximative.
   3063     { "var x; var x;", true, false },
   3064     { "var x = 5; var x;", true, false },
   3065     { "var x; { var x; }", true, false },
   3066     { "var x; function x() {}", true, false },
   3067     { "function x() {}; var x;", true, false },
   3068     { "var x; try {} catch (x) { var x = 5; }", true, false },
   3069   };
   3070   struct { const char* source; bool assigned; bool with; } inners[] = {
   3071     // Actual assignments.
   3072     { "x = 1;", true, false },
   3073     { "x++;", true, false },
   3074     { "++x;", true, false },
   3075     { "x--;", true, false },
   3076     { "--x;", true, false },
   3077     { "{ x = 1; }", true, false },
   3078     { "'use strict'; { let x; }; x = 0;", true, false },
   3079     { "'use strict'; { const x = 1; }; x = 0;", true, false },
   3080     { "'use strict'; { function x() {} }; x = 0;", true, false },
   3081     { "with ({}) { x = 1; }", true, true },
   3082     { "eval('');", true, false },
   3083     { "'use strict'; { let y; eval('') }", true, false },
   3084     { "function h() { x = 0; }", true, false },
   3085     { "(function() { x = 0; })", true, false },
   3086     { "(function() { x = 0; })", true, false },
   3087     { "with ({}) (function() { x = 0; })", true, true },
   3088     // Actual non-assignments.
   3089     { "", false, false },
   3090     { "x;", false, false },
   3091     { "var x;", false, false },
   3092     { "var x = 8;", false, false },
   3093     { "var x; x = 8;", false, false },
   3094     { "'use strict'; let x;", false, false },
   3095     { "'use strict'; let x = 8;", false, false },
   3096     { "'use strict'; let x; x = 8;", false, false },
   3097     { "'use strict'; const x = 8;", false, false },
   3098     { "function x() {}", false, false },
   3099     { "function x() { x = 0; }", false, false },
   3100     { "function h(x) { x = 0; }", false, false },
   3101     { "'use strict'; { let x; x = 0; }", false, false },
   3102     { "{ var x; }; x = 0;", false, false },
   3103     { "with ({}) {}", false, true },
   3104     { "var x; { with ({}) { x = 1; } }", false, true },
   3105     { "try {} catch(x) { x = 0; }", false, false },
   3106     { "try {} catch(x) { with ({}) { x = 1; } }", false, true },
   3107     // Eval approximation.
   3108     { "eval('');", true, false },
   3109     { "function h() { eval(''); }", true, false },
   3110     { "(function() { eval(''); })", true, false },
   3111     // Shadowing not recognized because of eval approximation.
   3112     { "var x; eval('');", true, false },
   3113     { "'use strict'; let x; eval('');", true, false },
   3114     { "try {} catch(x) { eval(''); }", true, false },
   3115     { "function x() { eval(''); }", true, false },
   3116     { "(function(x) { eval(''); })", true, false },
   3117   };
   3118 
   3119   // Used to trigger lazy compilation of function
   3120   int comment_len = 2048;
   3121   i::ScopedVector<char> comment(comment_len + 1);
   3122   i::SNPrintF(comment, "/*%0*d*/", comment_len - 4, 0);
   3123   int prefix_len = Utf8LengthHelper(prefix);
   3124   int midfix_len = Utf8LengthHelper(midfix);
   3125   int suffix_len = Utf8LengthHelper(suffix);
   3126   for (unsigned i = 0; i < arraysize(outers); ++i) {
   3127     const char* outer = outers[i].source;
   3128     int outer_len = Utf8LengthHelper(outer);
   3129     for (unsigned j = 0; j < arraysize(inners); ++j) {
   3130       for (unsigned outer_lazy = 0; outer_lazy < 2; ++outer_lazy) {
   3131         for (unsigned inner_lazy = 0; inner_lazy < 2; ++inner_lazy) {
   3132           if (outers[i].strict && inners[j].with) continue;
   3133           const char* inner = inners[j].source;
   3134           int inner_len = Utf8LengthHelper(inner);
   3135 
   3136           int outer_comment_len = outer_lazy ? comment_len : 0;
   3137           int inner_comment_len = inner_lazy ? comment_len : 0;
   3138           const char* outer_comment = outer_lazy ? comment.start() : "";
   3139           const char* inner_comment = inner_lazy ? comment.start() : "";
   3140           int len = prefix_len + outer_comment_len + outer_len + midfix_len +
   3141                     inner_comment_len + inner_len + suffix_len;
   3142           i::ScopedVector<char> program(len + 1);
   3143 
   3144           i::SNPrintF(program, "%s%s%s%s%s%s%s", prefix, outer_comment, outer,
   3145                       midfix, inner_comment, inner, suffix);
   3146           i::Handle<i::String> source =
   3147               factory->InternalizeUtf8String(program.start());
   3148           source->PrintOn(stdout);
   3149           printf("\n");
   3150 
   3151           i::Handle<i::Script> script = factory->NewScript(source);
   3152           i::CompilationInfoWithZone info(script);
   3153           i::Parser::ParseInfo parse_info = {
   3154               isolate->stack_guard()->real_climit(),
   3155               isolate->heap()->HashSeed(), isolate->unicode_cache()};
   3156           i::Parser parser(&info, &parse_info);
   3157           parser.set_allow_harmony_scoping(true);
   3158           CHECK(parser.Parse());
   3159           CHECK(i::Rewriter::Rewrite(&info));
   3160           CHECK(i::Scope::Analyze(&info));
   3161           CHECK(info.function() != NULL);
   3162 
   3163           i::Scope* scope = info.function()->scope();
   3164           CHECK_EQ(scope->inner_scopes()->length(), 1);
   3165           i::Scope* inner_scope = scope->inner_scopes()->at(0);
   3166           const i::AstRawString* var_name =
   3167               info.ast_value_factory()->GetOneByteString("x");
   3168           i::Variable* var = inner_scope->Lookup(var_name);
   3169           bool expected = outers[i].assigned || inners[j].assigned;
   3170           CHECK(var != NULL);
   3171           CHECK(var->is_used() || !expected);
   3172           CHECK((var->maybe_assigned() == i::kMaybeAssigned) == expected);
   3173         }
   3174       }
   3175     }
   3176   }
   3177 }
   3178 
   3179 namespace {
   3180 
   3181 int* global_use_counts = NULL;
   3182 
   3183 void MockUseCounterCallback(v8::Isolate* isolate,
   3184                             v8::Isolate::UseCounterFeature feature) {
   3185   ++global_use_counts[feature];
   3186 }
   3187 
   3188 }
   3189 
   3190 
   3191 TEST(UseAsmUseCount) {
   3192   i::Isolate* isolate = CcTest::i_isolate();
   3193   i::HandleScope scope(isolate);
   3194   LocalContext env;
   3195   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
   3196   global_use_counts = use_counts;
   3197   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
   3198   CompileRun("\"use asm\";\n"
   3199              "var foo = 1;\n"
   3200              "\"use asm\";\n"  // Only the first one counts.
   3201              "function bar() { \"use asm\"; var baz = 1; }");
   3202   CHECK_EQ(2, use_counts[v8::Isolate::kUseAsm]);
   3203 }
   3204 
   3205 
   3206 TEST(ErrorsArrowFunctions) {
   3207   // Tests that parser and preparser generate the same kind of errors
   3208   // on invalid arrow function syntax.
   3209   const char* context_data[][2] = {
   3210     {"", ";"},
   3211     {"v = ", ";"},
   3212     {"bar ? (", ") : baz;"},
   3213     {"bar ? baz : (", ");"},
   3214     {"bar[", "];"},
   3215     {"bar, ", ";"},
   3216     {"", ", bar;"},
   3217     {NULL, NULL}
   3218   };
   3219 
   3220   const char* statement_data[] = {
   3221     "=> 0",
   3222     "=>",
   3223     "() =>",
   3224     "=> {}",
   3225     ") => {}",
   3226     ", => {}",
   3227     "(,) => {}",
   3228     "return => {}",
   3229     "() => {'value': 42}",
   3230 
   3231     // Check that the early return introduced in ParsePrimaryExpression
   3232     // does not accept stray closing parentheses.
   3233     ")",
   3234     ") => 0",
   3235     "foo[()]",
   3236     "()",
   3237 
   3238     // Parameter lists with extra parens should be recognized as errors.
   3239     "(()) => 0",
   3240     "((x)) => 0",
   3241     "((x, y)) => 0",
   3242     "(x, (y)) => 0",
   3243     "((x, y, z)) => 0",
   3244     "(x, (y, z)) => 0",
   3245     "((x, y), z) => 0",
   3246 
   3247     // Parameter lists are always validated as strict, so those are errors.
   3248     "eval => {}",
   3249     "arguments => {}",
   3250     "yield => {}",
   3251     "interface => {}",
   3252     "(eval) => {}",
   3253     "(arguments) => {}",
   3254     "(yield) => {}",
   3255     "(interface) => {}",
   3256     "(eval, bar) => {}",
   3257     "(bar, eval) => {}",
   3258     "(bar, arguments) => {}",
   3259     "(bar, yield) => {}",
   3260     "(bar, interface) => {}",
   3261     // TODO(aperez): Detecting duplicates does not work in PreParser.
   3262     // "(bar, bar) => {}",
   3263 
   3264     // The parameter list is parsed as an expression, but only
   3265     // a comma-separated list of identifier is valid.
   3266     "32 => {}",
   3267     "(32) => {}",
   3268     "(a, 32) => {}",
   3269     "if => {}",
   3270     "(if) => {}",
   3271     "(a, if) => {}",
   3272     "a + b => {}",
   3273     "(a + b) => {}",
   3274     "(a + b, c) => {}",
   3275     "(a, b - c) => {}",
   3276     "\"a\" => {}",
   3277     "(\"a\") => {}",
   3278     "(\"a\", b) => {}",
   3279     "(a, \"b\") => {}",
   3280     "-a => {}",
   3281     "(-a) => {}",
   3282     "(-a, b) => {}",
   3283     "(a, -b) => {}",
   3284     "{} => {}",
   3285     "({}) => {}",
   3286     "(a, {}) => {}",
   3287     "({}, a) => {}",
   3288     "a++ => {}",
   3289     "(a++) => {}",
   3290     "(a++, b) => {}",
   3291     "(a, b++) => {}",
   3292     "[] => {}",
   3293     "([]) => {}",
   3294     "(a, []) => {}",
   3295     "([], a) => {}",
   3296     "(a = b) => {}",
   3297     "(a = b, c) => {}",
   3298     "(a, b = c) => {}",
   3299     "(foo ? bar : baz) => {}",
   3300     "(a, foo ? bar : baz) => {}",
   3301     "(foo ? bar : baz, a) => {}",
   3302     NULL
   3303   };
   3304 
   3305   // The test is quite slow, so run it with a reduced set of flags.
   3306   static const ParserFlag flags[] = {kAllowLazy, kAllowHarmonyScoping};
   3307   static const ParserFlag always_flags[] = { kAllowArrowFunctions };
   3308   RunParserSyncTest(context_data, statement_data, kError, flags,
   3309                     arraysize(flags), always_flags, arraysize(always_flags));
   3310 }
   3311 
   3312 
   3313 TEST(NoErrorsArrowFunctions) {
   3314   // Tests that parser and preparser accept valid arrow functions syntax.
   3315   const char* context_data[][2] = {
   3316     {"", ";"},
   3317     {"bar ? (", ") : baz;"},
   3318     {"bar ? baz : (", ");"},
   3319     {"bar, ", ";"},
   3320     {"", ", bar;"},
   3321     {NULL, NULL}
   3322   };
   3323 
   3324   const char* statement_data[] = {
   3325     "() => {}",
   3326     "() => { return 42 }",
   3327     "x => { return x; }",
   3328     "(x) => { return x; }",
   3329     "(x, y) => { return x + y; }",
   3330     "(x, y, z) => { return x + y + z; }",
   3331     "(x, y) => { x.a = y; }",
   3332     "() => 42",
   3333     "x => x",
   3334     "x => x * x",
   3335     "(x) => x",
   3336     "(x) => x * x",
   3337     "(x, y) => x + y",
   3338     "(x, y, z) => x, y, z",
   3339     "(x, y) => x.a = y",
   3340     "() => ({'value': 42})",
   3341     "x => y => x + y",
   3342     "(x, y) => (u, v) => x*u + y*v",
   3343     "(x, y) => z => z * (x + y)",
   3344     "x => (y, z) => z * (x + y)",
   3345 
   3346     // Those are comma-separated expressions, with arrow functions as items.
   3347     // They stress the code for validating arrow function parameter lists.
   3348     "a, b => 0",
   3349     "a, b, (c, d) => 0",
   3350     "(a, b, (c, d) => 0)",
   3351     "(a, b) => 0, (c, d) => 1",
   3352     "(a, b => {}, a => a + 1)",
   3353     "((a, b) => {}, (a => a + 1))",
   3354     "(a, (a, (b, c) => 0))",
   3355 
   3356     // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
   3357     "foo ? bar : baz => {}",
   3358     NULL
   3359   };
   3360 
   3361   static const ParserFlag always_flags[] = {kAllowArrowFunctions};
   3362   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   3363                     always_flags, arraysize(always_flags));
   3364 }
   3365 
   3366 
   3367 TEST(NoErrorsSuper) {
   3368   // Tests that parser and preparser accept 'super' keyword in right places.
   3369   const char* context_data[][2] = {{"", ";"},
   3370                                    {"k = ", ";"},
   3371                                    {"foo(", ");"},
   3372                                    {NULL, NULL}};
   3373 
   3374   const char* statement_data[] = {
   3375     "super.x",
   3376     "super[27]",
   3377     "new super",
   3378     "new super()",
   3379     "new super(12, 45)",
   3380     "new new super",
   3381     "new new super()",
   3382     "new new super()()",
   3383     "z.super",  // Ok, property lookup.
   3384     NULL};
   3385 
   3386   static const ParserFlag always_flags[] = {kAllowClasses};
   3387   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   3388                     always_flags, arraysize(always_flags));
   3389 }
   3390 
   3391 
   3392 TEST(ErrorsSuper) {
   3393   // Tests that parser and preparser generate same errors for 'super'.
   3394   const char* context_data[][2] = {{"", ";"},
   3395                                    {"k = ", ";"},
   3396                                    {"foo(", ");"},
   3397                                    {NULL, NULL}};
   3398 
   3399   const char* statement_data[] = {
   3400     "super = x",
   3401     "y = super",
   3402     "f(super)",
   3403     NULL};
   3404 
   3405   static const ParserFlag always_flags[] = {kAllowClasses};
   3406   RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
   3407                     always_flags, arraysize(always_flags));
   3408 }
   3409 
   3410 
   3411 TEST(NoErrorsMethodDefinition) {
   3412   const char* context_data[][2] = {{"({", "});"},
   3413                                    {"'use strict'; ({", "});"},
   3414                                    {"({*", "});"},
   3415                                    {"'use strict'; ({*", "});"},
   3416                                    {NULL, NULL}};
   3417 
   3418   const char* object_literal_body_data[] = {
   3419     "m() {}",
   3420     "m(x) { return x; }",
   3421     "m(x, y) {}, n() {}",
   3422     "set(x, y) {}",
   3423     "get(x, y) {}",
   3424     NULL
   3425   };
   3426 
   3427   static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
   3428   RunParserSyncTest(context_data, object_literal_body_data, kSuccess, NULL, 0,
   3429                     always_flags, arraysize(always_flags));
   3430 }
   3431 
   3432 
   3433 TEST(MethodDefinitionNames) {
   3434   const char* context_data[][2] = {{"({", "(x, y) {}});"},
   3435                                    {"'use strict'; ({", "(x, y) {}});"},
   3436                                    {"({*", "(x, y) {}});"},
   3437                                    {"'use strict'; ({*", "(x, y) {}});"},
   3438                                    {NULL, NULL}};
   3439 
   3440   const char* name_data[] = {
   3441     "m",
   3442     "'m'",
   3443     "\"m\"",
   3444     "\"m n\"",
   3445     "true",
   3446     "false",
   3447     "null",
   3448     "0",
   3449     "1.2",
   3450     "1e1",
   3451     "1E1",
   3452     "1e+1",
   3453     "1e-1",
   3454 
   3455     // Keywords
   3456     "async",
   3457     "await",
   3458     "break",
   3459     "case",
   3460     "catch",
   3461     "class",
   3462     "const",
   3463     "continue",
   3464     "debugger",
   3465     "default",
   3466     "delete",
   3467     "do",
   3468     "else",
   3469     "enum",
   3470     "export",
   3471     "extends",
   3472     "finally",
   3473     "for",
   3474     "function",
   3475     "if",
   3476     "implements",
   3477     "import",
   3478     "in",
   3479     "instanceof",
   3480     "interface",
   3481     "let",
   3482     "new",
   3483     "package",
   3484     "private",
   3485     "protected",
   3486     "public",
   3487     "return",
   3488     "static",
   3489     "super",
   3490     "switch",
   3491     "this",
   3492     "throw",
   3493     "try",
   3494     "typeof",
   3495     "var",
   3496     "void",
   3497     "while",
   3498     "with",
   3499     "yield",
   3500     NULL
   3501   };
   3502 
   3503   static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
   3504   RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
   3505                     always_flags, arraysize(always_flags));
   3506 }
   3507 
   3508 
   3509 TEST(MethodDefinitionStrictFormalParamereters) {
   3510   const char* context_data[][2] = {{"({method(", "){}});"},
   3511                                    {"'use strict'; ({method(", "){}});"},
   3512                                    {"({*method(", "){}});"},
   3513                                    {"'use strict'; ({*method(", "){}});"},
   3514                                    {NULL, NULL}};
   3515 
   3516   const char* params_data[] = {
   3517     "x, x",
   3518     "x, y, x",
   3519     "eval",
   3520     "arguments",
   3521     "var",
   3522     "const",
   3523     NULL
   3524   };
   3525 
   3526   static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
   3527   RunParserSyncTest(context_data, params_data, kError, NULL, 0,
   3528                     always_flags, arraysize(always_flags));
   3529 }
   3530 
   3531 
   3532 TEST(MethodDefinitionDuplicateProperty) {
   3533   // Duplicate properties are allowed in ES6 but we haven't removed that check
   3534   // yet.
   3535   const char* context_data[][2] = {{"'use strict'; ({", "});"},
   3536                                    {NULL, NULL}};
   3537 
   3538   const char* params_data[] = {
   3539     "x: 1, x() {}",
   3540     "x() {}, x: 1",
   3541     "x() {}, get x() {}",
   3542     "x() {}, set x(_) {}",
   3543     "x() {}, x() {}",
   3544     "x() {}, y() {}, x() {}",
   3545     "x() {}, \"x\"() {}",
   3546     "x() {}, 'x'() {}",
   3547     "0() {}, '0'() {}",
   3548     "1.0() {}, 1: 1",
   3549 
   3550     "x: 1, *x() {}",
   3551     "*x() {}, x: 1",
   3552     "*x() {}, get x() {}",
   3553     "*x() {}, set x(_) {}",
   3554     "*x() {}, *x() {}",
   3555     "*x() {}, y() {}, *x() {}",
   3556     "*x() {}, *\"x\"() {}",
   3557     "*x() {}, *'x'() {}",
   3558     "*0() {}, *'0'() {}",
   3559     "*1.0() {}, 1: 1",
   3560 
   3561     NULL
   3562   };
   3563 
   3564   static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
   3565   RunParserSyncTest(context_data, params_data, kError, NULL, 0,
   3566                     always_flags, arraysize(always_flags));
   3567 }
   3568 
   3569 
   3570 TEST(ClassExpressionNoErrors) {
   3571   const char* context_data[][2] = {{"(", ");"},
   3572                                    {"var C = ", ";"},
   3573                                    {"bar, ", ";"},
   3574                                    {NULL, NULL}};
   3575   const char* class_data[] = {
   3576     "class {}",
   3577     "class name {}",
   3578     "class extends F {}",
   3579     "class name extends F {}",
   3580     "class extends (F, G) {}",
   3581     "class name extends (F, G) {}",
   3582     "class extends class {} {}",
   3583     "class name extends class {} {}",
   3584     "class extends class base {} {}",
   3585     "class name extends class base {} {}",
   3586     NULL};
   3587 
   3588   static const ParserFlag always_flags[] = {kAllowClasses};
   3589   RunParserSyncTest(context_data, class_data, kSuccess, NULL, 0,
   3590                     always_flags, arraysize(always_flags));
   3591 }
   3592 
   3593 
   3594 TEST(ClassDeclarationNoErrors) {
   3595   const char* context_data[][2] = {{"", ""},
   3596                                    {"{", "}"},
   3597                                    {"if (true) {", "}"},
   3598                                    {NULL, NULL}};
   3599   const char* statement_data[] = {
   3600     "class name {}",
   3601     "class name extends F {}",
   3602     "class name extends (F, G) {}",
   3603     "class name extends class {} {}",
   3604     "class name extends class base {} {}",
   3605     NULL};
   3606 
   3607   static const ParserFlag always_flags[] = {kAllowClasses};
   3608   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
   3609                     always_flags, arraysize(always_flags));
   3610 }
   3611 
   3612 
   3613 TEST(ClassBodyNoErrors) {
   3614   // Tests that parser and preparser accept valid class syntax.
   3615   const char* context_data[][2] = {{"(class {", "});"},
   3616                                    {"(class extends Base {", "});"},
   3617                                    {"class C {", "}"},
   3618                                    {"class C extends Base {", "}"},
   3619                                    {NULL, NULL}};
   3620   const char* class_body_data[] = {
   3621     ";",
   3622     ";;",
   3623     "m() {}",
   3624     "m() {};",
   3625     "; m() {}",
   3626     "m() {}; n(x) {}",
   3627     "get x() {}",
   3628     "set x(v) {}",
   3629     "get() {}",
   3630     "set() {}",
   3631     "*g() {}",
   3632     "*g() {};",
   3633     "; *g() {}",
   3634     "*g() {}; *h(x) {}",
   3635     "static() {}",
   3636     "static m() {}",
   3637     "static get x() {}",
   3638     "static set x(v) {}",
   3639     "static get() {}",
   3640     "static set() {}",
   3641     "static static() {}",
   3642     "static get static() {}",
   3643     "static set static(v) {}",
   3644     "*static() {}",
   3645     "*get() {}",
   3646     "*set() {}",
   3647     "static *g() {}",
   3648     NULL};
   3649 
   3650   static const ParserFlag always_flags[] = {
   3651     kAllowClasses,
   3652     kAllowHarmonyObjectLiterals
   3653   };
   3654   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
   3655                     always_flags, arraysize(always_flags));
   3656 }
   3657 
   3658 
   3659 TEST(ClassPropertyNameNoErrors) {
   3660   const char* context_data[][2] = {{"(class {", "() {}});"},
   3661                                    {"(class { get ", "() {}});"},
   3662                                    {"(class { set ", "(v) {}});"},
   3663                                    {"(class { static ", "() {}});"},
   3664                                    {"(class { static get ", "() {}});"},
   3665                                    {"(class { static set ", "(v) {}});"},
   3666                                    {"(class { *", "() {}});"},
   3667                                    {"(class { static *", "() {}});"},
   3668                                    {"class C {", "() {}}"},
   3669                                    {"class C { get ", "() {}}"},
   3670                                    {"class C { set ", "(v) {}}"},
   3671                                    {"class C { static ", "() {}}"},
   3672                                    {"class C { static get ", "() {}}"},
   3673                                    {"class C { static set ", "(v) {}}"},
   3674                                    {"class C { *", "() {}}"},
   3675                                    {"class C { static *", "() {}}"},
   3676                                    {NULL, NULL}};
   3677   const char* name_data[] = {
   3678     "42",
   3679     "42.5",
   3680     "42e2",
   3681     "42e+2",
   3682     "42e-2",
   3683     "null",
   3684     "false",
   3685     "true",
   3686     "'str'",
   3687     "\"str\"",
   3688     "static",
   3689     "get",
   3690     "set",
   3691     "var",
   3692     "const",
   3693     "let",
   3694     "this",
   3695     "class",
   3696     "function",
   3697     "yield",
   3698     "if",
   3699     "else",
   3700     "for",
   3701     "while",
   3702     "do",
   3703     "try",
   3704     "catch",
   3705     "finally",
   3706     NULL};
   3707 
   3708   static const ParserFlag always_flags[] = {
   3709     kAllowClasses,
   3710     kAllowHarmonyObjectLiterals
   3711   };
   3712   RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
   3713                     always_flags, arraysize(always_flags));
   3714 }
   3715 
   3716 
   3717 TEST(ClassExpressionErrors) {
   3718   const char* context_data[][2] = {{"(", ");"},
   3719                                    {"var C = ", ";"},
   3720                                    {"bar, ", ";"},
   3721                                    {NULL, NULL}};
   3722   const char* class_data[] = {
   3723     "class",
   3724     "class name",
   3725     "class name extends",
   3726     "class extends",
   3727     "class {",
   3728     "class { m }",
   3729     "class { m; n }",
   3730     "class { m: 1 }",
   3731     "class { m(); n() }",
   3732     "class { get m }",
   3733     "class { get m() }",
   3734     "class { get m() { }",
   3735     "class { set m() {} }",  // Missing required parameter.
   3736     "class { m() {}, n() {} }",  // No commas allowed.
   3737     NULL};
   3738 
   3739   static const ParserFlag always_flags[] = {
   3740     kAllowClasses,
   3741     kAllowHarmonyObjectLiterals
   3742   };
   3743   RunParserSyncTest(context_data, class_data, kError, NULL, 0,
   3744                     always_flags, arraysize(always_flags));
   3745 }
   3746 
   3747 
   3748 TEST(ClassDeclarationErrors) {
   3749   const char* context_data[][2] = {{"", ""},
   3750                                    {"{", "}"},
   3751                                    {"if (true) {", "}"},
   3752                                    {NULL, NULL}};
   3753   const char* class_data[] = {
   3754     "class",
   3755     "class name",
   3756     "class name extends",
   3757     "class extends",
   3758     "class name {",
   3759     "class name { m }",
   3760     "class name { m; n }",
   3761     "class name { m: 1 }",
   3762     "class name { m(); n() }",
   3763     "class name { get x }",
   3764     "class name { get x() }",
   3765     "class name { set x() {) }",  // missing required param
   3766     "class {}",  // Name is required for declaration
   3767     "class extends base {}",
   3768     "class name { *",
   3769     "class name { * }",
   3770     "class name { *; }",
   3771     "class name { *get x() {} }",
   3772     "class name { *set x(_) {} }",
   3773     "class name { *static m() {} }",
   3774     NULL};
   3775 
   3776   static const ParserFlag always_flags[] = {
   3777     kAllowClasses,
   3778     kAllowHarmonyNumericLiterals
   3779   };
   3780   RunParserSyncTest(context_data, class_data, kError, NULL, 0,
   3781                     always_flags, arraysize(always_flags));
   3782 }
   3783 
   3784 
   3785 TEST(ClassNameErrors) {
   3786   const char* context_data[][2] = {{"class ", "{}"},
   3787                                    {"(class ", "{});"},
   3788                                    {"'use strict'; class ", "{}"},
   3789                                    {"'use strict'; (class ", "{});"},
   3790                                    {NULL, NULL}};
   3791   const char* class_name[] = {
   3792     "arguments",
   3793     "eval",
   3794     "implements",
   3795     "interface",
   3796     "let",
   3797     "package",
   3798     "private",
   3799     "protected",
   3800     "public",
   3801     "static",
   3802     "var",
   3803     "yield",
   3804     NULL};
   3805 
   3806   static const ParserFlag always_flags[] = {
   3807     kAllowClasses,
   3808     kAllowHarmonyObjectLiterals
   3809   };
   3810   RunParserSyncTest(context_data, class_name, kError, NULL, 0,
   3811                     always_flags, arraysize(always_flags));
   3812 }
   3813 
   3814 
   3815 TEST(ClassGetterParamNameErrors) {
   3816   const char* context_data[][2] = {
   3817     {"class C { get name(", ") {} }"},
   3818     {"(class { get name(", ") {} });"},
   3819     {"'use strict'; class C { get name(", ") {} }"},
   3820     {"'use strict'; (class { get name(", ") {} })"},
   3821     {NULL, NULL}
   3822   };
   3823 
   3824   const char* class_name[] = {
   3825     "arguments",
   3826     "eval",
   3827     "implements",
   3828     "interface",
   3829     "let",
   3830     "package",
   3831     "private",
   3832     "protected",
   3833     "public",
   3834     "static",
   3835     "var",
   3836     "yield",
   3837     NULL};
   3838 
   3839   static const ParserFlag always_flags[] = {
   3840     kAllowClasses,
   3841     kAllowHarmonyObjectLiterals
   3842   };
   3843   RunParserSyncTest(context_data, class_name, kError, NULL, 0,
   3844                     always_flags, arraysize(always_flags));
   3845 }
   3846 
   3847 
   3848 TEST(ClassStaticPrototypeErrors) {
   3849   const char* context_data[][2] = {{"class C {", "}"},
   3850                                    {"(class {", "});"},
   3851                                    {NULL, NULL}};
   3852 
   3853   const char* class_body_data[] = {
   3854     "static prototype() {}",
   3855     "static get prototype() {}",
   3856     "static set prototype(_) {}",
   3857     "static *prototype() {}",
   3858     NULL};
   3859 
   3860   static const ParserFlag always_flags[] = {
   3861     kAllowClasses,
   3862     kAllowHarmonyObjectLiterals
   3863   };
   3864   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
   3865                     always_flags, arraysize(always_flags));
   3866 }
   3867 
   3868 
   3869 TEST(ClassSpecialConstructorErrors) {
   3870   const char* context_data[][2] = {{"class C {", "}"},
   3871                                    {"(class {", "});"},
   3872                                    {NULL, NULL}};
   3873 
   3874   const char* class_body_data[] = {
   3875     "get constructor() {}",
   3876     "get constructor(_) {}",
   3877     "*constructor() {}",
   3878     NULL};
   3879 
   3880   static const ParserFlag always_flags[] = {
   3881     kAllowClasses,
   3882     kAllowHarmonyObjectLiterals
   3883   };
   3884   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
   3885                     always_flags, arraysize(always_flags));
   3886 }
   3887 
   3888 
   3889 TEST(ClassConstructorNoErrors) {
   3890   const char* context_data[][2] = {{"class C {", "}"},
   3891                                    {"(class {", "});"},
   3892                                    {NULL, NULL}};
   3893 
   3894   const char* class_body_data[] = {
   3895     "constructor() {}",
   3896     "static constructor() {}",
   3897     "static get constructor() {}",
   3898     "static set constructor(_) {}",
   3899     "static *constructor() {}",
   3900     NULL};
   3901 
   3902   static const ParserFlag always_flags[] = {
   3903     kAllowClasses,
   3904     kAllowHarmonyObjectLiterals
   3905   };
   3906   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
   3907                     always_flags, arraysize(always_flags));
   3908 }
   3909 
   3910 
   3911 TEST(ClassMultipleConstructorErrors) {
   3912   // We currently do not allow any duplicate properties in class bodies. This
   3913   // test ensures that when we change that we still throw on duplicate
   3914   // constructors.
   3915   const char* context_data[][2] = {{"class C {", "}"},
   3916                                    {"(class {", "});"},
   3917                                    {NULL, NULL}};
   3918 
   3919   const char* class_body_data[] = {
   3920     "constructor() {}; constructor() {}",
   3921     NULL};
   3922 
   3923   static const ParserFlag always_flags[] = {
   3924     kAllowClasses,
   3925     kAllowHarmonyObjectLiterals
   3926   };
   3927   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
   3928                     always_flags, arraysize(always_flags));
   3929 }
   3930 
   3931 
   3932 // TODO(arv): We should allow duplicate property names.
   3933 // https://code.google.com/p/v8/issues/detail?id=3570
   3934 DISABLED_TEST(ClassMultiplePropertyNamesNoErrors) {
   3935   const char* context_data[][2] = {{"class C {", "}"},
   3936                                    {"(class {", "});"},
   3937                                    {NULL, NULL}};
   3938 
   3939   const char* class_body_data[] = {
   3940     "constructor() {}; static constructor() {}",
   3941     "m() {}; static m() {}",
   3942     "m() {}; m() {}",
   3943     NULL};
   3944 
   3945   static const ParserFlag always_flags[] = {
   3946     kAllowClasses,
   3947     kAllowHarmonyObjectLiterals
   3948   };
   3949   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
   3950                     always_flags, arraysize(always_flags));
   3951 }
   3952 
   3953 
   3954 TEST(ClassesAreStrictErrors) {
   3955   const char* context_data[][2] = {{"", ""},
   3956                                    {"(", ");"},
   3957                                    {NULL, NULL}};
   3958 
   3959   const char* class_body_data[] = {
   3960     "class C { method() { with ({}) {} } }",
   3961     "class C extends function() { with ({}) {} } {}",
   3962     "class C { *method() { with ({}) {} } }",
   3963     NULL};
   3964 
   3965   static const ParserFlag always_flags[] = {
   3966     kAllowClasses,
   3967     kAllowHarmonyObjectLiterals
   3968   };
   3969   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
   3970                     always_flags, arraysize(always_flags));
   3971 }
   3972