13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Redistribution and use in source and binary forms, with or without
3d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// modification, are permitted provided that the following conditions are
4d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// met:
5d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
6d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Redistributions of source code must retain the above copyright
7d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       notice, this list of conditions and the following disclaimer.
8d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Redistributions in binary form must reproduce the above
9d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       copyright notice, this list of conditions and the following
10d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       disclaimer in the documentation and/or other materials provided
11d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       with the distribution.
12d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Neither the name of Google Inc. nor the names of its
13d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       contributors may be used to endorse or promote products derived
14d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       from this software without specific prior written permission.
15d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
16d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
28d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include <stdlib.h>
293e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu#include <stdio.h>
308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include <string.h>
31d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
32d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "v8.h"
33d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
34589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "cctest.h"
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "compiler.h"
36589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "execution.h"
3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h"
389ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick#include "parser.h"
393e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu#include "preparser.h"
40589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "scanner-character-streams.h"
41589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "token.h"
42589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "utils.h"
43d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(ScanKeywords) {
45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  struct KeywordToken {
46d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    const char* keyword;
47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::Token::Value token;
48d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  };
49d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
50d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const KeywordToken keywords[] = {
51d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define KEYWORD(t, s, d) { s, i::Token::t },
5269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      TOKEN_LIST(IGNORE_TOKEN, KEYWORD)
53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#undef KEYWORD
54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      { NULL, i::Token::IDENTIFIER }
55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  };
56d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  KeywordToken key_token;
5869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  i::UnicodeCache unicode_cache;
5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  i::byte buffer[32];
60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
6169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    const i::byte* keyword =
6269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        reinterpret_cast<const i::byte*>(key_token.keyword);
6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    int length = i::StrLength(key_token.keyword);
6469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    CHECK(static_cast<int>(sizeof(buffer)) >= length);
6569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    {
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Utf8ToUtf16CharacterStream stream(keyword, length);
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner scanner(&unicode_cache);
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // The scanner should parse Harmony keywords for this test.
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      scanner.SetHarmonyScoping(true);
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      scanner.SetHarmonyModules(true);
7169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      scanner.Initialize(&stream);
7269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(key_token.token, scanner.Next());
7369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::EOS, scanner.Next());
74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
7569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Removing characters will make keyword matching fail.
7669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    {
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner scanner(&unicode_cache);
7969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      scanner.Initialize(&stream);
8069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
8169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::EOS, scanner.Next());
8269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
8369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Adding characters will make keyword matching fail.
8469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    static const char chars_to_append[] = { 'z', '0', '_' };
8569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
8669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      memmove(buffer, keyword, length);
8769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      buffer[length] = chars_to_append[j];
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner scanner(&unicode_cache);
9069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      scanner.Initialize(&stream);
9169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
9269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::EOS, scanner.Next());
9369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
9469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Replacing characters will make keyword matching fail.
9569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    {
9669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      memmove(buffer, keyword, length);
9769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      buffer[length - 1] = '_';
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Utf8ToUtf16CharacterStream stream(buffer, length);
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner scanner(&unicode_cache);
10069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      scanner.Initialize(&stream);
10169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
10269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      CHECK_EQ(i::Token::EOS, scanner.Next());
103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
106d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1079ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1089ac36c9faca11611ada13b4054edbaa0738661d0Iain MerrickTEST(ScanHTMLEndComments) {
10969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
11069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1119ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Regression test. See:
1129ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  //    http://code.google.com/p/chromium/issues/detail?id=53548
1139ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Tests that --> is correctly interpreted as comment-to-end-of-line if there
1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // is only whitespace before it on the line (with comments considered as
1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // whitespace, even a multiline-comment containing a newline).
1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // This was not the case if it occurred before the first real token
1179ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // in the input.
1189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* tests[] = {
1199ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      // Before first real token.
1209ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "--> is eol-comment\nvar y = 37;\n",
1219ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "\n --> is eol-comment\nvar y = 37;\n",
1229ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "/* precomment */ --> is eol-comment\nvar y = 37;\n",
1239ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
1249ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      // After first real token.
1259ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
1269ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
1279ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      NULL
1289ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  };
1299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const char* fail_tests[] = {
1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "x --> is eol-comment\nvar y = 37;\n",
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "\"\\n\" --> is eol-comment\nvar y = 37;\n",
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "var x = 42; --> is eol-comment\nvar y = 37;\n",
1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      NULL
1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  };
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1409ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Parser/Scanner needs a stack limit.
1419ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  int marker;
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate::Current()->stack_guard()->SetStackLimit(
1439ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1449ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1459ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  for (int i = 0; tests[i]; i++) {
1469ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::ScriptData* data =
1470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        v8::ScriptData::PreCompile(tests[i], i::StrLength(tests[i]));
1489ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    CHECK(data != NULL && !data->HasError());
1499ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    delete data;
1509ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  }
1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; fail_tests[i]; i++) {
1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    v8::ScriptData* data =
1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        v8::ScriptData::PreCompile(fail_tests[i], i::StrLength(fail_tests[i]));
1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CHECK(data == NULL || data->HasError());
1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    delete data;
1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1589ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick}
1599ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1609ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1619ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickclass ScriptResource : public v8::String::ExternalAsciiStringResource {
1629ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick public:
1639ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  ScriptResource(const char* data, size_t length)
1649ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      : data_(data), length_(length) { }
1659ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1669ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* data() const { return data_; }
1679ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  size_t length() const { return length_; }
1689ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1699ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick private:
1709ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* data_;
1719ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  size_t length_;
1729ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick};
1739ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1749ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1759ac36c9faca11611ada13b4054edbaa0738661d0Iain MerrickTEST(Preparsing) {
1769ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  v8::HandleScope handles;
1779ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  v8::Persistent<v8::Context> context = v8::Context::New();
1789ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  v8::Context::Scope context_scope(context);
1799ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  int marker;
18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate::Current()->stack_guard()->SetStackLimit(
1819ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1829ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
1839ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Source containing functions that might be lazily compiled  and all types
1849ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // of symbols (string, propertyName, regexp).
1859ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* source =
1869ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var x = 42;"
1879ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "function foo(a) { return function nolazy(b) { return a + b; } }"
1889ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "function bar(a) { if (a) return function lazy(b) { return b; } }"
1899ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var z = {'string': 'string literal', bareword: 'propertyName', "
1909ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "         42: 'number literal', for: 'keyword as propertyName', "
1919ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "         f\\u006fr: 'keyword propertyname with escape'};"
1929ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var v = /RegExp Literal/;"
1939ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var w = /RegExp Literal\\u0020With Escape/gin;"
1949ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "var y = { get getter() { return 42; }, "
1959ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      "          set setter(v) { this.value = v; }};";
1960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int source_length = i::StrLength(source);
1979ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* error_source = "var x = y z;";
1980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  int error_source_length = i::StrLength(error_source);
1999ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
2009ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  v8::ScriptData* preparse =
2019ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      v8::ScriptData::PreCompile(source, source_length);
2029ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  CHECK(!preparse->HasError());
2039ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  bool lazy_flag = i::FLAG_lazy;
2049ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  {
2059ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    i::FLAG_lazy = true;
2069ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    ScriptResource* resource = new ScriptResource(source, source_length);
2079ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
2089ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::Script::Compile(script_source, NULL, preparse);
2099ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  }
2109ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
2119ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  {
2129ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    i::FLAG_lazy = false;
2139ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
2149ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    ScriptResource* resource = new ScriptResource(source, source_length);
2159ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
2169ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    v8::Script::New(script_source, NULL, preparse, v8::Local<v8::String>());
2179ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  }
2189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  delete preparse;
2199ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  i::FLAG_lazy = lazy_flag;
2209ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
2219ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Syntax error.
2229ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  v8::ScriptData* error_preparse =
2239ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      v8::ScriptData::PreCompile(error_source, error_source_length);
2249ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  CHECK(error_preparse->HasError());
2259ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  i::ScriptDataImpl *pre_impl =
2269ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      reinterpret_cast<i::ScriptDataImpl*>(error_preparse);
2279ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  i::Scanner::Location error_location =
2289ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick      pre_impl->MessageLocation();
2299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Error is at "z" in source, location 10..11.
2309ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  CHECK_EQ(10, error_location.beg_pos);
2319ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  CHECK_EQ(11, error_location.end_pos);
2329ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  // Should not crash.
2339ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  const char* message = pre_impl->BuildMessage();
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  pre_impl->BuildArgs();
2359ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  CHECK_GT(strlen(message), 0);
2369ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick}
2373e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2383e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2393e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui ZhuTEST(StandAlonePreParser) {
24069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
24169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
2423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  int marker;
24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate::Current()->stack_guard()->SetStackLimit(
2443e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
2453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2463e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  const char* programs[] = {
2473e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      "{label: 42}",
2483e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      "var x = 42;",
2493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      "function foo(x, y) { return x + y; }",
2503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      "%ArgleBargle(glop);",
2513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      "var x = new new Function('this.x = 42');",
2523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      NULL
2533e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  };
2543e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
2558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
2563e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  for (int i = 0; programs[i]; i++) {
2573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    const char* program = programs[i];
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Utf8ToUtf16CharacterStream stream(
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        reinterpret_cast<const i::byte*>(program),
260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        static_cast<unsigned>(strlen(program)));
2613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    i::CompleteParserRecorder log;
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Scanner scanner(i::Isolate::Current()->unicode_cache());
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    scanner.Initialize(&stream);
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int flags = i::kAllowLazy | i::kAllowNativesSyntax;
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    v8::preparser::PreParser::PreParseResult result =
267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        v8::preparser::PreParser::PreParseProgram(&scanner,
268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                  &log,
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  flags,
270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                  stack_limit);
271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
2723e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    i::ScriptDataImpl data(log.ExtractData());
2733e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    CHECK(!data.has_error());
2743e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  }
2753e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu}
2768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(StandAlonePreParserNoNatives) {
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::V8::Initialize();
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int marker;
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* programs[] = {
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "%ArgleBargle(glop);",
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "var x = %_IsSmi(42);",
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      NULL
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; programs[i]; i++) {
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const char* program = programs[i];
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Utf8ToUtf16CharacterStream stream(
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        reinterpret_cast<const i::byte*>(program),
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        static_cast<unsigned>(strlen(program)));
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::CompleteParserRecorder log;
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Scanner scanner(i::Isolate::Current()->unicode_cache());
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    scanner.Initialize(&stream);
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Flags don't allow natives syntax.
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    v8::preparser::PreParser::PreParseResult result =
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        v8::preparser::PreParser::PreParseProgram(&scanner,
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  &log,
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  i::kAllowLazy,
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  stack_limit);
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::ScriptDataImpl data(log.ExtractData());
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Data contains syntax error.
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK(data.has_error());
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangTEST(RegressChromium62639) {
31669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
31769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
3188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int marker;
3198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
3208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
3218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  const char* program = "var x = 'something';\n"
3238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                        "escape: function() {}";
3248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Fails parsing expecting an identifier after "function".
3258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
3268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // and then used the invalid currently scanned literal. This always
3278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // failed in debug mode, and sometimes crashed in release mode.
3288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream(
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<const i::byte*>(program),
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      static_cast<unsigned>(strlen(program)));
3328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::ScriptDataImpl* data =
33369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      i::ParserApi::PreParse(&stream, NULL, false);
3348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK(data->HasError());
3358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  delete data;
3368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
3378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangTEST(Regress928) {
34069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
34169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
3428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Preparsing didn't consider the catch clause of a try statement
3438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // as with-content, which made it assume that a function inside
3448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // the block could be lazily compiled, and an extra, unexpected,
3458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // entry was added to the data.
3468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int marker;
3478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
3488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
3498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  const char* program =
3518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      "try { } catch (e) { var foo = function () { /* first */ } }"
3528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      "var bar = function () { /* second */ }";
3538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::HandleScope handles;
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::String> source(
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FACTORY->NewStringFromAscii(i::CStrVector(program)));
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::ScriptDataImpl* data = i::ParserApi::PartialPreParse(source, NULL, false);
3588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK(!data->HasError());
3598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  data->Initialize();
3618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  int first_function =
363e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      static_cast<int>(strstr(program, "function") - program);
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int first_lbrace = first_function + i::StrLength("function () ");
3658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK_EQ('{', program[first_lbrace]);
3668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace);
3678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK(!entry1.is_valid());
3688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  int second_function =
370e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      static_cast<int>(strstr(program + first_lbrace, "function") - program);
371e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  int second_lbrace =
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      second_function + i::StrLength("function () ");
3738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK_EQ('{', program[second_lbrace]);
3748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace);
3758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK(entry2.is_valid());
3768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  CHECK_EQ('}', program[entry2.end_pos() - 1]);
3778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  delete data;
3788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(PreParseOverflow) {
38269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
38369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int marker;
3858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  size_t kProgramSize = 1024 * 1024;
389589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  i::SmartArrayPointer<char> program(
390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<char*>(malloc(kProgramSize + 1)));
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  memset(*program, '(', kProgramSize);
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  program[kProgramSize] = '\0';
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream(
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<const i::byte*>(*program),
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<unsigned>(kProgramSize));
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::CompleteParserRecorder log;
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  scanner.Initialize(&stream);
402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  v8::preparser::PreParser::PreParseResult result =
405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      v8::preparser::PreParser::PreParseProgram(&scanner,
406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                &log,
407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                true,
408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                stack_limit);
409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_EQ(v8::preparser::PreParser::kPreParseStackOverflow, result);
410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TestExternalResource: public v8::String::ExternalStringResource {
414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit TestExternalResource(uint16_t* data, int length)
416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : data_(data), length_(static_cast<size_t>(length)) { }
417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ~TestExternalResource() { }
419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const uint16_t* data() const {
421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return data_;
422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  size_t length() const {
425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return length_;
426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint16_t* data_;
429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  size_t length_;
430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid TestCharacterStream(const char* ascii_source,
436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         unsigned length,
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         unsigned start = 0,
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         unsigned end = 0) {
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (end == 0) end = length;
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned sub_length = end - start;
441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::HandleScope test_scope;
442589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned i = 0; i < length; i++) {
444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]);
445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length));
447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Handle<i::String> ascii_string(
44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FACTORY->NewStringFromAscii(ascii_vector));
449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestExternalResource resource(*uc16_buffer, length);
450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Handle<i::String> uc16_string(
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FACTORY->NewExternalStringFromTwoByte(&resource));
452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::GenericStringUtf16CharacterStream string_stream(ascii_string, start, end);
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream utf8_stream(
457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<const i::byte*>(ascii_source), end);
458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  utf8_stream.SeekForward(start);
459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned i = start;
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (i < end) {
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Read streams one char at a time
463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c0 = ascii_source[i];
467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c1 = uc16_stream.Advance();
468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c2 = string_stream.Advance();
469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c3 = utf8_stream.Advance();
470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i++;
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c1);
472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c2);
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c3);
474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (i > start + sub_length / 4) {
479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Pushback, re-read, pushback again.
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c0 = ascii_source[i - 1];
481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uc16_stream.PushBack(c0);
485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    string_stream.PushBack(c0);
486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    utf8_stream.PushBack(c0);
487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i--;
488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c1 = uc16_stream.Advance();
492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c2 = string_stream.Advance();
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c3 = utf8_stream.Advance();
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i++;
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c1);
499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c2);
500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c3);
501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    uc16_stream.PushBack(c0);
502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    string_stream.PushBack(c0);
503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    utf8_stream.PushBack(c0);
504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i--;
505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned halfway = start + sub_length / 2;
510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uc16_stream.SeekForward(halfway - i);
511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  string_stream.SeekForward(halfway - i);
512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  utf8_stream.SeekForward(halfway - i);
513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i = halfway;
514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_EQU(i, uc16_stream.pos());
515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_EQU(i, string_stream.pos());
516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_EQU(i, utf8_stream.pos());
517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (i < end) {
519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Read streams one char at a time
520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c0 = ascii_source[i];
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c1 = uc16_stream.Advance();
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c2 = string_stream.Advance();
526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c3 = utf8_stream.Advance();
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i++;
528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c1);
529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c2);
530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(c0, c3);
531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, uc16_stream.pos());
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, string_stream.pos());
533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, utf8_stream.pos());
534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t c1 = uc16_stream.Advance();
537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t c2 = string_stream.Advance();
538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int32_t c3 = utf8_stream.Advance();
539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_LT(c1, 0);
540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_LT(c2, 0);
541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CHECK_LT(c3, 0);
542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(CharacterStreams) {
546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  v8::HandleScope handles;
547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  v8::Persistent<v8::Context> context = v8::Context::New();
548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  v8::Context::Scope context_scope(context);
549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestCharacterStream("abc\0\n\r\x7f", 7);
551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const unsigned kBigStringSize = 4096;
552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  char buffer[kBigStringSize + 1];
553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned i = 0; i < kBigStringSize; i++) {
554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    buffer[i] = static_cast<char>(i & 0x7f);
555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestCharacterStream(buffer, kBigStringSize);
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestCharacterStream(buffer, kBigStringSize, 576, 3298);
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestCharacterStream("\0", 1);
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestCharacterStream("", 0);
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(Utf8CharacterStream) {
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar;
567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU);
568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kAllUtf8CharsSize =
570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      (unibrow::Utf8::kMaxOneByteChar + 1) +
571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      (unibrow::Utf8::kMaxTwoByteChar - unibrow::Utf8::kMaxOneByteChar) * 2 +
572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      (unibrow::Utf8::kMaxThreeByteChar - unibrow::Utf8::kMaxTwoByteChar) * 3;
573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const unsigned kAllUtf8CharsSizeU =
574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      static_cast<unsigned>(kAllUtf8CharsSize);
575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  char buffer[kAllUtf8CharsSizeU];
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned cursor = 0;
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i <= kMaxUC16Char; i++) {
5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    cursor += unibrow::Utf8::Encode(buffer + cursor,
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    i,
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    unibrow::Utf16::kNoPreviousCharacter);
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(cursor == kAllUtf8CharsSizeU);
584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       kAllUtf8CharsSizeU);
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i <= kMaxUC16Char; i++) {
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, stream.pos());
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c = stream.Advance();
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(i, c);
591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i + 1, stream.pos());
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = kMaxUC16Char; i >= 0; i--) {
594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i + 1, stream.pos());
595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    stream.PushBack(i);
596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, stream.pos());
597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
598b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int i = 0;
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  while (stream.pos() < kMaxUC16CharU) {
600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, stream.pos());
601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned progress = stream.SeekForward(12);
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i += progress;
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t c = stream.Advance();
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (i <= kMaxUC16Char) {
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      CHECK_EQ(i, c);
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    } else {
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      CHECK_EQ(-1, c);
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i += 1;
610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQU(i, stream.pos());
611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef CHECK_EQU
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid TestStreamScanner(i::Utf16CharacterStream* stream,
617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       i::Token::Value* expected_tokens,
618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       int skip_pos = 0,  // Zero means not skipping.
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       int skip_to = 0) {
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
6219fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  scanner.Initialize(stream);
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int i = 0;
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  do {
625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i::Token::Value expected = expected_tokens[i];
626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i::Token::Value actual = scanner.Next();
627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (scanner.location().end_pos == skip_pos) {
629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      scanner.SeekForward(skip_to);
630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    i++;
632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } while (expected_tokens[i] != i::Token::ILLEGAL);
633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(StreamScanner) {
63669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
63769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        static_cast<unsigned>(strlen(str1)));
641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Token::Value expectations1[] = {
642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::LBRACE,
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::IDENTIFIER,
644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::IDENTIFIER,
645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::FOR,
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::COLON,
647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::MUL,
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::DIV,
649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::LT,
650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::SUB,
651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::IDENTIFIER,
652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::EOS,
653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::ILLEGAL
654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestStreamScanner(&stream1, expectations1, 0, 0);
656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        static_cast<unsigned>(strlen(str2)));
660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Token::Value expectations2[] = {
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::CASE,
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::DEFAULT,
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::CONST,
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::LBRACE,
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Skipped part here
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::RBRACE,
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::DO,
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::EOS,
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::ILLEGAL
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT_EQ('{', str2[19]);
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT_EQ('}', str2[37]);
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestStreamScanner(&stream2, expectations2, 20, 37);
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const char* str3 = "{}}}}";
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Token::Value expectations3[] = {
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::LBRACE,
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::RBRACE,
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::RBRACE,
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::RBRACE,
681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::RBRACE,
682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::EOS,
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      i::Token::ILLEGAL
684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Skip zero-four RBRACEs.
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i <= 4; i++) {
687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch     expectations3[6 - i] = i::Token::ILLEGAL;
688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch     expectations3[5 - i] = i::Token::EOS;
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch     i::Utf8ToUtf16CharacterStream stream3(
690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch         reinterpret_cast<const i::byte*>(str3),
691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch         static_cast<unsigned>(strlen(str3)));
692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch     TestStreamScanner(&stream3, expectations3, 1, 1 + i);
693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
695086aeeaae12517475c22695a200be45495516549Ben Murdoch
696086aeeaae12517475c22695a200be45495516549Ben Murdoch
697086aeeaae12517475c22695a200be45495516549Ben Murdochvoid TestScanRegExp(const char* re_source, const char* expected) {
6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Utf8ToUtf16CharacterStream stream(
699086aeeaae12517475c22695a200be45495516549Ben Murdoch       reinterpret_cast<const i::byte*>(re_source),
700086aeeaae12517475c22695a200be45495516549Ben Murdoch       static_cast<unsigned>(strlen(re_source)));
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
702086aeeaae12517475c22695a200be45495516549Ben Murdoch  scanner.Initialize(&stream);
703086aeeaae12517475c22695a200be45495516549Ben Murdoch
704086aeeaae12517475c22695a200be45495516549Ben Murdoch  i::Token::Value start = scanner.peek();
705086aeeaae12517475c22695a200be45495516549Ben Murdoch  CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
706086aeeaae12517475c22695a200be45495516549Ben Murdoch  CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
707086aeeaae12517475c22695a200be45495516549Ben Murdoch  scanner.Next();  // Current token is now the regexp literal.
708086aeeaae12517475c22695a200be45495516549Ben Murdoch  CHECK(scanner.is_literal_ascii());
709086aeeaae12517475c22695a200be45495516549Ben Murdoch  i::Vector<const char> actual = scanner.literal_ascii_string();
710086aeeaae12517475c22695a200be45495516549Ben Murdoch  for (int i = 0; i < actual.length(); i++) {
711086aeeaae12517475c22695a200be45495516549Ben Murdoch    CHECK_NE('\0', expected[i]);
712086aeeaae12517475c22695a200be45495516549Ben Murdoch    CHECK_EQ(expected[i], actual[i]);
713086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
714086aeeaae12517475c22695a200be45495516549Ben Murdoch}
715086aeeaae12517475c22695a200be45495516549Ben Murdoch
716086aeeaae12517475c22695a200be45495516549Ben Murdoch
717086aeeaae12517475c22695a200be45495516549Ben MurdochTEST(RegExpScanning) {
71869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::V8::Initialize();
71969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
720086aeeaae12517475c22695a200be45495516549Ben Murdoch  // RegExp token with added garbage at the end. The scanner should only
721086aeeaae12517475c22695a200be45495516549Ben Murdoch  // scan the RegExp until the terminating slash just before "flipperwald".
722086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/b/flipperwald", "b");
723086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Incomplete escape sequences doesn't hide the terminating slash.
724086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\x/flipperwald", "\\x");
725086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\u/flipperwald", "\\u");
726086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\u1/flipperwald", "\\u1");
727086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\u12/flipperwald", "\\u12");
728086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\u123/flipperwald", "\\u123");
729086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\c/flipperwald", "\\c");
730086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\c//flipperwald", "\\c");
731086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Slashes inside character classes are not terminating.
732086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[/]/flipperwald", "[/]");
733086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
734086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Incomplete escape sequences inside a character class doesn't hide
735086aeeaae12517475c22695a200be45495516549Ben Murdoch  // the end of the character class.
736086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
737086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
738086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
739086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
740086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
741086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
742086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
743086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
744086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Escaped ']'s wont end the character class.
745086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
746086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Escaped slashes are not terminating.
747086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/\\//flipperwald", "\\/");
748086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Starting with '=' works too.
749086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/=/", "=");
750086aeeaae12517475c22695a200be45495516549Ben Murdoch  TestScanRegExp("/=?/", "=?");
751086aeeaae12517475c22695a200be45495516549Ben Murdoch}
752692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
753692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int Utf8LengthHelper(const char* s) {
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int len = i::StrLength(s);
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int character_length = len;
7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < len; i++) {
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    unsigned char c = s[i];
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int input_offset = 0;
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int output_adjust = 0;
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (c > 0x7f) {
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (c < 0xc0) continue;
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (c >= 0xf0) {
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (c >= 0xf8) {
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // byte.
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          continue;  // Handle first UTF-8 byte.
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // This 4 byte sequence could have been coded as a 3 byte sequence.
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Record a single kBadChar for the first byte and continue.
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          continue;
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        input_offset = 3;
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        character_length -= 2;
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else if (c >= 0xe0) {
7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // This 3 byte sequence could have been coded as a 2 byte sequence.
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Record a single kBadChar for the first byte and continue.
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          continue;
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        input_offset = 2;
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        output_adjust = 2;
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if ((c & 0x1e) == 0) {
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // This 2 byte sequence could have been coded as a 1 byte sequence.
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Record a single kBadChar for the first byte and continue.
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          continue;
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        input_offset = 1;
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        output_adjust = 1;
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool bad = false;
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (int j = 1; j <= input_offset; j++) {
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if ((s[i + j] & 0xc0) != 0x80) {
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          // which is a single UTF-16 code unit.
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          bad = true;
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          break;
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!bad) {
8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        i += input_offset;
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        character_length -= output_adjust;
8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return character_length;
8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(ScopePositions) {
8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Test the parser for correctly setting the start and end positions
8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of a scope. We check the scope positions of exactly one scope
8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // nested in the global scope of a program. 'inner source' is the
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // source code that determines the part of the source belonging
8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to the nested scope. 'outer_prefix' and 'outer_suffix' are
8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parts of the source that belong to the global scope.
8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  struct SourceData {
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const char* outer_prefix;
8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const char* inner_source;
8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const char* outer_suffix;
8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::ScopeType scope_type;
8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::LanguageMode language_mode;
8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const SourceData source_data[] = {
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({}) ", "{\n"
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    block;\n"
8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({}) ", "statement", "\n"
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  with ({})\n"
8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    ", "statement;", "\n"
8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::WITH_SCOPE, i::CLASSIC_MODE },
8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  try {} catch ", "(e) { block; }", " more;",
8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::CATCH_SCOPE, i::CLASSIC_MODE },
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  try {} catch ", "(e) { block; }", "; more;",
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::CATCH_SCOPE, i::CLASSIC_MODE },
8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  try {} catch ", "(e) {\n"
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    block;\n"
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::CATCH_SCOPE, i::CLASSIC_MODE },
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  try {} catch ", "(e) { block; }", " finally { block; } more;",
8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::CATCH_SCOPE, i::CLASSIC_MODE },
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  start;\n"
8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  start;\n"
8563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  start;\n"
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  ", "{\n"
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    let block;\n"
8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  start;\n"
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  function fun", "(a,b) { infunction; }", " more;",
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  start;\n"
8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  function fun", "(a,b) {\n"
8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    infunction;\n"
8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::FUNCTION_SCOPE, i::CLASSIC_MODE },
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  (function fun", "(a,b) { infunction; }", ")();",
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x) {\n"
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    block;\n"
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x = 1 ; x < 10; ++ x)\n"
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    statement;", "\n"
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {}) { block; }", " more;",
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {}) { block; }", "; more;",
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {}) {\n"
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    block;\n"
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  }", "\n"
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {}) statement;", " more;",
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::BLOCK_SCOPE, i::EXTENDED_MODE },
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {}) statement", "\n"
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  for ", "(let x in {})\n"
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "    statement;", "\n"
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // the preparser off in terms of byte offsets.
9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // 6 byte encoding.
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\240\201\355\260\211';\n"
9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // 4 byte encoding.
9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\360\220\220\212';\n"
9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // 3 byte encoding of \u0fff.
9133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\340\277\277';\n"
9143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 6 byte encoding with missing last byte.
9173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\240\201\355\211';\n"
9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 3 byte encoding of \u0fff with missing last byte.
9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\340\277';\n"
9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\340';\n"
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\340\203\277';\n"
9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\340\201\277';\n"
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Unpaired lead surrogate.
9373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\240\201';\n"
9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Unpaired lead surrogate where following code point is a 3 byte sequence.
9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\240\201\340\277\277';\n"
9423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Unpaired lead surrogate where following code point is a 4 byte encoding
9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // of a trail surrogate.
9463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\240\201\360\215\260\211';\n"
9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Unpaired trail surrogate.
9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\355\260\211';\n"
9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // 2 byte encoding of \u00ff.
9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\303\277';\n"
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 2 byte encoding of \u00ff with missing last byte.
9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\303';\n"
9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\301\277';\n"
9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Illegal 5 byte encoding.
9663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\370\277\277\277\277';\n"
9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Illegal 6 byte encoding.
9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\374\277\277\277\277\277';\n"
9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Illegal 0xfe byte
9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\376\277\277\277\277\277\277';\n"
9753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Illegal 0xff byte
9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo\377\277\277\277\277\277\277\277';\n"
9793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { infunction; }", ")();",
9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo';\n"
9823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
9833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { "  'foo';\n"
9853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "  (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::FUNCTION_SCOPE, i::CLASSIC_MODE },
9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE }
9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::HandleScope handles;
9913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::Persistent<v8::Context> context = v8::Context::New();
9923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::Context::Scope context_scope(context);
9933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int marker;
9953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
9963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::FLAG_harmony_scoping = true;
9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; source_data[i].outer_prefix; i++) {
10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kInnerByteLen = i::StrLength(source_data[i].inner_source);
10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Vector<char> program = i::Vector<char>::New(kProgramByteSize + 1);
10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::OS::SNPrintF(program, "%s%s%s",
10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             source_data[i].outer_prefix,
10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             source_data[i].inner_source,
10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             source_data[i].outer_suffix);
10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Parse program source.
10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Handle<i::String> source(
10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(source->length(), kProgramSize);
10183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Handle<i::Script> script = FACTORY->NewScript(source);
10193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::CompilationInfo info(script);
10213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    info.MarkAsGlobal();
10223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    info.SetLanguageMode(source_data[i].language_mode);
10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::FunctionLiteral* function = parser.ParseProgram(&info);
10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK(function != NULL);
10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Check scope types and positions.
10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Scope* scope = function->scope();
10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK(scope->is_global_scope());
10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(scope->start_position(), 0);
10303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(scope->end_position(), kProgramSize);
10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(scope->inner_scopes()->length(), 1);
10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Scope* inner_scope = scope->inner_scopes()->at(0);
10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(inner_scope->type(), source_data[i].scope_type);
10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(inner_scope->start_position(), kPrefixLen);
10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // The end position of a token is one position after the last
10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // character belonging to that token.
10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid TestParserSync(i::Handle<i::String> source, int flags) {
1044692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool harmony_scoping = ((i::kLanguageModeMask & flags) == i::EXTENDED_MODE);
1046692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1047692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  // Preparse the data.
1048692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::CompleteParserRecorder log;
10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  scanner.SetHarmonyScoping(harmony_scoping);
1052692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  scanner.Initialize(&stream);
1053692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  v8::preparser::PreParser::PreParseResult result =
1054692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      v8::preparser::PreParser::PreParseProgram(
10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          &scanner, &log, flags, stack_limit);
1056692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
1057692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::ScriptDataImpl data(log.ExtractData());
1058692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1059692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  // Parse the data
1060692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::Handle<i::Script> script = FACTORY->NewScript(source);
10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool save_harmony_scoping = i::FLAG_harmony_scoping;
10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::FLAG_harmony_scoping = harmony_scoping;
10633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Parser parser(script, flags, NULL, NULL);
10643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::CompilationInfo info(script);
10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  info.MarkAsGlobal();
10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::FunctionLiteral* function = parser.ParseProgram(&info);
10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::FLAG_harmony_scoping = save_harmony_scoping;
1068692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1069692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::String* type_string = NULL;
1070692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  if (function == NULL) {
1071692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    // Extract exception from the parser.
1072692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::Handle<i::String> type_symbol = FACTORY->LookupAsciiSymbol("type");
1073692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    CHECK(i::Isolate::Current()->has_pending_exception());
1074692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::MaybeObject* maybe_object = i::Isolate::Current()->pending_exception();
1075692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::JSObject* exception = NULL;
1076692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    CHECK(maybe_object->To(&exception));
1077692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1078692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    // Get the type string.
1079692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    maybe_object = exception->GetProperty(*type_symbol);
1080692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    CHECK(maybe_object->To(&type_string));
1081692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  }
1082692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1083692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  // Check that preparsing fails iff parsing fails.
1084692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  if (data.has_error() && function != NULL) {
1085692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::OS::Print(
1086692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "Preparser failed on:\n"
1087692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "\t%s\n"
1088692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "with error:\n"
1089692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "\t%s\n"
1090692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "However, the parser succeeded",
1091692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        *source->ToCString(), data.BuildMessage());
1092692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    CHECK(false);
1093692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  } else if (!data.has_error() && function == NULL) {
1094692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::OS::Print(
1095692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "Parser failed on:\n"
1096692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "\t%s\n"
1097692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "with error:\n"
1098692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "\t%s\n"
1099692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        "However, the preparser succeeded",
1100692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        *source->ToCString(), *type_string->ToCString());
1101692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    CHECK(false);
1102692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  }
1103692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1104692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  // Check that preparser and parser produce the same error.
1105692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  if (function == NULL) {
1106692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    if (!type_string->IsEqualTo(i::CStrVector(data.BuildMessage()))) {
1107692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      i::OS::Print(
1108692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          "Expected parser and preparser to produce the same error on:\n"
1109692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          "\t%s\n"
1110692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          "However, found the following error messages\n"
1111692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          "\tparser:    %s\n"
1112692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          "\tpreparser: %s\n",
1113692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch          *source->ToCString(), *type_string->ToCString(), data.BuildMessage());
1114692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      CHECK(false);
1115692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    }
1116692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  }
1117692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch}
1118692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1119692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid TestParserSyncWithFlags(i::Handle<i::String> source) {
11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kFlagsCount = 6;
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int flags[kFlagsCount] = {
11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kNoParsingFlags | i::CLASSIC_MODE,
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kNoParsingFlags | i::STRICT_MODE,
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kNoParsingFlags | i::EXTENDED_MODE,
11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kAllowLazy | i::CLASSIC_MODE,
11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kAllowLazy | i::STRICT_MODE,
11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::kAllowLazy | i::EXTENDED_MODE
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int k = 0; k < kFlagsCount; ++k) {
11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    TestParserSync(source, flags[k]);
11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1137692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben MurdochTEST(ParserSync) {
1138692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  const char* context_data[][2] = {
1139692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "", "" },
1140692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "{", "}" },
1141692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "if (true) ", " else {}" },
1142692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "if (true) {} else ", "" },
1143692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "if (true) ", "" },
1144692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "do ", " while (false)" },
1145692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "while (false) ", "" },
1146692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "for (;;) ", "" },
1147692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "with ({})", "" },
1148692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "switch (12) { case 12: ", "}" },
1149692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "switch (12) { default: ", "}" },
1150692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { "label2: ", "" },
1151692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    { NULL, NULL }
1152692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  };
1153692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1154692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  const char* statement_data[] = {
1155692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "{}",
1156692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "var x",
1157692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "var x = 1",
1158692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "const x",
1159692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "const x = 1",
1160692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    ";",
1161692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "12",
1162692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) {} else ;",
1163692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) {} else {}",
1164692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) {} else 12",
1165692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) ;"
1166692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) {}",
1167692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "if (false) 12",
1168692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "do {} while (false)",
1169692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "for (;;) ;",
1170692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "for (;;) {}",
1171692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "for (;;) 12",
1172692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "continue",
1173692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "continue label",
1174692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "continue\nlabel",
1175692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "break",
1176692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "break label",
1177692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "break\nlabel",
1178692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "return",
1179692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "return  12",
1180692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "return\n12",
1181692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "with ({}) ;",
1182692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "with ({}) {}",
1183692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "with ({}) 12",
1184692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "switch ({}) { default: }"
1185692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "label3: "
1186692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "throw",
1187692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "throw  12",
1188692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "throw\n12",
1189692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "try {} catch(e) {}",
1190692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "try {} finally {}",
1191692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "try {} catch(e) {} finally {}",
1192692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "debugger",
1193692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    NULL
1194692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  };
1195692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1196692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  const char* termination_data[] = {
1197692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "",
1198692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    ";",
1199692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "\n",
1200692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    ";\n",
1201692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    "\n;",
1202692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    NULL
1203692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  };
1204692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1205692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  v8::HandleScope handles;
1206692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  v8::Persistent<v8::Context> context = v8::Context::New();
1207692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  v8::Context::Scope context_scope(context);
1208692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1209692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  int marker;
1210692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::Isolate::Current()->stack_guard()->SetStackLimit(
1211692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1212692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1213692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  for (int i = 0; context_data[i][0] != NULL; ++i) {
1214692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    for (int j = 0; statement_data[j] != NULL; ++j) {
1215692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      for (int k = 0; termination_data[k] != NULL; ++k) {
1216692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int kPrefixLen = i::StrLength(context_data[i][0]);
1217692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int kStatementLen = i::StrLength(statement_data[j]);
1218692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int kTerminationLen = i::StrLength(termination_data[k]);
1219692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int kSuffixLen = i::StrLength(context_data[i][1]);
1220692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
1221692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            + kSuffixLen + i::StrLength("label: for (;;) {  }");
1222692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch
1223692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        // Plug the source code pieces together.
1224692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        i::Vector<char> program = i::Vector<char>::New(kProgramSize + 1);
1225692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        int length = i::OS::SNPrintF(program,
1226692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            "label: for (;;) { %s%s%s%s }",
1227692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            context_data[i][0],
1228692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            statement_data[j],
1229692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            termination_data[k],
1230692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            context_data[i][1]);
1231692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        CHECK(length == kProgramSize);
1232692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch        i::Handle<i::String> source =
1233692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch            FACTORY->NewStringFromAscii(i::CStrVector(program.start()));
12343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        TestParserSyncWithFlags(source);
1235692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch      }
1236692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    }
1237692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  }
1238692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch}
1239