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 <stdlib.h>
     29 #include <stdio.h>
     30 #include <string.h>
     31 
     32 #include "src/v8.h"
     33 
     34 #include "src/compiler.h"
     35 #include "src/execution.h"
     36 #include "src/isolate.h"
     37 #include "src/objects.h"
     38 #include "src/parser.h"
     39 #include "src/preparser.h"
     40 #include "src/scanner-character-streams.h"
     41 #include "src/token.h"
     42 #include "src/utils.h"
     43 #include "test/cctest/cctest.h"
     44 
     45 TEST(ScanKeywords) {
     46   struct KeywordToken {
     47     const char* keyword;
     48     i::Token::Value token;
     49   };
     50 
     51   static const KeywordToken keywords[] = {
     52 #define KEYWORD(t, s, d) { s, i::Token::t },
     53       TOKEN_LIST(IGNORE_TOKEN, KEYWORD)
     54 #undef KEYWORD
     55       { NULL, i::Token::IDENTIFIER }
     56   };
     57 
     58   KeywordToken key_token;
     59   i::UnicodeCache unicode_cache;
     60   i::byte buffer[32];
     61   for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
     62     const i::byte* keyword =
     63         reinterpret_cast<const i::byte*>(key_token.keyword);
     64     int length = i::StrLength(key_token.keyword);
     65     CHECK(static_cast<int>(sizeof(buffer)) >= length);
     66     {
     67       i::Utf8ToUtf16CharacterStream stream(keyword, length);
     68       i::Scanner scanner(&unicode_cache);
     69       // The scanner should parse Harmony keywords for this test.
     70       scanner.SetHarmonyScoping(true);
     71       scanner.SetHarmonyModules(true);
     72       scanner.Initialize(&stream);
     73       CHECK_EQ(key_token.token, scanner.Next());
     74       CHECK_EQ(i::Token::EOS, scanner.Next());
     75     }
     76     // Removing characters will make keyword matching fail.
     77     {
     78       i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
     79       i::Scanner scanner(&unicode_cache);
     80       scanner.Initialize(&stream);
     81       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     82       CHECK_EQ(i::Token::EOS, scanner.Next());
     83     }
     84     // Adding characters will make keyword matching fail.
     85     static const char chars_to_append[] = { 'z', '0', '_' };
     86     for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
     87       i::MemMove(buffer, keyword, length);
     88       buffer[length] = chars_to_append[j];
     89       i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
     90       i::Scanner scanner(&unicode_cache);
     91       scanner.Initialize(&stream);
     92       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     93       CHECK_EQ(i::Token::EOS, scanner.Next());
     94     }
     95     // Replacing characters will make keyword matching fail.
     96     {
     97       i::MemMove(buffer, keyword, length);
     98       buffer[length - 1] = '_';
     99       i::Utf8ToUtf16CharacterStream stream(buffer, length);
    100       i::Scanner scanner(&unicode_cache);
    101       scanner.Initialize(&stream);
    102       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
    103       CHECK_EQ(i::Token::EOS, scanner.Next());
    104     }
    105   }
    106 }
    107 
    108 
    109 TEST(ScanHTMLEndComments) {
    110   v8::V8::Initialize();
    111   v8::Isolate* isolate = CcTest::isolate();
    112   v8::HandleScope handles(isolate);
    113 
    114   // Regression test. See:
    115   //    http://code.google.com/p/chromium/issues/detail?id=53548
    116   // Tests that --> is correctly interpreted as comment-to-end-of-line if there
    117   // is only whitespace before it on the line (with comments considered as
    118   // whitespace, even a multiline-comment containing a newline).
    119   // This was not the case if it occurred before the first real token
    120   // in the input.
    121   const char* tests[] = {
    122       // Before first real token.
    123       "--> is eol-comment\nvar y = 37;\n",
    124       "\n --> is eol-comment\nvar y = 37;\n",
    125       "/* precomment */ --> is eol-comment\nvar y = 37;\n",
    126       "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    127       // After first real token.
    128       "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
    129       "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
    130       NULL
    131   };
    132 
    133   const char* fail_tests[] = {
    134       "x --> is eol-comment\nvar y = 37;\n",
    135       "\"\\n\" --> is eol-comment\nvar y = 37;\n",
    136       "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
    137       "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    138       "var x = 42; --> is eol-comment\nvar y = 37;\n",
    139       "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
    140       NULL
    141   };
    142 
    143   // Parser/Scanner needs a stack limit.
    144   int marker;
    145   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    146       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    147   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    148   for (int i = 0; tests[i]; i++) {
    149     const i::byte* source =
    150         reinterpret_cast<const i::byte*>(tests[i]);
    151     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i]));
    152     i::CompleteParserRecorder log;
    153     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    154     scanner.Initialize(&stream);
    155     i::PreParser preparser(&scanner, &log, stack_limit);
    156     preparser.set_allow_lazy(true);
    157     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    158     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    159     i::ScriptData data(log.ExtractData());
    160     CHECK(!data.has_error());
    161   }
    162 
    163   for (int i = 0; fail_tests[i]; i++) {
    164     const i::byte* source =
    165         reinterpret_cast<const i::byte*>(fail_tests[i]);
    166     i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i]));
    167     i::CompleteParserRecorder log;
    168     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    169     scanner.Initialize(&stream);
    170     i::PreParser preparser(&scanner, &log, stack_limit);
    171     preparser.set_allow_lazy(true);
    172     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    173     // Even in the case of a syntax error, kPreParseSuccess is returned.
    174     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    175     i::ScriptData data(log.ExtractData());
    176     CHECK(data.has_error());
    177   }
    178 }
    179 
    180 
    181 class ScriptResource : public v8::String::ExternalAsciiStringResource {
    182  public:
    183   ScriptResource(const char* data, size_t length)
    184       : data_(data), length_(length) { }
    185 
    186   const char* data() const { return data_; }
    187   size_t length() const { return length_; }
    188 
    189  private:
    190   const char* data_;
    191   size_t length_;
    192 };
    193 
    194 
    195 TEST(UsingCachedData) {
    196   v8::Isolate* isolate = CcTest::isolate();
    197   v8::HandleScope handles(isolate);
    198   v8::Local<v8::Context> context = v8::Context::New(isolate);
    199   v8::Context::Scope context_scope(context);
    200   int marker;
    201   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    202       reinterpret_cast<uintptr_t>(&marker) - 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   int source_length = i::StrLength(source);
    218 
    219   // ScriptResource will be deleted when the corresponding String is GCd.
    220   v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
    221       isolate, new ScriptResource(source, source_length)));
    222   i::FLAG_min_preparse_length = 0;
    223   v8::ScriptCompiler::Compile(isolate, &script_source,
    224                               v8::ScriptCompiler::kProduceDataToCache);
    225   CHECK(script_source.GetCachedData());
    226 
    227   // Compile the script again, using the cached data.
    228   bool lazy_flag = i::FLAG_lazy;
    229   i::FLAG_lazy = true;
    230   v8::ScriptCompiler::Compile(isolate, &script_source);
    231   i::FLAG_lazy = false;
    232   v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
    233   i::FLAG_lazy = lazy_flag;
    234 }
    235 
    236 
    237 TEST(PreparseFunctionDataIsUsed) {
    238   // This tests that we actually do use the function data generated by the
    239   // preparser.
    240 
    241   // Make preparsing work for short scripts.
    242   i::FLAG_min_preparse_length = 0;
    243 
    244   v8::Isolate* isolate = CcTest::isolate();
    245   v8::HandleScope handles(isolate);
    246   v8::Local<v8::Context> context = v8::Context::New(isolate);
    247   v8::Context::Scope context_scope(context);
    248   int marker;
    249   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    250       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    251 
    252   const char* good_code =
    253       "function this_is_lazy() { var a; } function foo() { return 25; } foo();";
    254 
    255   // Insert a syntax error inside the lazy function.
    256   const char* bad_code =
    257       "function this_is_lazy() { if (   } function foo() { return 25; } foo();";
    258 
    259   v8::ScriptCompiler::Source good_source(v8_str(good_code));
    260   v8::ScriptCompiler::Compile(isolate, &good_source,
    261                               v8::ScriptCompiler::kProduceDataToCache);
    262 
    263   const v8::ScriptCompiler::CachedData* cached_data =
    264       good_source.GetCachedData();
    265   CHECK(cached_data->data != NULL);
    266   CHECK_GT(cached_data->length, 0);
    267 
    268   // Now compile the erroneous code with the good preparse data. If the preparse
    269   // data is used, the lazy function is skipped and it should compile fine.
    270   v8::ScriptCompiler::Source bad_source(
    271       v8_str(bad_code), new v8::ScriptCompiler::CachedData(
    272                             cached_data->data, cached_data->length));
    273   v8::Local<v8::Value> result =
    274       v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
    275   CHECK(result->IsInt32());
    276   CHECK_EQ(25, result->Int32Value());
    277 }
    278 
    279 
    280 TEST(StandAlonePreParser) {
    281   v8::V8::Initialize();
    282 
    283   int marker;
    284   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    285       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    286 
    287   const char* programs[] = {
    288       "{label: 42}",
    289       "var x = 42;",
    290       "function foo(x, y) { return x + y; }",
    291       "%ArgleBargle(glop);",
    292       "var x = new new Function('this.x = 42');",
    293       NULL
    294   };
    295 
    296   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    297   for (int i = 0; programs[i]; i++) {
    298     const char* program = programs[i];
    299     i::Utf8ToUtf16CharacterStream stream(
    300         reinterpret_cast<const i::byte*>(program),
    301         static_cast<unsigned>(strlen(program)));
    302     i::CompleteParserRecorder log;
    303     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    304     scanner.Initialize(&stream);
    305 
    306     i::PreParser preparser(&scanner, &log, stack_limit);
    307     preparser.set_allow_lazy(true);
    308     preparser.set_allow_natives_syntax(true);
    309     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    310     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    311     i::ScriptData data(log.ExtractData());
    312     CHECK(!data.has_error());
    313   }
    314 }
    315 
    316 
    317 TEST(StandAlonePreParserNoNatives) {
    318   v8::V8::Initialize();
    319 
    320   int marker;
    321   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    322       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    323 
    324   const char* programs[] = {
    325       "%ArgleBargle(glop);",
    326       "var x = %_IsSmi(42);",
    327       NULL
    328   };
    329 
    330   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    331   for (int i = 0; programs[i]; i++) {
    332     const char* program = programs[i];
    333     i::Utf8ToUtf16CharacterStream stream(
    334         reinterpret_cast<const i::byte*>(program),
    335         static_cast<unsigned>(strlen(program)));
    336     i::CompleteParserRecorder log;
    337     i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    338     scanner.Initialize(&stream);
    339 
    340     // Preparser defaults to disallowing natives syntax.
    341     i::PreParser preparser(&scanner, &log, stack_limit);
    342     preparser.set_allow_lazy(true);
    343     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    344     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    345     i::ScriptData data(log.ExtractData());
    346     // Data contains syntax error.
    347     CHECK(data.has_error());
    348   }
    349 }
    350 
    351 
    352 TEST(PreparsingObjectLiterals) {
    353   // Regression test for a bug where the symbol stream produced by PreParser
    354   // didn't match what Parser wanted to consume.
    355   v8::Isolate* isolate = CcTest::isolate();
    356   v8::HandleScope handles(isolate);
    357   v8::Local<v8::Context> context = v8::Context::New(isolate);
    358   v8::Context::Scope context_scope(context);
    359   int marker;
    360   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    361       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    362 
    363   {
    364     const char* source = "var myo = {if: \"foo\"}; myo.if;";
    365     v8::Local<v8::Value> result = PreCompileCompileRun(source);
    366     CHECK(result->IsString());
    367     v8::String::Utf8Value utf8(result);
    368     CHECK_EQ("foo", *utf8);
    369   }
    370 
    371   {
    372     const char* source = "var myo = {\"bar\": \"foo\"}; myo[\"bar\"];";
    373     v8::Local<v8::Value> result = PreCompileCompileRun(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 = {1: \"foo\"}; myo[1];";
    381     v8::Local<v8::Value> result = PreCompileCompileRun(source);
    382     CHECK(result->IsString());
    383     v8::String::Utf8Value utf8(result);
    384     CHECK_EQ("foo", *utf8);
    385   }
    386 }
    387 
    388 
    389 TEST(RegressChromium62639) {
    390   v8::V8::Initialize();
    391   i::Isolate* isolate = CcTest::i_isolate();
    392 
    393   int marker;
    394   isolate->stack_guard()->SetStackLimit(
    395       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    396 
    397   const char* program = "var x = 'something';\n"
    398                         "escape: function() {}";
    399   // Fails parsing expecting an identifier after "function".
    400   // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
    401   // and then used the invalid currently scanned literal. This always
    402   // failed in debug mode, and sometimes crashed in release mode.
    403 
    404   i::Utf8ToUtf16CharacterStream stream(
    405       reinterpret_cast<const i::byte*>(program),
    406       static_cast<unsigned>(strlen(program)));
    407   i::CompleteParserRecorder log;
    408   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    409   scanner.Initialize(&stream);
    410   i::PreParser preparser(&scanner, &log,
    411                          CcTest::i_isolate()->stack_guard()->real_climit());
    412   preparser.set_allow_lazy(true);
    413   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    414   // Even in the case of a syntax error, kPreParseSuccess is returned.
    415   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    416   i::ScriptData data(log.ExtractData());
    417   CHECK(data.has_error());
    418 }
    419 
    420 
    421 TEST(Regress928) {
    422   v8::V8::Initialize();
    423   i::Isolate* isolate = CcTest::i_isolate();
    424   i::Factory* factory = isolate->factory();
    425 
    426   // Preparsing didn't consider the catch clause of a try statement
    427   // as with-content, which made it assume that a function inside
    428   // the block could be lazily compiled, and an extra, unexpected,
    429   // entry was added to the data.
    430   int marker;
    431   isolate->stack_guard()->SetStackLimit(
    432       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    433 
    434   const char* program =
    435       "try { } catch (e) { var foo = function () { /* first */ } }"
    436       "var bar = function () { /* second */ }";
    437 
    438   v8::HandleScope handles(CcTest::isolate());
    439   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(program);
    440   i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
    441   i::CompleteParserRecorder log;
    442   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    443   scanner.Initialize(&stream);
    444   i::PreParser preparser(&scanner, &log,
    445                          CcTest::i_isolate()->stack_guard()->real_climit());
    446   preparser.set_allow_lazy(true);
    447   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    448   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    449   i::ScriptData data(log.ExtractData());
    450   CHECK(!data.has_error());
    451   data.Initialize();
    452 
    453   int first_function =
    454       static_cast<int>(strstr(program, "function") - program);
    455   int first_lbrace = first_function + i::StrLength("function () ");
    456   CHECK_EQ('{', program[first_lbrace]);
    457   i::FunctionEntry entry1 = data.GetFunctionEntry(first_lbrace);
    458   CHECK(!entry1.is_valid());
    459 
    460   int second_function =
    461       static_cast<int>(strstr(program + first_lbrace, "function") - program);
    462   int second_lbrace =
    463       second_function + i::StrLength("function () ");
    464   CHECK_EQ('{', program[second_lbrace]);
    465   i::FunctionEntry entry2 = data.GetFunctionEntry(second_lbrace);
    466   CHECK(entry2.is_valid());
    467   CHECK_EQ('}', program[entry2.end_pos() - 1]);
    468 }
    469 
    470 
    471 TEST(PreParseOverflow) {
    472   v8::V8::Initialize();
    473 
    474   int marker;
    475   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    476       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
    477 
    478   size_t kProgramSize = 1024 * 1024;
    479   i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1));
    480   memset(program.get(), '(', kProgramSize);
    481   program[kProgramSize] = '\0';
    482 
    483   uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
    484 
    485   i::Utf8ToUtf16CharacterStream stream(
    486       reinterpret_cast<const i::byte*>(program.get()),
    487       static_cast<unsigned>(kProgramSize));
    488   i::CompleteParserRecorder log;
    489   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    490   scanner.Initialize(&stream);
    491 
    492   i::PreParser preparser(&scanner, &log, stack_limit);
    493   preparser.set_allow_lazy(true);
    494   i::PreParser::PreParseResult result = preparser.PreParseProgram();
    495   CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
    496 }
    497 
    498 
    499 class TestExternalResource: public v8::String::ExternalStringResource {
    500  public:
    501   explicit TestExternalResource(uint16_t* data, int length)
    502       : data_(data), length_(static_cast<size_t>(length)) { }
    503 
    504   ~TestExternalResource() { }
    505 
    506   const uint16_t* data() const {
    507     return data_;
    508   }
    509 
    510   size_t length() const {
    511     return length_;
    512   }
    513  private:
    514   uint16_t* data_;
    515   size_t length_;
    516 };
    517 
    518 
    519 #define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
    520 
    521 void TestCharacterStream(const char* ascii_source,
    522                          unsigned length,
    523                          unsigned start = 0,
    524                          unsigned end = 0) {
    525   if (end == 0) end = length;
    526   unsigned sub_length = end - start;
    527   i::Isolate* isolate = CcTest::i_isolate();
    528   i::Factory* factory = isolate->factory();
    529   i::HandleScope test_scope(isolate);
    530   i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
    531   for (unsigned i = 0; i < length; i++) {
    532     uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]);
    533   }
    534   i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length));
    535   i::Handle<i::String> ascii_string =
    536       factory->NewStringFromAscii(ascii_vector).ToHandleChecked();
    537   TestExternalResource resource(uc16_buffer.get(), length);
    538   i::Handle<i::String> uc16_string(
    539       factory->NewExternalStringFromTwoByte(&resource).ToHandleChecked());
    540 
    541   i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
    542       i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
    543   i::GenericStringUtf16CharacterStream string_stream(ascii_string, start, end);
    544   i::Utf8ToUtf16CharacterStream utf8_stream(
    545       reinterpret_cast<const i::byte*>(ascii_source), end);
    546   utf8_stream.SeekForward(start);
    547 
    548   unsigned i = start;
    549   while (i < end) {
    550     // Read streams one char at a time
    551     CHECK_EQU(i, uc16_stream.pos());
    552     CHECK_EQU(i, string_stream.pos());
    553     CHECK_EQU(i, utf8_stream.pos());
    554     int32_t c0 = ascii_source[i];
    555     int32_t c1 = uc16_stream.Advance();
    556     int32_t c2 = string_stream.Advance();
    557     int32_t c3 = utf8_stream.Advance();
    558     i++;
    559     CHECK_EQ(c0, c1);
    560     CHECK_EQ(c0, c2);
    561     CHECK_EQ(c0, c3);
    562     CHECK_EQU(i, uc16_stream.pos());
    563     CHECK_EQU(i, string_stream.pos());
    564     CHECK_EQU(i, utf8_stream.pos());
    565   }
    566   while (i > start + sub_length / 4) {
    567     // Pushback, re-read, pushback again.
    568     int32_t c0 = ascii_source[i - 1];
    569     CHECK_EQU(i, uc16_stream.pos());
    570     CHECK_EQU(i, string_stream.pos());
    571     CHECK_EQU(i, utf8_stream.pos());
    572     uc16_stream.PushBack(c0);
    573     string_stream.PushBack(c0);
    574     utf8_stream.PushBack(c0);
    575     i--;
    576     CHECK_EQU(i, uc16_stream.pos());
    577     CHECK_EQU(i, string_stream.pos());
    578     CHECK_EQU(i, utf8_stream.pos());
    579     int32_t c1 = uc16_stream.Advance();
    580     int32_t c2 = string_stream.Advance();
    581     int32_t c3 = utf8_stream.Advance();
    582     i++;
    583     CHECK_EQU(i, uc16_stream.pos());
    584     CHECK_EQU(i, string_stream.pos());
    585     CHECK_EQU(i, utf8_stream.pos());
    586     CHECK_EQ(c0, c1);
    587     CHECK_EQ(c0, c2);
    588     CHECK_EQ(c0, c3);
    589     uc16_stream.PushBack(c0);
    590     string_stream.PushBack(c0);
    591     utf8_stream.PushBack(c0);
    592     i--;
    593     CHECK_EQU(i, uc16_stream.pos());
    594     CHECK_EQU(i, string_stream.pos());
    595     CHECK_EQU(i, utf8_stream.pos());
    596   }
    597   unsigned halfway = start + sub_length / 2;
    598   uc16_stream.SeekForward(halfway - i);
    599   string_stream.SeekForward(halfway - i);
    600   utf8_stream.SeekForward(halfway - i);
    601   i = halfway;
    602   CHECK_EQU(i, uc16_stream.pos());
    603   CHECK_EQU(i, string_stream.pos());
    604   CHECK_EQU(i, utf8_stream.pos());
    605 
    606   while (i < end) {
    607     // Read streams one char at a time
    608     CHECK_EQU(i, uc16_stream.pos());
    609     CHECK_EQU(i, string_stream.pos());
    610     CHECK_EQU(i, utf8_stream.pos());
    611     int32_t c0 = ascii_source[i];
    612     int32_t c1 = uc16_stream.Advance();
    613     int32_t c2 = string_stream.Advance();
    614     int32_t c3 = utf8_stream.Advance();
    615     i++;
    616     CHECK_EQ(c0, c1);
    617     CHECK_EQ(c0, c2);
    618     CHECK_EQ(c0, c3);
    619     CHECK_EQU(i, uc16_stream.pos());
    620     CHECK_EQU(i, string_stream.pos());
    621     CHECK_EQU(i, utf8_stream.pos());
    622   }
    623 
    624   int32_t c1 = uc16_stream.Advance();
    625   int32_t c2 = string_stream.Advance();
    626   int32_t c3 = utf8_stream.Advance();
    627   CHECK_LT(c1, 0);
    628   CHECK_LT(c2, 0);
    629   CHECK_LT(c3, 0);
    630 }
    631 
    632 
    633 TEST(CharacterStreams) {
    634   v8::Isolate* isolate = CcTest::isolate();
    635   v8::HandleScope handles(isolate);
    636   v8::Local<v8::Context> context = v8::Context::New(isolate);
    637   v8::Context::Scope context_scope(context);
    638 
    639   TestCharacterStream("abc\0\n\r\x7f", 7);
    640   static const unsigned kBigStringSize = 4096;
    641   char buffer[kBigStringSize + 1];
    642   for (unsigned i = 0; i < kBigStringSize; i++) {
    643     buffer[i] = static_cast<char>(i & 0x7f);
    644   }
    645   TestCharacterStream(buffer, kBigStringSize);
    646 
    647   TestCharacterStream(buffer, kBigStringSize, 576, 3298);
    648 
    649   TestCharacterStream("\0", 1);
    650   TestCharacterStream("", 0);
    651 }
    652 
    653 
    654 TEST(Utf8CharacterStream) {
    655   static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar;
    656   static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU);
    657 
    658   static const int kAllUtf8CharsSize =
    659       (unibrow::Utf8::kMaxOneByteChar + 1) +
    660       (unibrow::Utf8::kMaxTwoByteChar - unibrow::Utf8::kMaxOneByteChar) * 2 +
    661       (unibrow::Utf8::kMaxThreeByteChar - unibrow::Utf8::kMaxTwoByteChar) * 3;
    662   static const unsigned kAllUtf8CharsSizeU =
    663       static_cast<unsigned>(kAllUtf8CharsSize);
    664 
    665   char buffer[kAllUtf8CharsSizeU];
    666   unsigned cursor = 0;
    667   for (int i = 0; i <= kMaxUC16Char; i++) {
    668     cursor += unibrow::Utf8::Encode(buffer + cursor,
    669                                     i,
    670                                     unibrow::Utf16::kNoPreviousCharacter);
    671   }
    672   ASSERT(cursor == kAllUtf8CharsSizeU);
    673 
    674   i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
    675                                        kAllUtf8CharsSizeU);
    676   for (int i = 0; i <= kMaxUC16Char; i++) {
    677     CHECK_EQU(i, stream.pos());
    678     int32_t c = stream.Advance();
    679     CHECK_EQ(i, c);
    680     CHECK_EQU(i + 1, stream.pos());
    681   }
    682   for (int i = kMaxUC16Char; i >= 0; i--) {
    683     CHECK_EQU(i + 1, stream.pos());
    684     stream.PushBack(i);
    685     CHECK_EQU(i, stream.pos());
    686   }
    687   int i = 0;
    688   while (stream.pos() < kMaxUC16CharU) {
    689     CHECK_EQU(i, stream.pos());
    690     unsigned progress = stream.SeekForward(12);
    691     i += progress;
    692     int32_t c = stream.Advance();
    693     if (i <= kMaxUC16Char) {
    694       CHECK_EQ(i, c);
    695     } else {
    696       CHECK_EQ(-1, c);
    697     }
    698     i += 1;
    699     CHECK_EQU(i, stream.pos());
    700   }
    701 }
    702 
    703 #undef CHECK_EQU
    704 
    705 void TestStreamScanner(i::Utf16CharacterStream* stream,
    706                        i::Token::Value* expected_tokens,
    707                        int skip_pos = 0,  // Zero means not skipping.
    708                        int skip_to = 0) {
    709   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    710   scanner.Initialize(stream);
    711 
    712   int i = 0;
    713   do {
    714     i::Token::Value expected = expected_tokens[i];
    715     i::Token::Value actual = scanner.Next();
    716     CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
    717     if (scanner.location().end_pos == skip_pos) {
    718       scanner.SeekForward(skip_to);
    719     }
    720     i++;
    721   } while (expected_tokens[i] != i::Token::ILLEGAL);
    722 }
    723 
    724 
    725 TEST(StreamScanner) {
    726   v8::V8::Initialize();
    727 
    728   const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
    729   i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
    730                                         static_cast<unsigned>(strlen(str1)));
    731   i::Token::Value expectations1[] = {
    732       i::Token::LBRACE,
    733       i::Token::IDENTIFIER,
    734       i::Token::IDENTIFIER,
    735       i::Token::FOR,
    736       i::Token::COLON,
    737       i::Token::MUL,
    738       i::Token::DIV,
    739       i::Token::LT,
    740       i::Token::SUB,
    741       i::Token::IDENTIFIER,
    742       i::Token::EOS,
    743       i::Token::ILLEGAL
    744   };
    745   TestStreamScanner(&stream1, expectations1, 0, 0);
    746 
    747   const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
    748   i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
    749                                         static_cast<unsigned>(strlen(str2)));
    750   i::Token::Value expectations2[] = {
    751       i::Token::CASE,
    752       i::Token::DEFAULT,
    753       i::Token::CONST,
    754       i::Token::LBRACE,
    755       // Skipped part here
    756       i::Token::RBRACE,
    757       i::Token::DO,
    758       i::Token::EOS,
    759       i::Token::ILLEGAL
    760   };
    761   ASSERT_EQ('{', str2[19]);
    762   ASSERT_EQ('}', str2[37]);
    763   TestStreamScanner(&stream2, expectations2, 20, 37);
    764 
    765   const char* str3 = "{}}}}";
    766   i::Token::Value expectations3[] = {
    767       i::Token::LBRACE,
    768       i::Token::RBRACE,
    769       i::Token::RBRACE,
    770       i::Token::RBRACE,
    771       i::Token::RBRACE,
    772       i::Token::EOS,
    773       i::Token::ILLEGAL
    774   };
    775   // Skip zero-four RBRACEs.
    776   for (int i = 0; i <= 4; i++) {
    777      expectations3[6 - i] = i::Token::ILLEGAL;
    778      expectations3[5 - i] = i::Token::EOS;
    779      i::Utf8ToUtf16CharacterStream stream3(
    780          reinterpret_cast<const i::byte*>(str3),
    781          static_cast<unsigned>(strlen(str3)));
    782      TestStreamScanner(&stream3, expectations3, 1, 1 + i);
    783   }
    784 }
    785 
    786 
    787 void TestScanRegExp(const char* re_source, const char* expected) {
    788   i::Utf8ToUtf16CharacterStream stream(
    789        reinterpret_cast<const i::byte*>(re_source),
    790        static_cast<unsigned>(strlen(re_source)));
    791   i::HandleScope scope(CcTest::i_isolate());
    792   i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
    793   scanner.Initialize(&stream);
    794 
    795   i::Token::Value start = scanner.peek();
    796   CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
    797   CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
    798   scanner.Next();  // Current token is now the regexp literal.
    799   i::Handle<i::String> val =
    800       scanner.AllocateInternalizedString(CcTest::i_isolate());
    801   i::DisallowHeapAllocation no_alloc;
    802   i::String::FlatContent content = val->GetFlatContent();
    803   CHECK(content.IsAscii());
    804   i::Vector<const uint8_t> actual = content.ToOneByteVector();
    805   for (int i = 0; i < actual.length(); i++) {
    806     CHECK_NE('\0', expected[i]);
    807     CHECK_EQ(expected[i], actual[i]);
    808   }
    809 }
    810 
    811 
    812 TEST(RegExpScanning) {
    813   v8::V8::Initialize();
    814 
    815   // RegExp token with added garbage at the end. The scanner should only
    816   // scan the RegExp until the terminating slash just before "flipperwald".
    817   TestScanRegExp("/b/flipperwald", "b");
    818   // Incomplete escape sequences doesn't hide the terminating slash.
    819   TestScanRegExp("/\\x/flipperwald", "\\x");
    820   TestScanRegExp("/\\u/flipperwald", "\\u");
    821   TestScanRegExp("/\\u1/flipperwald", "\\u1");
    822   TestScanRegExp("/\\u12/flipperwald", "\\u12");
    823   TestScanRegExp("/\\u123/flipperwald", "\\u123");
    824   TestScanRegExp("/\\c/flipperwald", "\\c");
    825   TestScanRegExp("/\\c//flipperwald", "\\c");
    826   // Slashes inside character classes are not terminating.
    827   TestScanRegExp("/[/]/flipperwald", "[/]");
    828   TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
    829   // Incomplete escape sequences inside a character class doesn't hide
    830   // the end of the character class.
    831   TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
    832   TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
    833   TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
    834   TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
    835   TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
    836   TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
    837   TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
    838   TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
    839   // Escaped ']'s wont end the character class.
    840   TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
    841   // Escaped slashes are not terminating.
    842   TestScanRegExp("/\\//flipperwald", "\\/");
    843   // Starting with '=' works too.
    844   TestScanRegExp("/=/", "=");
    845   TestScanRegExp("/=?/", "=?");
    846 }
    847 
    848 
    849 static int Utf8LengthHelper(const char* s) {
    850   int len = i::StrLength(s);
    851   int character_length = len;
    852   for (int i = 0; i < len; i++) {
    853     unsigned char c = s[i];
    854     int input_offset = 0;
    855     int output_adjust = 0;
    856     if (c > 0x7f) {
    857       if (c < 0xc0) continue;
    858       if (c >= 0xf0) {
    859         if (c >= 0xf8) {
    860           // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
    861           // byte.
    862           continue;  // Handle first UTF-8 byte.
    863         }
    864         if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
    865           // This 4 byte sequence could have been coded as a 3 byte sequence.
    866           // Record a single kBadChar for the first byte and continue.
    867           continue;
    868         }
    869         input_offset = 3;
    870         // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
    871         character_length -= 2;
    872       } else if (c >= 0xe0) {
    873         if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
    874           // This 3 byte sequence could have been coded as a 2 byte sequence.
    875           // Record a single kBadChar for the first byte and continue.
    876           continue;
    877         }
    878         input_offset = 2;
    879         // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
    880         output_adjust = 2;
    881       } else {
    882         if ((c & 0x1e) == 0) {
    883           // This 2 byte sequence could have been coded as a 1 byte sequence.
    884           // Record a single kBadChar for the first byte and continue.
    885           continue;
    886         }
    887         input_offset = 1;
    888         // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
    889         output_adjust = 1;
    890       }
    891       bool bad = false;
    892       for (int j = 1; j <= input_offset; j++) {
    893         if ((s[i + j] & 0xc0) != 0x80) {
    894           // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
    895           // which is a single UTF-16 code unit.
    896           bad = true;
    897           break;
    898         }
    899       }
    900       if (!bad) {
    901         i += input_offset;
    902         character_length -= output_adjust;
    903       }
    904     }
    905   }
    906   return character_length;
    907 }
    908 
    909 
    910 TEST(ScopePositions) {
    911   v8::internal::FLAG_harmony_scoping = true;
    912 
    913   // Test the parser for correctly setting the start and end positions
    914   // of a scope. We check the scope positions of exactly one scope
    915   // nested in the global scope of a program. 'inner source' is the
    916   // source code that determines the part of the source belonging
    917   // to the nested scope. 'outer_prefix' and 'outer_suffix' are
    918   // parts of the source that belong to the global scope.
    919   struct SourceData {
    920     const char* outer_prefix;
    921     const char* inner_source;
    922     const char* outer_suffix;
    923     i::ScopeType scope_type;
    924     i::StrictMode strict_mode;
    925   };
    926 
    927   const SourceData source_data[] = {
    928     { "  with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::SLOPPY },
    929     { "  with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::SLOPPY },
    930     { "  with ({}) ", "{\n"
    931       "    block;\n"
    932       "  }", "\n"
    933       "  more;", i::WITH_SCOPE, i::SLOPPY },
    934     { "  with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::SLOPPY },
    935     { "  with ({}) ", "statement", "\n"
    936       "  more;", i::WITH_SCOPE, i::SLOPPY },
    937     { "  with ({})\n"
    938       "    ", "statement;", "\n"
    939       "  more;", i::WITH_SCOPE, i::SLOPPY },
    940     { "  try {} catch ", "(e) { block; }", " more;",
    941       i::CATCH_SCOPE, i::SLOPPY },
    942     { "  try {} catch ", "(e) { block; }", "; more;",
    943       i::CATCH_SCOPE, i::SLOPPY },
    944     { "  try {} catch ", "(e) {\n"
    945       "    block;\n"
    946       "  }", "\n"
    947       "  more;", i::CATCH_SCOPE, i::SLOPPY },
    948     { "  try {} catch ", "(e) { block; }", " finally { block; } more;",
    949       i::CATCH_SCOPE, i::SLOPPY },
    950     { "  start;\n"
    951       "  ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::STRICT },
    952     { "  start;\n"
    953       "  ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::STRICT },
    954     { "  start;\n"
    955       "  ", "{\n"
    956       "    let block;\n"
    957       "  }", "\n"
    958       "  more;", i::BLOCK_SCOPE, i::STRICT },
    959     { "  start;\n"
    960       "  function fun", "(a,b) { infunction; }", " more;",
    961       i::FUNCTION_SCOPE, i::SLOPPY },
    962     { "  start;\n"
    963       "  function fun", "(a,b) {\n"
    964       "    infunction;\n"
    965       "  }", "\n"
    966       "  more;", i::FUNCTION_SCOPE, i::SLOPPY },
    967     { "  (function fun", "(a,b) { infunction; }", ")();",
    968       i::FUNCTION_SCOPE, i::SLOPPY },
    969     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
    970       i::BLOCK_SCOPE, i::STRICT },
    971     { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
    972       i::BLOCK_SCOPE, i::STRICT },
    973     { "  for ", "(let x = 1 ; x < 10; ++ x) {\n"
    974       "    block;\n"
    975       "  }", "\n"
    976       "  more;", i::BLOCK_SCOPE, i::STRICT },
    977     { "  for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
    978       i::BLOCK_SCOPE, i::STRICT },
    979     { "  for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
    980       "  more;", i::BLOCK_SCOPE, i::STRICT },
    981     { "  for ", "(let x = 1 ; x < 10; ++ x)\n"
    982       "    statement;", "\n"
    983       "  more;", i::BLOCK_SCOPE, i::STRICT },
    984     { "  for ", "(let x in {}) { block; }", " more;",
    985       i::BLOCK_SCOPE, i::STRICT },
    986     { "  for ", "(let x in {}) { block; }", "; more;",
    987       i::BLOCK_SCOPE, i::STRICT },
    988     { "  for ", "(let x in {}) {\n"
    989       "    block;\n"
    990       "  }", "\n"
    991       "  more;", i::BLOCK_SCOPE, i::STRICT },
    992     { "  for ", "(let x in {}) statement;", " more;",
    993       i::BLOCK_SCOPE, i::STRICT },
    994     { "  for ", "(let x in {}) statement", "\n"
    995       "  more;", i::BLOCK_SCOPE, i::STRICT },
    996     { "  for ", "(let x in {})\n"
    997       "    statement;", "\n"
    998       "  more;", i::BLOCK_SCOPE, i::STRICT },
    999     // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
   1000     // the preparser off in terms of byte offsets.
   1001     // 6 byte encoding.
   1002     { "  'foo\355\240\201\355\260\211';\n"
   1003       "  (function fun", "(a,b) { infunction; }", ")();",
   1004       i::FUNCTION_SCOPE, i::SLOPPY },
   1005     // 4 byte encoding.
   1006     { "  'foo\360\220\220\212';\n"
   1007       "  (function fun", "(a,b) { infunction; }", ")();",
   1008       i::FUNCTION_SCOPE, i::SLOPPY },
   1009     // 3 byte encoding of \u0fff.
   1010     { "  'foo\340\277\277';\n"
   1011       "  (function fun", "(a,b) { infunction; }", ")();",
   1012       i::FUNCTION_SCOPE, i::SLOPPY },
   1013     // Broken 6 byte encoding with missing last byte.
   1014     { "  'foo\355\240\201\355\211';\n"
   1015       "  (function fun", "(a,b) { infunction; }", ")();",
   1016       i::FUNCTION_SCOPE, i::SLOPPY },
   1017     // Broken 3 byte encoding of \u0fff with missing last byte.
   1018     { "  'foo\340\277';\n"
   1019       "  (function fun", "(a,b) { infunction; }", ")();",
   1020       i::FUNCTION_SCOPE, i::SLOPPY },
   1021     // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
   1022     { "  'foo\340';\n"
   1023       "  (function fun", "(a,b) { infunction; }", ")();",
   1024       i::FUNCTION_SCOPE, i::SLOPPY },
   1025     // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
   1026     { "  'foo\340\203\277';\n"
   1027       "  (function fun", "(a,b) { infunction; }", ")();",
   1028       i::FUNCTION_SCOPE, i::SLOPPY },
   1029     // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
   1030     { "  'foo\340\201\277';\n"
   1031       "  (function fun", "(a,b) { infunction; }", ")();",
   1032       i::FUNCTION_SCOPE, i::SLOPPY },
   1033     // Unpaired lead surrogate.
   1034     { "  'foo\355\240\201';\n"
   1035       "  (function fun", "(a,b) { infunction; }", ")();",
   1036       i::FUNCTION_SCOPE, i::SLOPPY },
   1037     // Unpaired lead surrogate where following code point is a 3 byte sequence.
   1038     { "  'foo\355\240\201\340\277\277';\n"
   1039       "  (function fun", "(a,b) { infunction; }", ")();",
   1040       i::FUNCTION_SCOPE, i::SLOPPY },
   1041     // Unpaired lead surrogate where following code point is a 4 byte encoding
   1042     // of a trail surrogate.
   1043     { "  'foo\355\240\201\360\215\260\211';\n"
   1044       "  (function fun", "(a,b) { infunction; }", ")();",
   1045       i::FUNCTION_SCOPE, i::SLOPPY },
   1046     // Unpaired trail surrogate.
   1047     { "  'foo\355\260\211';\n"
   1048       "  (function fun", "(a,b) { infunction; }", ")();",
   1049       i::FUNCTION_SCOPE, i::SLOPPY },
   1050     // 2 byte encoding of \u00ff.
   1051     { "  'foo\303\277';\n"
   1052       "  (function fun", "(a,b) { infunction; }", ")();",
   1053       i::FUNCTION_SCOPE, i::SLOPPY },
   1054     // Broken 2 byte encoding of \u00ff with missing last byte.
   1055     { "  'foo\303';\n"
   1056       "  (function fun", "(a,b) { infunction; }", ")();",
   1057       i::FUNCTION_SCOPE, i::SLOPPY },
   1058     // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
   1059     { "  'foo\301\277';\n"
   1060       "  (function fun", "(a,b) { infunction; }", ")();",
   1061       i::FUNCTION_SCOPE, i::SLOPPY },
   1062     // Illegal 5 byte encoding.
   1063     { "  'foo\370\277\277\277\277';\n"
   1064       "  (function fun", "(a,b) { infunction; }", ")();",
   1065       i::FUNCTION_SCOPE, i::SLOPPY },
   1066     // Illegal 6 byte encoding.
   1067     { "  'foo\374\277\277\277\277\277';\n"
   1068       "  (function fun", "(a,b) { infunction; }", ")();",
   1069       i::FUNCTION_SCOPE, i::SLOPPY },
   1070     // Illegal 0xfe byte
   1071     { "  'foo\376\277\277\277\277\277\277';\n"
   1072       "  (function fun", "(a,b) { infunction; }", ")();",
   1073       i::FUNCTION_SCOPE, i::SLOPPY },
   1074     // Illegal 0xff byte
   1075     { "  'foo\377\277\277\277\277\277\277\277';\n"
   1076       "  (function fun", "(a,b) { infunction; }", ")();",
   1077       i::FUNCTION_SCOPE, i::SLOPPY },
   1078     { "  'foo';\n"
   1079       "  (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
   1080       i::FUNCTION_SCOPE, i::SLOPPY },
   1081     { "  'foo';\n"
   1082       "  (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
   1083       i::FUNCTION_SCOPE, i::SLOPPY },
   1084     { NULL, NULL, NULL, i::EVAL_SCOPE, i::SLOPPY }
   1085   };
   1086 
   1087   i::Isolate* isolate = CcTest::i_isolate();
   1088   i::Factory* factory = isolate->factory();
   1089 
   1090   v8::HandleScope handles(CcTest::isolate());
   1091   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1092   v8::Context::Scope context_scope(context);
   1093 
   1094   int marker;
   1095   isolate->stack_guard()->SetStackLimit(
   1096       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
   1097 
   1098   for (int i = 0; source_data[i].outer_prefix; i++) {
   1099     int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
   1100     int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
   1101     int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
   1102     int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
   1103     int kInnerByteLen = i::StrLength(source_data[i].inner_source);
   1104     int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
   1105     int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
   1106     int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
   1107     i::ScopedVector<char> program(kProgramByteSize + 1);
   1108     i::SNPrintF(program, "%s%s%s",
   1109                          source_data[i].outer_prefix,
   1110                          source_data[i].inner_source,
   1111                          source_data[i].outer_suffix);
   1112 
   1113     // Parse program source.
   1114     i::Handle<i::String> source = factory->NewStringFromUtf8(
   1115         i::CStrVector(program.start())).ToHandleChecked();
   1116     CHECK_EQ(source->length(), kProgramSize);
   1117     i::Handle<i::Script> script = factory->NewScript(source);
   1118     i::CompilationInfoWithZone info(script);
   1119     i::Parser parser(&info);
   1120     parser.set_allow_lazy(true);
   1121     parser.set_allow_harmony_scoping(true);
   1122     info.MarkAsGlobal();
   1123     info.SetStrictMode(source_data[i].strict_mode);
   1124     parser.Parse();
   1125     CHECK(info.function() != NULL);
   1126 
   1127     // Check scope types and positions.
   1128     i::Scope* scope = info.function()->scope();
   1129     CHECK(scope->is_global_scope());
   1130     CHECK_EQ(scope->start_position(), 0);
   1131     CHECK_EQ(scope->end_position(), kProgramSize);
   1132     CHECK_EQ(scope->inner_scopes()->length(), 1);
   1133 
   1134     i::Scope* inner_scope = scope->inner_scopes()->at(0);
   1135     CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type);
   1136     CHECK_EQ(inner_scope->start_position(), kPrefixLen);
   1137     // The end position of a token is one position after the last
   1138     // character belonging to that token.
   1139     CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
   1140   }
   1141 }
   1142 
   1143 
   1144 i::Handle<i::String> FormatMessage(i::ScriptData* data) {
   1145   i::Isolate* isolate = CcTest::i_isolate();
   1146   i::Factory* factory = isolate->factory();
   1147   const char* message = data->BuildMessage();
   1148   i::Handle<i::String> format = v8::Utils::OpenHandle(
   1149       *v8::String::NewFromUtf8(CcTest::isolate(), message));
   1150   const char* arg = data->BuildArg();
   1151   i::Handle<i::JSArray> args_array = factory->NewJSArray(arg == NULL ? 0 : 1);
   1152   if (arg != NULL) {
   1153     i::JSArray::SetElement(
   1154         args_array, 0, v8::Utils::OpenHandle(*v8::String::NewFromUtf8(
   1155                                                   CcTest::isolate(), arg)),
   1156         NONE, i::SLOPPY).Check();
   1157   }
   1158   i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
   1159   i::Handle<i::Object> format_fun = i::Object::GetProperty(
   1160       isolate, builtins, "FormatMessage").ToHandleChecked();
   1161   i::Handle<i::Object> arg_handles[] = { format, args_array };
   1162   i::Handle<i::Object> result = i::Execution::Call(
   1163       isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
   1164   CHECK(result->IsString());
   1165   i::DeleteArray(message);
   1166   i::DeleteArray(arg);
   1167   return i::Handle<i::String>::cast(result);
   1168 }
   1169 
   1170 
   1171 enum ParserFlag {
   1172   kAllowLazy,
   1173   kAllowNativesSyntax,
   1174   kAllowHarmonyScoping,
   1175   kAllowModules,
   1176   kAllowGenerators,
   1177   kAllowForOf,
   1178   kAllowHarmonyNumericLiterals
   1179 };
   1180 
   1181 
   1182 enum ParserSyncTestResult {
   1183   kSuccessOrError,
   1184   kSuccess,
   1185   kError
   1186 };
   1187 
   1188 template <typename Traits>
   1189 void SetParserFlags(i::ParserBase<Traits>* parser,
   1190                     i::EnumSet<ParserFlag> flags) {
   1191   parser->set_allow_lazy(flags.Contains(kAllowLazy));
   1192   parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax));
   1193   parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
   1194   parser->set_allow_modules(flags.Contains(kAllowModules));
   1195   parser->set_allow_generators(flags.Contains(kAllowGenerators));
   1196   parser->set_allow_for_of(flags.Contains(kAllowForOf));
   1197   parser->set_allow_harmony_numeric_literals(
   1198       flags.Contains(kAllowHarmonyNumericLiterals));
   1199 }
   1200 
   1201 
   1202 void TestParserSyncWithFlags(i::Handle<i::String> source,
   1203                              i::EnumSet<ParserFlag> flags,
   1204                              ParserSyncTestResult result) {
   1205   i::Isolate* isolate = CcTest::i_isolate();
   1206   i::Factory* factory = isolate->factory();
   1207 
   1208   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
   1209 
   1210   // Preparse the data.
   1211   i::CompleteParserRecorder log;
   1212   {
   1213     i::Scanner scanner(isolate->unicode_cache());
   1214     i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
   1215     i::PreParser preparser(&scanner, &log, stack_limit);
   1216     SetParserFlags(&preparser, flags);
   1217     scanner.Initialize(&stream);
   1218     i::PreParser::PreParseResult result = preparser.PreParseProgram();
   1219     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
   1220   }
   1221   i::ScriptData data(log.ExtractData());
   1222 
   1223   // Parse the data
   1224   i::FunctionLiteral* function;
   1225   {
   1226     i::Handle<i::Script> script = factory->NewScript(source);
   1227     i::CompilationInfoWithZone info(script);
   1228     i::Parser parser(&info);
   1229     SetParserFlags(&parser, flags);
   1230     info.MarkAsGlobal();
   1231     parser.Parse();
   1232     function = info.function();
   1233   }
   1234 
   1235   // Check that preparsing fails iff parsing fails.
   1236   if (function == NULL) {
   1237     // Extract exception from the parser.
   1238     CHECK(isolate->has_pending_exception());
   1239     i::Handle<i::JSObject> exception_handle(
   1240         i::JSObject::cast(isolate->pending_exception()));
   1241     i::Handle<i::String> message_string =
   1242         i::Handle<i::String>::cast(i::Object::GetProperty(
   1243             isolate, exception_handle, "message").ToHandleChecked());
   1244 
   1245     if (result == kSuccess) {
   1246       i::OS::Print(
   1247           "Parser failed on:\n"
   1248           "\t%s\n"
   1249           "with error:\n"
   1250           "\t%s\n"
   1251           "However, we expected no error.",
   1252           source->ToCString().get(), message_string->ToCString().get());
   1253       CHECK(false);
   1254     }
   1255 
   1256     if (!data.has_error()) {
   1257       i::OS::Print(
   1258           "Parser failed on:\n"
   1259           "\t%s\n"
   1260           "with error:\n"
   1261           "\t%s\n"
   1262           "However, the preparser succeeded",
   1263           source->ToCString().get(), message_string->ToCString().get());
   1264       CHECK(false);
   1265     }
   1266     // Check that preparser and parser produce the same error.
   1267     i::Handle<i::String> preparser_message = FormatMessage(&data);
   1268     if (!i::String::Equals(message_string, preparser_message)) {
   1269       i::OS::Print(
   1270           "Expected parser and preparser to produce the same error on:\n"
   1271           "\t%s\n"
   1272           "However, found the following error messages\n"
   1273           "\tparser:    %s\n"
   1274           "\tpreparser: %s\n",
   1275           source->ToCString().get(),
   1276           message_string->ToCString().get(),
   1277           preparser_message->ToCString().get());
   1278       CHECK(false);
   1279     }
   1280   } else if (data.has_error()) {
   1281     i::OS::Print(
   1282         "Preparser failed on:\n"
   1283         "\t%s\n"
   1284         "with error:\n"
   1285         "\t%s\n"
   1286         "However, the parser succeeded",
   1287         source->ToCString().get(), FormatMessage(&data)->ToCString().get());
   1288     CHECK(false);
   1289   } else if (result == kError) {
   1290     i::OS::Print(
   1291         "Expected error on:\n"
   1292         "\t%s\n"
   1293         "However, parser and preparser succeeded",
   1294         source->ToCString().get());
   1295     CHECK(false);
   1296   }
   1297 }
   1298 
   1299 
   1300 void TestParserSync(const char* source,
   1301                     const ParserFlag* flag_list,
   1302                     size_t flag_list_length,
   1303                     ParserSyncTestResult result = kSuccessOrError) {
   1304   i::Handle<i::String> str =
   1305       CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
   1306   for (int bits = 0; bits < (1 << flag_list_length); bits++) {
   1307     i::EnumSet<ParserFlag> flags;
   1308     for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) {
   1309       if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]);
   1310     }
   1311     TestParserSyncWithFlags(str, flags, result);
   1312   }
   1313 }
   1314 
   1315 
   1316 TEST(ParserSync) {
   1317   const char* context_data[][2] = {
   1318     { "", "" },
   1319     { "{", "}" },
   1320     { "if (true) ", " else {}" },
   1321     { "if (true) {} else ", "" },
   1322     { "if (true) ", "" },
   1323     { "do ", " while (false)" },
   1324     { "while (false) ", "" },
   1325     { "for (;;) ", "" },
   1326     { "with ({})", "" },
   1327     { "switch (12) { case 12: ", "}" },
   1328     { "switch (12) { default: ", "}" },
   1329     { "switch (12) { ", "case 12: }" },
   1330     { "label2: ", "" },
   1331     { NULL, NULL }
   1332   };
   1333 
   1334   const char* statement_data[] = {
   1335     "{}",
   1336     "var x",
   1337     "var x = 1",
   1338     "const x",
   1339     "const x = 1",
   1340     ";",
   1341     "12",
   1342     "if (false) {} else ;",
   1343     "if (false) {} else {}",
   1344     "if (false) {} else 12",
   1345     "if (false) ;"
   1346     "if (false) {}",
   1347     "if (false) 12",
   1348     "do {} while (false)",
   1349     "for (;;) ;",
   1350     "for (;;) {}",
   1351     "for (;;) 12",
   1352     "continue",
   1353     "continue label",
   1354     "continue\nlabel",
   1355     "break",
   1356     "break label",
   1357     "break\nlabel",
   1358     // TODO(marja): activate once parsing 'return' is merged into ParserBase.
   1359     // "return",
   1360     // "return  12",
   1361     // "return\n12",
   1362     "with ({}) ;",
   1363     "with ({}) {}",
   1364     "with ({}) 12",
   1365     "switch ({}) { default: }"
   1366     "label3: "
   1367     "throw",
   1368     "throw  12",
   1369     "throw\n12",
   1370     "try {} catch(e) {}",
   1371     "try {} finally {}",
   1372     "try {} catch(e) {} finally {}",
   1373     "debugger",
   1374     NULL
   1375   };
   1376 
   1377   const char* termination_data[] = {
   1378     "",
   1379     ";",
   1380     "\n",
   1381     ";\n",
   1382     "\n;",
   1383     NULL
   1384   };
   1385 
   1386   v8::HandleScope handles(CcTest::isolate());
   1387   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1388   v8::Context::Scope context_scope(context);
   1389 
   1390   int marker;
   1391   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1392       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
   1393 
   1394   static const ParserFlag flags1[] = {
   1395     kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
   1396     kAllowForOf
   1397   };
   1398   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1399     for (int j = 0; statement_data[j] != NULL; ++j) {
   1400       for (int k = 0; termination_data[k] != NULL; ++k) {
   1401         int kPrefixLen = i::StrLength(context_data[i][0]);
   1402         int kStatementLen = i::StrLength(statement_data[j]);
   1403         int kTerminationLen = i::StrLength(termination_data[k]);
   1404         int kSuffixLen = i::StrLength(context_data[i][1]);
   1405         int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
   1406             + kSuffixLen + i::StrLength("label: for (;;) {  }");
   1407 
   1408         // Plug the source code pieces together.
   1409         i::ScopedVector<char> program(kProgramSize + 1);
   1410         int length = i::SNPrintF(program,
   1411             "label: for (;;) { %s%s%s%s }",
   1412             context_data[i][0],
   1413             statement_data[j],
   1414             termination_data[k],
   1415             context_data[i][1]);
   1416         CHECK(length == kProgramSize);
   1417         TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1));
   1418       }
   1419     }
   1420   }
   1421 
   1422   // Neither Harmony numeric literals nor our natives syntax have any
   1423   // interaction with the flags above, so test these separately to reduce
   1424   // the combinatorial explosion.
   1425   static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals };
   1426   TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2));
   1427   TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2));
   1428 
   1429   static const ParserFlag flags3[] = { kAllowNativesSyntax };
   1430   TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3));
   1431 }
   1432 
   1433 
   1434 TEST(StrictOctal) {
   1435   // Test that syntax error caused by octal literal is reported correctly as
   1436   // such (issue 2220).
   1437   v8::V8::Initialize();
   1438   v8::HandleScope scope(CcTest::isolate());
   1439   v8::Context::Scope context_scope(
   1440       v8::Context::New(CcTest::isolate()));
   1441   v8::TryCatch try_catch;
   1442   const char* script =
   1443       "\"use strict\";       \n"
   1444       "a = function() {      \n"
   1445       "  b = function() {    \n"
   1446       "    01;               \n"
   1447       "  };                  \n"
   1448       "};                    \n";
   1449   v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script));
   1450   CHECK(try_catch.HasCaught());
   1451   v8::String::Utf8Value exception(try_catch.Exception());
   1452   CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
   1453            *exception);
   1454 }
   1455 
   1456 
   1457 void RunParserSyncTest(const char* context_data[][2],
   1458                        const char* statement_data[],
   1459                        ParserSyncTestResult result,
   1460                        const ParserFlag* flags = NULL,
   1461                        int flags_len = 0) {
   1462   v8::HandleScope handles(CcTest::isolate());
   1463   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   1464   v8::Context::Scope context_scope(context);
   1465 
   1466   int marker;
   1467   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1468       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
   1469 
   1470   static const ParserFlag default_flags[] = {
   1471     kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
   1472     kAllowForOf, kAllowNativesSyntax
   1473   };
   1474   if (!flags) {
   1475     flags = default_flags;
   1476     flags_len = ARRAY_SIZE(default_flags);
   1477   }
   1478   for (int i = 0; context_data[i][0] != NULL; ++i) {
   1479     for (int j = 0; statement_data[j] != NULL; ++j) {
   1480       int kPrefixLen = i::StrLength(context_data[i][0]);
   1481       int kStatementLen = i::StrLength(statement_data[j]);
   1482       int kSuffixLen = i::StrLength(context_data[i][1]);
   1483       int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
   1484 
   1485       // Plug the source code pieces together.
   1486       i::ScopedVector<char> program(kProgramSize + 1);
   1487       int length = i::SNPrintF(program,
   1488                                "%s%s%s",
   1489                                context_data[i][0],
   1490                                statement_data[j],
   1491                                context_data[i][1]);
   1492       CHECK(length == kProgramSize);
   1493       TestParserSync(program.start(),
   1494                      flags,
   1495                      flags_len,
   1496                      result);
   1497     }
   1498   }
   1499 }
   1500 
   1501 
   1502 TEST(ErrorsEvalAndArguments) {
   1503   // Tests that both preparsing and parsing produce the right kind of errors for
   1504   // using "eval" and "arguments" as identifiers. Without the strict mode, it's
   1505   // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
   1506   // isn't.
   1507   const char* context_data[][2] = {
   1508     { "\"use strict\";", "" },
   1509     { "var eval; function test_func() {\"use strict\"; ", "}"},
   1510     { NULL, NULL }
   1511   };
   1512 
   1513   const char* statement_data[] = {
   1514     "var eval;",
   1515     "var arguments",
   1516     "var foo, eval;",
   1517     "var foo, arguments;",
   1518     "try { } catch (eval) { }",
   1519     "try { } catch (arguments) { }",
   1520     "function eval() { }",
   1521     "function arguments() { }",
   1522     "function foo(eval) { }",
   1523     "function foo(arguments) { }",
   1524     "function foo(bar, eval) { }",
   1525     "function foo(bar, arguments) { }",
   1526     "eval = 1;",
   1527     "arguments = 1;",
   1528     "var foo = eval = 1;",
   1529     "var foo = arguments = 1;",
   1530     "++eval;",
   1531     "++arguments;",
   1532     "eval++;",
   1533     "arguments++;",
   1534     NULL
   1535   };
   1536 
   1537   RunParserSyncTest(context_data, statement_data, kError);
   1538 }
   1539 
   1540 
   1541 TEST(NoErrorsEvalAndArgumentsSloppy) {
   1542   // Tests that both preparsing and parsing accept "eval" and "arguments" as
   1543   // identifiers when needed.
   1544   const char* context_data[][2] = {
   1545     { "", "" },
   1546     { "function test_func() {", "}"},
   1547     { NULL, NULL }
   1548   };
   1549 
   1550   const char* statement_data[] = {
   1551     "var eval;",
   1552     "var arguments",
   1553     "var foo, eval;",
   1554     "var foo, arguments;",
   1555     "try { } catch (eval) { }",
   1556     "try { } catch (arguments) { }",
   1557     "function eval() { }",
   1558     "function arguments() { }",
   1559     "function foo(eval) { }",
   1560     "function foo(arguments) { }",
   1561     "function foo(bar, eval) { }",
   1562     "function foo(bar, arguments) { }",
   1563     "eval = 1;",
   1564     "arguments = 1;",
   1565     "var foo = eval = 1;",
   1566     "var foo = arguments = 1;",
   1567     "++eval;",
   1568     "++arguments;",
   1569     "eval++;",
   1570     "arguments++;",
   1571     NULL
   1572   };
   1573 
   1574   RunParserSyncTest(context_data, statement_data, kSuccess);
   1575 }
   1576 
   1577 
   1578 TEST(NoErrorsEvalAndArgumentsStrict) {
   1579   const char* context_data[][2] = {
   1580     { "\"use strict\";", "" },
   1581     { "function test_func() { \"use strict\";", "}" },
   1582     { NULL, NULL }
   1583   };
   1584 
   1585   const char* statement_data[] = {
   1586     "eval;",
   1587     "arguments;",
   1588     "var foo = eval;",
   1589     "var foo = arguments;",
   1590     "var foo = { eval: 1 };",
   1591     "var foo = { arguments: 1 };",
   1592     "var foo = { }; foo.eval = {};",
   1593     "var foo = { }; foo.arguments = {};",
   1594     NULL
   1595   };
   1596 
   1597   RunParserSyncTest(context_data, statement_data, kSuccess);
   1598 }
   1599 
   1600 
   1601 TEST(ErrorsFutureStrictReservedWords) {
   1602   // Tests that both preparsing and parsing produce the right kind of errors for
   1603   // using future strict reserved words as identifiers. Without the strict mode,
   1604   // it's ok to use future strict reserved words as identifiers. With the strict
   1605   // mode, it isn't.
   1606   const char* context_data[][2] = {
   1607     { "\"use strict\";", "" },
   1608     { "function test_func() {\"use strict\"; ", "}"},
   1609     { NULL, NULL }
   1610   };
   1611 
   1612   const char* statement_data[] = {
   1613     "var interface;",
   1614     "var foo, interface;",
   1615     "try { } catch (interface) { }",
   1616     "function interface() { }",
   1617     "function foo(interface) { }",
   1618     "function foo(bar, interface) { }",
   1619     "interface = 1;",
   1620     "var foo = interface = 1;",
   1621     "++interface;",
   1622     "interface++;",
   1623     NULL
   1624   };
   1625 
   1626   RunParserSyncTest(context_data, statement_data, kError);
   1627 }
   1628 
   1629 
   1630 TEST(NoErrorsFutureStrictReservedWords) {
   1631   const char* context_data[][2] = {
   1632     { "", "" },
   1633     { "function test_func() {", "}"},
   1634     { NULL, NULL }
   1635   };
   1636 
   1637   const char* statement_data[] = {
   1638     "var interface;",
   1639     "var foo, interface;",
   1640     "try { } catch (interface) { }",
   1641     "function interface() { }",
   1642     "function foo(interface) { }",
   1643     "function foo(bar, interface) { }",
   1644     "interface = 1;",
   1645     "var foo = interface = 1;",
   1646     "++interface;",
   1647     "interface++;",
   1648     NULL
   1649   };
   1650 
   1651   RunParserSyncTest(context_data, statement_data, kSuccess);
   1652 }
   1653 
   1654 
   1655 TEST(ErrorsReservedWords) {
   1656   // Tests that both preparsing and parsing produce the right kind of errors for
   1657   // using future reserved words as identifiers. These tests don't depend on the
   1658   // strict mode.
   1659   const char* context_data[][2] = {
   1660     { "", "" },
   1661     { "\"use strict\";", "" },
   1662     { "var eval; function test_func() {", "}"},
   1663     { "var eval; function test_func() {\"use strict\"; ", "}"},
   1664     { NULL, NULL }
   1665   };
   1666 
   1667   const char* statement_data[] = {
   1668     "var super;",
   1669     "var foo, super;",
   1670     "try { } catch (super) { }",
   1671     "function super() { }",
   1672     "function foo(super) { }",
   1673     "function foo(bar, super) { }",
   1674     "super = 1;",
   1675     "var foo = super = 1;",
   1676     "++super;",
   1677     "super++;",
   1678     "function foo super",
   1679     NULL
   1680   };
   1681 
   1682   RunParserSyncTest(context_data, statement_data, kError);
   1683 }
   1684 
   1685 
   1686 TEST(NoErrorsYieldSloppy) {
   1687   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
   1688   // generator (see next test).
   1689   const char* context_data[][2] = {
   1690     { "", "" },
   1691     { "function is_not_gen() {", "}" },
   1692     { NULL, NULL }
   1693   };
   1694 
   1695   const char* statement_data[] = {
   1696     "var yield;",
   1697     "var foo, yield;",
   1698     "try { } catch (yield) { }",
   1699     "function yield() { }",
   1700     "function foo(yield) { }",
   1701     "function foo(bar, yield) { }",
   1702     "yield = 1;",
   1703     "var foo = yield = 1;",
   1704     "++yield;",
   1705     "yield++;",
   1706     NULL
   1707   };
   1708 
   1709   RunParserSyncTest(context_data, statement_data, kSuccess);
   1710 }
   1711 
   1712 
   1713 TEST(ErrorsYieldSloppyGenerator) {
   1714   const char* context_data[][2] = {
   1715     { "function * is_gen() {", "}" },
   1716     { NULL, NULL }
   1717   };
   1718 
   1719   const char* statement_data[] = {
   1720     "var yield;",
   1721     "var foo, yield;",
   1722     "try { } catch (yield) { }",
   1723     "function yield() { }",
   1724     // BUG: These should not be allowed, but they are (if kAllowGenerators is
   1725     // set)
   1726     // "function foo(yield) { }",
   1727     // "function foo(bar, yield) { }",
   1728     "yield = 1;",
   1729     "var foo = yield = 1;",
   1730     "++yield;",
   1731     "yield++;",
   1732     NULL
   1733   };
   1734 
   1735   // If generators are not allowed, the error will be produced at the '*' token,
   1736   // so this test works both with and without the kAllowGenerators flag.
   1737   RunParserSyncTest(context_data, statement_data, kError);
   1738 }
   1739 
   1740 
   1741 TEST(ErrorsYieldStrict) {
   1742   const char* context_data[][2] = {
   1743     { "\"use strict\";", "" },
   1744     { "\"use strict\"; function is_not_gen() {", "}" },
   1745     { "function test_func() {\"use strict\"; ", "}"},
   1746     { NULL, NULL }
   1747   };
   1748 
   1749   const char* statement_data[] = {
   1750     "var yield;",
   1751     "var foo, yield;",
   1752     "try { } catch (yield) { }",
   1753     "function yield() { }",
   1754     "function foo(yield) { }",
   1755     "function foo(bar, yield) { }",
   1756     "yield = 1;",
   1757     "var foo = yield = 1;",
   1758     "++yield;",
   1759     "yield++;",
   1760     NULL
   1761   };
   1762 
   1763   RunParserSyncTest(context_data, statement_data, kError);
   1764 }
   1765 
   1766 
   1767 TEST(ErrorsYield) {
   1768   const char* context_data[][2] = {
   1769     { "function * is_gen() {", "}" },
   1770     { NULL, NULL }
   1771   };
   1772 
   1773   const char* statement_data[] = {
   1774     "yield 2;",  // this is legal inside generator
   1775     "yield * 2;",  // this is legal inside generator
   1776     NULL
   1777   };
   1778 
   1779   // Here we cannot assert that there is no error, since there will be without
   1780   // the kAllowGenerators flag. However, we test that Parser and PreParser
   1781   // produce the same errors.
   1782   RunParserSyncTest(context_data, statement_data, kSuccessOrError);
   1783 }
   1784 
   1785 
   1786 TEST(ErrorsNameOfStrictFunction) {
   1787   // Tests that illegal tokens as names of a strict function produce the correct
   1788   // errors.
   1789   const char* context_data[][2] = {
   1790     { "", ""},
   1791     { "\"use strict\";", ""},
   1792     { NULL, NULL }
   1793   };
   1794 
   1795   const char* statement_data[] = {
   1796     "function eval() {\"use strict\";}",
   1797     "function arguments() {\"use strict\";}",
   1798     "function interface() {\"use strict\";}",
   1799     "function yield() {\"use strict\";}",
   1800     // Future reserved words are always illegal
   1801     "function super() { }",
   1802     "function super() {\"use strict\";}",
   1803     NULL
   1804   };
   1805 
   1806   RunParserSyncTest(context_data, statement_data, kError);
   1807 }
   1808 
   1809 
   1810 TEST(NoErrorsNameOfStrictFunction) {
   1811   const char* context_data[][2] = {
   1812     { "", ""},
   1813     { NULL, NULL }
   1814   };
   1815 
   1816   const char* statement_data[] = {
   1817     "function eval() { }",
   1818     "function arguments() { }",
   1819     "function interface() { }",
   1820     "function yield() { }",
   1821     NULL
   1822   };
   1823 
   1824   RunParserSyncTest(context_data, statement_data, kSuccess);
   1825 }
   1826 
   1827 
   1828 
   1829 TEST(ErrorsIllegalWordsAsLabelsSloppy) {
   1830   // Using future reserved words as labels is always an error.
   1831   const char* context_data[][2] = {
   1832     { "", ""},
   1833     { "function test_func() {", "}" },
   1834     { NULL, NULL }
   1835   };
   1836 
   1837   const char* statement_data[] = {
   1838     "super: while(true) { break super; }",
   1839     NULL
   1840   };
   1841 
   1842   RunParserSyncTest(context_data, statement_data, kError);
   1843 }
   1844 
   1845 
   1846 TEST(ErrorsIllegalWordsAsLabelsStrict) {
   1847   // Tests that illegal tokens as labels produce the correct errors.
   1848   const char* context_data[][2] = {
   1849     { "\"use strict\";", "" },
   1850     { "function test_func() {\"use strict\"; ", "}"},
   1851     { NULL, NULL }
   1852   };
   1853 
   1854   const char* statement_data[] = {
   1855     "super: while(true) { break super; }",
   1856     "interface: while(true) { break interface; }",
   1857     "yield: while(true) { break yield; }",
   1858     NULL
   1859   };
   1860 
   1861   RunParserSyncTest(context_data, statement_data, kError);
   1862 }
   1863 
   1864 
   1865 TEST(NoErrorsIllegalWordsAsLabels) {
   1866   // Using eval and arguments as labels is legal even in strict mode.
   1867   const char* context_data[][2] = {
   1868     { "", ""},
   1869     { "function test_func() {", "}" },
   1870     { "\"use strict\";", "" },
   1871     { "\"use strict\"; function test_func() {", "}" },
   1872     { NULL, NULL }
   1873   };
   1874 
   1875   const char* statement_data[] = {
   1876     "mylabel: while(true) { break mylabel; }",
   1877     "eval: while(true) { break eval; }",
   1878     "arguments: while(true) { break arguments; }",
   1879     NULL
   1880   };
   1881 
   1882   RunParserSyncTest(context_data, statement_data, kSuccess);
   1883 }
   1884 
   1885 
   1886 TEST(ErrorsParenthesizedLabels) {
   1887   // Parenthesized identifiers shouldn't be recognized as labels.
   1888   const char* context_data[][2] = {
   1889     { "", ""},
   1890     { "function test_func() {", "}" },
   1891     { NULL, NULL }
   1892   };
   1893 
   1894   const char* statement_data[] = {
   1895     "(mylabel): while(true) { break mylabel; }",
   1896     NULL
   1897   };
   1898 
   1899   RunParserSyncTest(context_data, statement_data, kError);
   1900 }
   1901 
   1902 
   1903 TEST(NoErrorsParenthesizedDirectivePrologue) {
   1904   // Parenthesized directive prologue shouldn't be recognized.
   1905   const char* context_data[][2] = {
   1906     { "", ""},
   1907     { NULL, NULL }
   1908   };
   1909 
   1910   const char* statement_data[] = {
   1911     "(\"use strict\"); var eval;",
   1912     NULL
   1913   };
   1914 
   1915   RunParserSyncTest(context_data, statement_data, kSuccess);
   1916 }
   1917 
   1918 
   1919 TEST(ErrorsNotAnIdentifierName) {
   1920   const char* context_data[][2] = {
   1921     { "", ""},
   1922     { "\"use strict\";", ""},
   1923     { NULL, NULL }
   1924   };
   1925 
   1926   const char* statement_data[] = {
   1927     "var foo = {}; foo.{;",
   1928     "var foo = {}; foo.};",
   1929     "var foo = {}; foo.=;",
   1930     "var foo = {}; foo.888;",
   1931     "var foo = {}; foo.-;",
   1932     "var foo = {}; foo.--;",
   1933     NULL
   1934   };
   1935 
   1936   RunParserSyncTest(context_data, statement_data, kError);
   1937 }
   1938 
   1939 
   1940 TEST(NoErrorsIdentifierNames) {
   1941   // Keywords etc. are valid as property names.
   1942   const char* context_data[][2] = {
   1943     { "", ""},
   1944     { "\"use strict\";", ""},
   1945     { NULL, NULL }
   1946   };
   1947 
   1948   const char* statement_data[] = {
   1949     "var foo = {}; foo.if;",
   1950     "var foo = {}; foo.yield;",
   1951     "var foo = {}; foo.super;",
   1952     "var foo = {}; foo.interface;",
   1953     "var foo = {}; foo.eval;",
   1954     "var foo = {}; foo.arguments;",
   1955     NULL
   1956   };
   1957 
   1958   RunParserSyncTest(context_data, statement_data, kSuccess);
   1959 }
   1960 
   1961 
   1962 TEST(DontRegressPreParserDataSizes) {
   1963   // These tests make sure that Parser doesn't start producing less "preparse
   1964   // data" (data which the embedder can cache).
   1965   v8::V8::Initialize();
   1966   v8::Isolate* isolate = CcTest::isolate();
   1967   v8::HandleScope handles(isolate);
   1968 
   1969   int marker;
   1970   CcTest::i_isolate()->stack_guard()->SetStackLimit(
   1971       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
   1972 
   1973   struct TestCase {
   1974     const char* program;
   1975     int functions;
   1976   } test_cases[] = {
   1977     // No functions.
   1978     {"var x = 42;", 0},
   1979     // Functions.
   1980     {"function foo() {}", 1}, {"function foo() {} function bar() {}", 2},
   1981     // Getter / setter functions are recorded as functions if they're on the top
   1982     // level.
   1983     {"var x = {get foo(){} };", 1},
   1984     // Functions insize lazy functions are not recorded.
   1985     {"function lazy() { function a() {} function b() {} function c() {} }", 1},
   1986     {"function lazy() { var x = {get foo(){} } }", 1},
   1987     {NULL, 0}
   1988   };
   1989 
   1990   for (int i = 0; test_cases[i].program; i++) {
   1991     const char* program = test_cases[i].program;
   1992     i::Factory* factory = CcTest::i_isolate()->factory();
   1993     i::Handle<i::String> source =
   1994         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   1995     i::Handle<i::Script> script = factory->NewScript(source);
   1996     i::CompilationInfoWithZone info(script);
   1997     i::ScriptData* data = NULL;
   1998     info.SetCachedData(&data, i::PRODUCE_CACHED_DATA);
   1999     i::Parser::Parse(&info, true);
   2000     CHECK(data);
   2001     CHECK(!data->HasError());
   2002 
   2003     if (data->function_count() != test_cases[i].functions) {
   2004       i::OS::Print(
   2005           "Expected preparse data for program:\n"
   2006           "\t%s\n"
   2007           "to contain %d functions, however, received %d functions.\n",
   2008           program, test_cases[i].functions,
   2009           data->function_count());
   2010       CHECK(false);
   2011     }
   2012     delete data;
   2013   }
   2014 }
   2015 
   2016 
   2017 TEST(FunctionDeclaresItselfStrict) {
   2018   // Tests that we produce the right kinds of errors when a function declares
   2019   // itself strict (we cannot produce there errors as soon as we see the
   2020   // offending identifiers, because we don't know at that point whether the
   2021   // function is strict or not).
   2022   const char* context_data[][2] = {
   2023     {"function eval() {", "}"},
   2024     {"function arguments() {", "}"},
   2025     {"function yield() {", "}"},
   2026     {"function interface() {", "}"},
   2027     {"function foo(eval) {", "}"},
   2028     {"function foo(arguments) {", "}"},
   2029     {"function foo(yield) {", "}"},
   2030     {"function foo(interface) {", "}"},
   2031     {"function foo(bar, eval) {", "}"},
   2032     {"function foo(bar, arguments) {", "}"},
   2033     {"function foo(bar, yield) {", "}"},
   2034     {"function foo(bar, interface) {", "}"},
   2035     {"function foo(bar, bar) {", "}"},
   2036     { NULL, NULL }
   2037   };
   2038 
   2039   const char* strict_statement_data[] = {
   2040     "\"use strict\";",
   2041     NULL
   2042   };
   2043 
   2044   const char* non_strict_statement_data[] = {
   2045     ";",
   2046     NULL
   2047   };
   2048 
   2049   RunParserSyncTest(context_data, strict_statement_data, kError);
   2050   RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
   2051 }
   2052 
   2053 
   2054 TEST(ErrorsTryWithoutCatchOrFinally) {
   2055   const char* context_data[][2] = {
   2056     {"", ""},
   2057     { NULL, NULL }
   2058   };
   2059 
   2060   const char* statement_data[] = {
   2061     "try { }",
   2062     "try { } foo();",
   2063     "try { } catch (e) foo();",
   2064     "try { } catch { }",
   2065     "try { } finally foo();",
   2066     NULL
   2067   };
   2068 
   2069   RunParserSyncTest(context_data, statement_data, kError);
   2070 }
   2071 
   2072 
   2073 TEST(NoErrorsTryCatchFinally) {
   2074   const char* context_data[][2] = {
   2075     {"", ""},
   2076     { NULL, NULL }
   2077   };
   2078 
   2079   const char* statement_data[] = {
   2080     "try { } catch (e) { }",
   2081     "try { } catch (e) { } finally { }",
   2082     "try { } finally { }",
   2083     NULL
   2084   };
   2085 
   2086   RunParserSyncTest(context_data, statement_data, kSuccess);
   2087 }
   2088 
   2089 
   2090 TEST(ErrorsRegexpLiteral) {
   2091   const char* context_data[][2] = {
   2092     {"var r = ", ""},
   2093     { NULL, NULL }
   2094   };
   2095 
   2096   const char* statement_data[] = {
   2097     "/unterminated",
   2098     NULL
   2099   };
   2100 
   2101   RunParserSyncTest(context_data, statement_data, kError);
   2102 }
   2103 
   2104 
   2105 TEST(NoErrorsRegexpLiteral) {
   2106   const char* context_data[][2] = {
   2107     {"var r = ", ""},
   2108     { NULL, NULL }
   2109   };
   2110 
   2111   const char* statement_data[] = {
   2112     "/foo/",
   2113     "/foo/g",
   2114     "/foo/whatever",  // This is an error but not detected by the parser.
   2115     NULL
   2116   };
   2117 
   2118   RunParserSyncTest(context_data, statement_data, kSuccess);
   2119 }
   2120 
   2121 
   2122 TEST(Intrinsics) {
   2123   const char* context_data[][2] = {
   2124     {"", ""},
   2125     { NULL, NULL }
   2126   };
   2127 
   2128   const char* statement_data[] = {
   2129     "%someintrinsic(arg)",
   2130     NULL
   2131   };
   2132 
   2133   // Parsing will fail or succeed depending on whether we allow natives syntax
   2134   // or not.
   2135   RunParserSyncTest(context_data, statement_data, kSuccessOrError);
   2136 }
   2137 
   2138 
   2139 TEST(NoErrorsNewExpression) {
   2140   const char* context_data[][2] = {
   2141     {"", ""},
   2142     {"var f =", ""},
   2143     { NULL, NULL }
   2144   };
   2145 
   2146   const char* statement_data[] = {
   2147     "new foo",
   2148     "new foo();",
   2149     "new foo(1);",
   2150     "new foo(1, 2);",
   2151     // The first () will be processed as a part of the NewExpression and the
   2152     // second () will be processed as part of LeftHandSideExpression.
   2153     "new foo()();",
   2154     // The first () will be processed as a part of the inner NewExpression and
   2155     // the second () will be processed as a part of the outer NewExpression.
   2156     "new new foo()();",
   2157     "new foo.bar;",
   2158     "new foo.bar();",
   2159     "new foo.bar.baz;",
   2160     "new foo.bar().baz;",
   2161     "new foo[bar];",
   2162     "new foo[bar]();",
   2163     "new foo[bar][baz];",
   2164     "new foo[bar]()[baz];",
   2165     "new foo[bar].baz(baz)()[bar].baz;",
   2166     "new \"foo\"",  // Runtime error
   2167     "new 1",  // Runtime error
   2168     // This even runs:
   2169     "(new new Function(\"this.x = 1\")).x;",
   2170     "new new Test_Two(String, 2).v(0123).length;",
   2171     NULL
   2172   };
   2173 
   2174   RunParserSyncTest(context_data, statement_data, kSuccess);
   2175 }
   2176 
   2177 
   2178 TEST(ErrorsNewExpression) {
   2179   const char* context_data[][2] = {
   2180     {"", ""},
   2181     {"var f =", ""},
   2182     { NULL, NULL }
   2183   };
   2184 
   2185   const char* statement_data[] = {
   2186     "new foo bar",
   2187     "new ) foo",
   2188     "new ++foo",
   2189     "new foo ++",
   2190     NULL
   2191   };
   2192 
   2193   RunParserSyncTest(context_data, statement_data, kError);
   2194 }
   2195 
   2196 
   2197 TEST(StrictObjectLiteralChecking) {
   2198   const char* strict_context_data[][2] = {
   2199     {"\"use strict\"; var myobject = {", "};"},
   2200     { NULL, NULL }
   2201   };
   2202   const char* non_strict_context_data[][2] = {
   2203     {"var myobject = {", "};"},
   2204     { NULL, NULL }
   2205   };
   2206 
   2207   // These are only errors in strict mode.
   2208   const char* statement_data[] = {
   2209     "foo: 1, foo: 2",
   2210     "\"foo\": 1, \"foo\": 2",
   2211     "foo: 1, \"foo\": 2",
   2212     "1: 1, 1: 2",
   2213     "1: 1, \"1\": 2",
   2214     "get: 1, get: 2",  // Not a getter for real, just a property called get.
   2215     "set: 1, set: 2",  // Not a setter for real, just a property called set.
   2216     NULL
   2217   };
   2218 
   2219   RunParserSyncTest(non_strict_context_data, statement_data, kSuccess);
   2220   RunParserSyncTest(strict_context_data, statement_data, kError);
   2221 }
   2222 
   2223 
   2224 TEST(ErrorsObjectLiteralChecking) {
   2225   const char* context_data[][2] = {
   2226     {"\"use strict\"; var myobject = {", "};"},
   2227     {"var myobject = {", "};"},
   2228     { NULL, NULL }
   2229   };
   2230 
   2231   const char* statement_data[] = {
   2232     "foo: 1, get foo() {}",
   2233     "foo: 1, set foo(v) {}",
   2234     "\"foo\": 1, get \"foo\"() {}",
   2235     "\"foo\": 1, set \"foo\"(v) {}",
   2236     "1: 1, get 1() {}",
   2237     "1: 1, set 1() {}",
   2238     // It's counter-intuitive, but these collide too (even in classic
   2239     // mode). Note that we can have "foo" and foo as properties in classic mode,
   2240     // but we cannot have "foo" and get foo, or foo and get "foo".
   2241     "foo: 1, get \"foo\"() {}",
   2242     "foo: 1, set \"foo\"(v) {}",
   2243     "\"foo\": 1, get foo() {}",
   2244     "\"foo\": 1, set foo(v) {}",
   2245     "1: 1, get \"1\"() {}",
   2246     "1: 1, set \"1\"() {}",
   2247     "\"1\": 1, get 1() {}"
   2248     "\"1\": 1, set 1(v) {}"
   2249     // Wrong number of parameters
   2250     "get bar(x) {}",
   2251     "get bar(x, y) {}",
   2252     "set bar() {}",
   2253     "set bar(x, y) {}",
   2254     // Parsing FunctionLiteral for getter or setter fails
   2255     "get foo( +",
   2256     "get foo() \"error\"",
   2257     NULL
   2258   };
   2259 
   2260   RunParserSyncTest(context_data, statement_data, kError);
   2261 }
   2262 
   2263 
   2264 TEST(NoErrorsObjectLiteralChecking) {
   2265   const char* context_data[][2] = {
   2266     {"var myobject = {", "};"},
   2267     {"\"use strict\"; var myobject = {", "};"},
   2268     { NULL, NULL }
   2269   };
   2270 
   2271   const char* statement_data[] = {
   2272     "foo: 1, bar: 2",
   2273     "\"foo\": 1, \"bar\": 2",
   2274     "1: 1, 2: 2",
   2275     // Syntax: IdentifierName ':' AssignmentExpression
   2276     "foo: bar = 5 + baz",
   2277     // Syntax: 'get' PropertyName '(' ')' '{' FunctionBody '}'
   2278     "get foo() {}",
   2279     "get \"foo\"() {}",
   2280     "get 1() {}",
   2281     // Syntax: 'set' PropertyName '(' PropertySetParameterList ')'
   2282     //     '{' FunctionBody '}'
   2283     "set foo(v) {}",
   2284     "set \"foo\"(v) {}",
   2285     "set 1(v) {}",
   2286     // Non-colliding getters and setters -> no errors
   2287     "foo: 1, get bar() {}",
   2288     "foo: 1, set bar(v) {}",
   2289     "\"foo\": 1, get \"bar\"() {}",
   2290     "\"foo\": 1, set \"bar\"(v) {}",
   2291     "1: 1, get 2() {}",
   2292     "1: 1, set 2(v) {}",
   2293     // Keywords, future reserved and strict future reserved are also allowed as
   2294     // property names.
   2295     "if: 4",
   2296     "interface: 5",
   2297     "super: 6",
   2298     "eval: 7",
   2299     "arguments: 8",
   2300     NULL
   2301   };
   2302 
   2303   RunParserSyncTest(context_data, statement_data, kSuccess);
   2304 }
   2305 
   2306 
   2307 TEST(TooManyArguments) {
   2308   const char* context_data[][2] = {
   2309     {"foo(", "0)"},
   2310     { NULL, NULL }
   2311   };
   2312 
   2313   using v8::internal::Code;
   2314   char statement[Code::kMaxArguments * 2 + 1];
   2315   for (int i = 0; i < Code::kMaxArguments; ++i) {
   2316     statement[2 * i] = '0';
   2317     statement[2 * i + 1] = ',';
   2318   }
   2319   statement[Code::kMaxArguments * 2] = 0;
   2320 
   2321   const char* statement_data[] = {
   2322     statement,
   2323     NULL
   2324   };
   2325 
   2326   // The test is quite slow, so run it with a reduced set of flags.
   2327   static const ParserFlag empty_flags[] = {kAllowLazy};
   2328   RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
   2329 }
   2330 
   2331 
   2332 TEST(StrictDelete) {
   2333   // "delete <Identifier>" is not allowed in strict mode.
   2334   const char* strict_context_data[][2] = {
   2335     {"\"use strict\"; ", ""},
   2336     { NULL, NULL }
   2337   };
   2338 
   2339   const char* sloppy_context_data[][2] = {
   2340     {"", ""},
   2341     { NULL, NULL }
   2342   };
   2343 
   2344   // These are errors in the strict mode.
   2345   const char* sloppy_statement_data[] = {
   2346     "delete foo;",
   2347     "delete foo + 1;",
   2348     "delete (foo);",
   2349     "delete eval;",
   2350     "delete interface;",
   2351     NULL
   2352   };
   2353 
   2354   // These are always OK
   2355   const char* good_statement_data[] = {
   2356     "delete this;",
   2357     "delete 1;",
   2358     "delete 1 + 2;",
   2359     "delete foo();",
   2360     "delete foo.bar;",
   2361     "delete foo[bar];",
   2362     "delete foo--;",
   2363     "delete --foo;",
   2364     "delete new foo();",
   2365     "delete new foo(bar);",
   2366     NULL
   2367   };
   2368 
   2369   // These are always errors
   2370   const char* bad_statement_data[] = {
   2371     "delete if;",
   2372     NULL
   2373   };
   2374 
   2375   RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
   2376   RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
   2377 
   2378   RunParserSyncTest(strict_context_data, good_statement_data, kSuccess);
   2379   RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess);
   2380 
   2381   RunParserSyncTest(strict_context_data, bad_statement_data, kError);
   2382   RunParserSyncTest(sloppy_context_data, bad_statement_data, kError);
   2383 }
   2384 
   2385 
   2386 TEST(InvalidLeftHandSide) {
   2387   const char* assignment_context_data[][2] = {
   2388     {"", " = 1;"},
   2389     {"\"use strict\"; ", " = 1;"},
   2390     { NULL, NULL }
   2391   };
   2392 
   2393   const char* prefix_context_data[][2] = {
   2394     {"++", ";"},
   2395     {"\"use strict\"; ++", ";"},
   2396     {NULL, NULL},
   2397   };
   2398 
   2399   const char* postfix_context_data[][2] = {
   2400     {"", "++;"},
   2401     {"\"use strict\"; ", "++;"},
   2402     { NULL, NULL }
   2403   };
   2404 
   2405   // Good left hand sides for assigment or prefix / postfix operations.
   2406   const char* good_statement_data[] = {
   2407     "foo",
   2408     "foo.bar",
   2409     "foo[bar]",
   2410     "foo()[bar]",
   2411     "foo().bar",
   2412     "this.foo",
   2413     "this[foo]",
   2414     "new foo()[bar]",
   2415     "new foo().bar",
   2416     "foo()",
   2417     "foo(bar)",
   2418     "foo[bar]()",
   2419     "foo.bar()",
   2420     "this()",
   2421     "this.foo()",
   2422     "this[foo].bar()",
   2423     "this.foo[foo].bar(this)(bar)[foo]()",
   2424     NULL
   2425   };
   2426 
   2427   // Bad left hand sides for assigment or prefix / postfix operations.
   2428   const char* bad_statement_data_common[] = {
   2429     "2",
   2430     "new foo",
   2431     "new foo()",
   2432     "null",
   2433     "if",  // Unexpected token
   2434     "{x: 1}",  // Unexpected token
   2435     "this",
   2436     "\"bar\"",
   2437     "(foo + bar)",
   2438     "new new foo()[bar]",  // means: new (new foo()[bar])
   2439     "new new foo().bar",  // means: new (new foo()[bar])
   2440     NULL
   2441   };
   2442 
   2443   // These are not okay for assignment, but okay for prefix / postix.
   2444   const char* bad_statement_data_for_assignment[] = {
   2445     "++foo",
   2446     "foo++",
   2447     "foo + bar",
   2448     NULL
   2449   };
   2450 
   2451   RunParserSyncTest(assignment_context_data, good_statement_data, kSuccess);
   2452   RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
   2453   RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
   2454                     kError);
   2455 
   2456   RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
   2457   RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
   2458 
   2459   RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
   2460   RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
   2461 }
   2462 
   2463 
   2464 TEST(FuncNameInferrerBasic) {
   2465   // Tests that function names are inferred properly.
   2466   i::FLAG_allow_natives_syntax = true;
   2467   v8::Isolate* isolate = CcTest::isolate();
   2468   v8::HandleScope scope(isolate);
   2469   LocalContext env;
   2470   CompileRun("var foo1 = function() {}; "
   2471              "var foo2 = function foo3() {}; "
   2472              "function not_ctor() { "
   2473              "  var foo4 = function() {}; "
   2474              "  return %FunctionGetInferredName(foo4); "
   2475              "} "
   2476              "function Ctor() { "
   2477              "  var foo5 = function() {}; "
   2478              "  return %FunctionGetInferredName(foo5); "
   2479              "} "
   2480              "var obj1 = { foo6: function() {} }; "
   2481              "var obj2 = { 'foo7': function() {} }; "
   2482              "var obj3 = {}; "
   2483              "obj3[1] = function() {}; "
   2484              "var obj4 = {}; "
   2485              "obj4[1] = function foo8() {}; "
   2486              "var obj5 = {}; "
   2487              "obj5['foo9'] = function() {}; "
   2488              "var obj6 = { obj7 : { foo10: function() {} } };");
   2489   ExpectString("%FunctionGetInferredName(foo1)", "foo1");
   2490   // foo2 is not unnamed -> its name is not inferred.
   2491   ExpectString("%FunctionGetInferredName(foo2)", "");
   2492   ExpectString("not_ctor()", "foo4");
   2493   ExpectString("Ctor()", "Ctor.foo5");
   2494   ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
   2495   ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
   2496   ExpectString("%FunctionGetInferredName(obj3[1])",
   2497                "obj3.(anonymous function)");
   2498   ExpectString("%FunctionGetInferredName(obj4[1])", "");
   2499   ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
   2500   ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
   2501 }
   2502 
   2503 
   2504 TEST(FuncNameInferrerTwoByte) {
   2505   // Tests function name inferring in cases where some parts of the inferred
   2506   // function name are two-byte strings.
   2507   i::FLAG_allow_natives_syntax = true;
   2508   v8::Isolate* isolate = CcTest::isolate();
   2509   v8::HandleScope scope(isolate);
   2510   LocalContext env;
   2511   uint16_t* two_byte_source = AsciiToTwoByteString(
   2512       "var obj1 = { oXj2 : { foo1: function() {} } }; "
   2513       "%FunctionGetInferredName(obj1.oXj2.foo1)");
   2514   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   2515   // Make it really non-ASCII (replace the Xs with a non-ASCII character).
   2516   two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010d;
   2517   v8::Local<v8::String> source =
   2518       v8::String::NewFromTwoByte(isolate, two_byte_source);
   2519   v8::Local<v8::Value> result = CompileRun(source);
   2520   CHECK(result->IsString());
   2521   v8::Local<v8::String> expected_name =
   2522       v8::String::NewFromTwoByte(isolate, two_byte_name);
   2523   CHECK(result->Equals(expected_name));
   2524   i::DeleteArray(two_byte_source);
   2525   i::DeleteArray(two_byte_name);
   2526 }
   2527 
   2528 
   2529 TEST(FuncNameInferrerEscaped) {
   2530   // The same as FuncNameInferrerTwoByte, except that we express the two-byte
   2531   // character as a unicode escape.
   2532   i::FLAG_allow_natives_syntax = true;
   2533   v8::Isolate* isolate = CcTest::isolate();
   2534   v8::HandleScope scope(isolate);
   2535   LocalContext env;
   2536   uint16_t* two_byte_source = AsciiToTwoByteString(
   2537       "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
   2538       "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
   2539   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
   2540   // Fix to correspond to the non-ASCII name in two_byte_source.
   2541   two_byte_name[6] = 0x010d;
   2542   v8::Local<v8::String> source =
   2543       v8::String::NewFromTwoByte(isolate, two_byte_source);
   2544   v8::Local<v8::Value> result = CompileRun(source);
   2545   CHECK(result->IsString());
   2546   v8::Local<v8::String> expected_name =
   2547       v8::String::NewFromTwoByte(isolate, two_byte_name);
   2548   CHECK(result->Equals(expected_name));
   2549   i::DeleteArray(two_byte_source);
   2550   i::DeleteArray(two_byte_name);
   2551 }
   2552