1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
28a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Redistribution and use in source and binary forms, with or without
38a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// modification, are permitted provided that the following conditions are
48a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// met:
58a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//
68a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//     * Redistributions of source code must retain the above copyright
78a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       notice, this list of conditions and the following disclaimer.
88a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//     * Redistributions in binary form must reproduce the above
98a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       copyright notice, this list of conditions and the following
108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       disclaimer in the documentation and/or other materials provided
118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       with the distribution.
128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//     * Neither the name of Google Inc. nor the names of its
138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       contributors may be used to endorse or promote products derived
148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//       from this software without specific prior written permission.
158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang//
168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
28589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include <math.h>
29589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "../include/v8stdint.h"
31589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "allocation.h"
33589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "checks.h"
34589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "conversions.h"
35589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "conversions-inl.h"
36589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "globals.h"
37589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "hashmap.h"
388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "list.h"
39257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "preparse-data-format.h"
408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "preparse-data.h"
418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "preparser.h"
42589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "unicode.h"
43589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "utils.h"
443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangnamespace v8 {
46589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
47589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef _MSC_VER
48589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Usually defined in math.h, but not in MSVC.
49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Abstracted to work
50589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint isfinite(double value);
51589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif
52589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangnamespace preparser {
548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPreParser::PreParseResult PreParser::PreParseLazyFunction(
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::LanguageMode mode, i::ParserRecorder* log) {
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  log_ = log;
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lazy functions always have trivial outer scopes (no with/catch scopes).
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope top_scope(&scope_, kTopLevelScope);
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  set_language_mode(mode);
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope function_scope(&scope_, kFunctionScope);
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ok = true;
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int start_position = scanner_->peek_location().beg_pos;
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ParseLazyFunctionLiteralBody(&ok);
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (stack_overflow_) return kPreParseStackOverflow;
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!ok) {
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ReportUnexpectedToken(scanner_->current_token());
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_classic_mode()) {
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int end_pos = scanner_->location().end_pos;
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CheckOctalLiteral(start_position, end_pos, &ok);
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (ok) {
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return kPreParseSuccess;
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Preparsing checks a JavaScript program and emits preparse-data that helps
848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// a later parsing to be faster.
858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// See preparser-data.h for the data.
868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// The PreParser checks that the syntax follows the grammar for JavaScript,
888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// and collects some information about the program along the way.
898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// The grammar check is only performed in order to understand the program
908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// sufficiently to deduce some information about it, that can be used
918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// to speed up later parsing. Finding errors is not the goal of pre-parsing,
928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// rather it is to speed up properly written and correct programs.
938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// That means that contextual checks (like a label being declared where
948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// it is used) are generally omitted.
958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid PreParser::ReportUnexpectedToken(i::Token::Value token) {
978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // We don't report stack overflows here, to avoid increasing the
988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // stack depth even further.  Instead we report it after parsing is
998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // over, in ParseProgram.
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (token == i::Token::ILLEGAL && stack_overflow_) {
1018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return;
1028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Scanner::Location source_location = scanner_->location();
1048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Four of the tokens are treated specially
1068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  switch (token) {
1078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  case i::Token::EOS:
108589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location, "unexpected_eos", NULL);
1098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  case i::Token::NUMBER:
110589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location, "unexpected_token_number", NULL);
1118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  case i::Token::STRING:
112589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location, "unexpected_token_string", NULL);
1138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  case i::Token::IDENTIFIER:
114589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location,
1158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                           "unexpected_token_identifier", NULL);
1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  case i::Token::FUTURE_RESERVED_WORD:
117589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location, "unexpected_reserved", NULL);
1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  case i::Token::FUTURE_STRICT_RESERVED_WORD:
119589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ReportMessageAt(source_location,
1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           "unexpected_strict_reserved", NULL);
1218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  default:
1228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    const char* name = i::Token::String(token);
123589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(source_location, "unexpected_token", name);
1248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
1258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
1268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Checks whether octal literal last seen is between beg_pos and end_pos.
129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// If so, reports an error.
130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Scanner::Location octal = scanner_->octal_position();
132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
133589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(octal, "strict_octal_literal", NULL);
134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    scanner_->clear_octal_position();
135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define CHECK_OK  ok);                      \
141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!*ok) return kUnknownSourceElements;  \
142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ((void)0
143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define DUMMY )  // to make indentation work
144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef DUMMY
145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
14769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochPreParser::Statement PreParser::ParseSourceElement(bool* ok) {
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // (Ecma 262 5th Edition, clause 14):
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // SourceElement:
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    Statement
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    FunctionDeclaration
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // In harmony mode we allow additionally the following productions
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // SourceElement:
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    LetDeclaration
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    ConstDeclaration
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  switch (peek()) {
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case i::Token::FUNCTION:
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return ParseFunctionDeclaration(ok);
16169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    case i::Token::LET:
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case i::Token::CONST:
16369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return ParseVariableStatement(kSourceElement, ok);
16469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    default:
16569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return ParseStatement(ok);
16669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
16769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
16869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
16969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::SourceElements PreParser::ParseSourceElements(int end_token,
171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                         bool* ok) {
1728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // SourceElements ::
1738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   (Statement)* <end_token>
1748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
175257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool allow_directive_prologue = true;
1768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (peek() != end_token) {
17769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    Statement statement = ParseSourceElement(CHECK_OK);
178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (allow_directive_prologue) {
179257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (statement.IsUseStrictLiteral()) {
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        set_language_mode(harmony_scoping_ ?
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          i::EXTENDED_MODE : i::STRICT_MODE);
182257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      } else if (!statement.IsStringLiteral()) {
183257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        allow_directive_prologue = false;
184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
1878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return kUnknownSourceElements;
1888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
1898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_OK
192257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define CHECK_OK  ok);                   \
193257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!*ok) return Statement::Default();  \
194257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ((void)0
195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define DUMMY )  // to make indentation work
196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef DUMMY
197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
198257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseStatement(bool* ok) {
2008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Statement ::
2018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Block
2028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   VariableStatement
2038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   EmptyStatement
2048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ExpressionStatement
2058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   IfStatement
2068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   IterationStatement
2078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ContinueStatement
2088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   BreakStatement
2098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ReturnStatement
2108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   WithStatement
2118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   LabelledStatement
2128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   SwitchStatement
2138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ThrowStatement
2148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   TryStatement
2158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   DebuggerStatement
2168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Note: Since labels can only be used by 'break' and 'continue'
2188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // statements, which themselves are only valid within blocks,
2198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // iterations or 'switch' statements (i.e., BreakableStatements),
2208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // labels can be simply ignored in all other cases; except for
2218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // trivial labeled break statements 'label: break label' which is
2228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // parsed into an empty statement.
2238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Keep the source position of the statement
2258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  switch (peek()) {
2268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::LBRACE:
2278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseBlock(ok);
2288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::CONST:
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case i::Token::LET:
2318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::VAR:
23269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return ParseVariableStatement(kStatement, ok);
2338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::SEMICOLON:
2358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Statement::Default();
2378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::IF:
239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return ParseIfStatement(ok);
2408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::DO:
2428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseDoWhileStatement(ok);
2438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::WHILE:
2458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseWhileStatement(ok);
2468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::FOR:
2488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseForStatement(ok);
2498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::CONTINUE:
2518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseContinueStatement(ok);
2528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::BREAK:
2548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseBreakStatement(ok);
2558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::RETURN:
2578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseReturnStatement(ok);
2588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::WITH:
2608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseWithStatement(ok);
2618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::SWITCH:
2638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseSwitchStatement(ok);
2648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::THROW:
2668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseThrowStatement(ok);
2678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::TRY:
2698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseTryStatement(ok);
2708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case i::Token::FUNCTION: {
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner::Location start_location = scanner_->peek_location();
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Statement statement = ParseFunctionDeclaration(CHECK_OK);
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      i::Scanner::Location end_location = scanner_->location();
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!is_classic_mode()) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ReportMessageAt(start_location.beg_pos, end_location.end_pos,
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        "strict_function", NULL);
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *ok = false;
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return Statement::Default();
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return statement;
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::DEBUGGER:
2868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseDebuggerStatement(ok);
2878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    default:
2898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return ParseExpressionOrLabelledStatement(ok);
2908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
2918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
2928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
2958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // FunctionDeclaration ::
2968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::FUNCTION, CHECK_OK);
298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Identifier identifier = ParseIdentifier(CHECK_OK);
300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Scanner::Location location = scanner_->location();
301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expression function_value = ParseFunctionLiteral(CHECK_OK);
303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (function_value.IsStrictFunction() &&
305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      !identifier.IsValidStrictVariable()) {
306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Strict mode violation, using either reserved word or eval/arguments
307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // as name of strict function.
308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    const char* type = "strict_function_name";
3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (identifier.IsFutureStrictReserved()) {
310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      type = "strict_reserved_word";
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
312589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(location, type, NULL);
313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::FunctionDeclaration();
3168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
3178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseBlock(bool* ok) {
3208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Block ::
3218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '{' Statement* '}'
3228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Note that a Block does not introduce a new execution scope!
3248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // (ECMA-262, 3rd, 12.2)
3258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //
3268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LBRACE, CHECK_OK);
3278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (peek() != i::Token::RBRACE) {
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (is_extended_mode()) {
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ParseSourceElement(CHECK_OK);
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ParseStatement(CHECK_OK);
332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
3338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expect(i::Token::RBRACE, ok);
335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
3368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
3378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
33969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochPreParser::Statement PreParser::ParseVariableStatement(
34069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    VariableDeclarationContext var_context,
34169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    bool* ok) {
3428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // VariableStatement ::
3438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   VariableDeclarations ';'
3448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
34569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Statement result = ParseVariableDeclarations(var_context,
34669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                               NULL,
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               NULL,
34869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                               CHECK_OK);
3498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ExpectSemicolon(CHECK_OK);
3508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return result;
3518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
3528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// If the variable declaration declares exactly one non-const
3558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// variable, then *var is set to that variable. In all other cases,
3568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// *var is untouched; in particular, it is the caller's responsibility
3578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// to initialize it properly. This mechanism is also used for the parsing
3588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// of 'for-in' loops.
35969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochPreParser::Statement PreParser::ParseVariableDeclarations(
36069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    VariableDeclarationContext var_context,
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VariableDeclarationProperties* decl_props,
36269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    int* num_decl,
36369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    bool* ok) {
3648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // VariableDeclarations ::
3658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The ES6 Draft Rev3 specifies the following grammar for const declarations
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ConstDeclaration ::
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   const ConstBinding (',' ConstBinding)* ';'
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ConstBinding ::
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   Identifier '=' AssignmentExpression
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // TODO(ES6):
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ConstBinding ::
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //   BindingPattern '=' AssignmentExpression
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool require_initializer = false;
3788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::VAR) {
3798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Consume(i::Token::VAR);
3808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } else if (peek() == i::Token::CONST) {
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // * It is a Syntax Error if the code that matches this production is not
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   contained in extended code.
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // However disallowing const in classic mode will break compatibility with
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // existing pages. Therefore we keep allowing const with the old
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // non-harmony semantics in classic mode.
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Consume(i::Token::CONST);
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    switch (language_mode()) {
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      case i::CLASSIC_MODE:
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      case i::STRICT_MODE: {
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        i::Scanner::Location location = scanner_->peek_location();
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ReportMessageAt(location, "strict_const", NULL);
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *ok = false;
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return Statement::Default();
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      case i::EXTENDED_MODE:
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (var_context != kSourceElement &&
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            var_context != kForStatement) {
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          i::Scanner::Location location = scanner_->peek_location();
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          ReportMessageAt(location.beg_pos, location.end_pos,
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          "unprotected_const", NULL);
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          *ok = false;
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          return Statement::Default();
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        require_initializer = true;
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (peek() == i::Token::LET) {
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // ES6 Draft Rev4 section 12.2.1:
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // LetDeclaration : let LetBindingList ;
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // * It is a Syntax Error if the code that matches this production is not
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    //   contained in extended code.
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_extended_mode()) {
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      i::Scanner::Location location = scanner_->peek_location();
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ReportMessageAt(location.beg_pos, location.end_pos,
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      "illegal_let", NULL);
424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      *ok = false;
425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Statement::Default();
426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Consume(i::Token::LET);
42869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if (var_context != kSourceElement &&
42969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        var_context != kForStatement) {
43069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      i::Scanner::Location location = scanner_->peek_location();
43169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      ReportMessageAt(location.beg_pos, location.end_pos,
43269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                      "unprotected_let", NULL);
43369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      *ok = false;
43469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return Statement::Default();
43569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
4368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } else {
4378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *ok = false;
438257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Statement::Default();
4398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
4408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
44169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // The scope of a var/const declared variable anywhere inside a function
44269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
44369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // of a let declared variable is the scope of the immediately enclosing
44469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // block.
4458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int nvars = 0;  // the number of variables declared
4468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  do {
4478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    // Parse variable name.
4488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (nvars > 0) Consume(i::Token::COMMA);
449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Identifier identifier  = ParseIdentifier(CHECK_OK);
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StrictModeIdentifierViolation(scanner_->location(),
452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    "strict_var_name",
453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    identifier,
454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    ok);
455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Statement::Default();
456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    nvars++;
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (peek() == i::Token::ASSIGN || require_initializer) {
4598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::ASSIGN, CHECK_OK);
46069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (decl_props != NULL) *decl_props = kHasInitializers;
4628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
4638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } while (peek() == i::Token::COMMA);
4648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (num_decl != NULL) *num_decl = nvars;
466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
4678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
4688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochPreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
4718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ExpressionStatement | LabelledStatement ::
4728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Expression ';'
4738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Identifier ':' Statement
4748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression expr = ParseExpression(true, CHECK_OK);
4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (expr.IsRawIdentifier()) {
4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(!expr.AsIdentifier().IsFutureReserved());
4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(is_classic_mode() || !expr.AsIdentifier().IsFutureStrictReserved());
4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (peek() == i::Token::COLON) {
480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Consume(i::Token::COLON);
4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return ParseStatement(ok);
482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Preparsing is disabled for extensions (because the extension details
4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // aren't passed to lazily compiled functions), so we don't
4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // accept "native function" in the preparser.
4868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
4878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Parsed expression statement.
4888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ExpectSemicolon(CHECK_OK);
489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::ExpressionStatement(expr);
4908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
4918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseIfStatement(bool* ok) {
4948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // IfStatement ::
4958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'if' '(' Expression ')' Statement ('else' Statement)?
4968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::IF, CHECK_OK);
4988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
4998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
5008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
5018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseStatement(CHECK_OK);
5028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::ELSE) {
5038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Next();
5048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseStatement(CHECK_OK);
5058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
5078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
5088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
5118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ContinueStatement ::
5128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'continue' [no line terminator] Identifier? ';'
5138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::CONTINUE, CHECK_OK);
5158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value tok = peek();
5163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
5178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::SEMICOLON &&
5188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::RBRACE &&
5198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::EOS) {
5208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseIdentifier(CHECK_OK);
5218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
5228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ExpectSemicolon(CHECK_OK);
523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
5248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
5258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
5288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // BreakStatement ::
5298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'break' [no line terminator] Identifier? ';'
5308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::BREAK, CHECK_OK);
5328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value tok = peek();
5333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
5348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::SEMICOLON &&
5358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::RBRACE &&
5368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::EOS) {
5378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseIdentifier(CHECK_OK);
5388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
5398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ExpectSemicolon(CHECK_OK);
540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
5418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
5428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
5458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ReturnStatement ::
5468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'return' [no line terminator] Expression? ';'
5478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Consume the return token. It is necessary to do the before
5498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // reporting any errors on it, because of the way errors are
5508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // reported (underlining).
5518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RETURN, CHECK_OK);
5528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // An ECMAScript program is considered syntactically incorrect if it
5548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // contains a return statement that is not within the body of a
5558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // function. See ECMA-262, section 12.9, page 67.
5568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // This is not handled during preparsing.
5578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value tok = peek();
5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
5608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::SEMICOLON &&
5618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::RBRACE &&
5628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok != i::Token::EOS) {
5638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseExpression(true, CHECK_OK);
5648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
5658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ExpectSemicolon(CHECK_OK);
566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
5678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
5688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseWithStatement(bool* ok) {
5718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // WithStatement ::
5728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'with' '(' Expression ')' Statement
5738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::WITH, CHECK_OK);
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!is_classic_mode()) {
575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Scanner::Location location = scanner_->location();
576589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(location, "strict_mode_with", NULL);
577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Statement::Default();
579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
5808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
5818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
5828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
5838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  scope_->EnterWith();
5858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseStatement(CHECK_OK);
5868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  scope_->LeaveWith();
587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
5888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
5898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
5928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // SwitchStatement ::
5938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'switch' '(' Expression ')' '{' CaseClause* '}'
5948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::SWITCH, CHECK_OK);
5968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
5978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
5988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
5998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LBRACE, CHECK_OK);
6018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value token = peek();
6028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (token != i::Token::RBRACE) {
6038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (token == i::Token::CASE) {
6048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::CASE, CHECK_OK);
6058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      ParseExpression(true, CHECK_OK);
6068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::COLON, CHECK_OK);
6078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    } else if (token == i::Token::DEFAULT) {
6088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::DEFAULT, CHECK_OK);
6098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::COLON, CHECK_OK);
6108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    } else {
6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ParseStatement(CHECK_OK);
6128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
6138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    token = peek();
6148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expect(i::Token::RBRACE, ok);
616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
6178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
6188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
6218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // DoStatement ::
6228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'do' Statement 'while' '(' Expression ')' ';'
6238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::DO, CHECK_OK);
6258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseStatement(CHECK_OK);
6268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::WHILE, CHECK_OK);
6278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
6288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
629257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expect(i::Token::RPAREN, ok);
630692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON);
631257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
6328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
6338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
6368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // WhileStatement ::
6378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'while' '(' Expression ')' Statement
6388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::WHILE, CHECK_OK);
6408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
6418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
6428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
643257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ParseStatement(ok);
644257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
6458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
6468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseForStatement(bool* ok) {
6498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ForStatement ::
6508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
6518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::FOR, CHECK_OK);
6538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
6548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() != i::Token::SEMICOLON) {
65569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
65669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        peek() == i::Token::LET) {
6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool is_let = peek() == i::Token::LET;
6588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      int decl_count;
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      VariableDeclarationProperties decl_props = kHasNoInitializers;
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ParseVariableDeclarations(
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          kForStatement, &decl_props, &decl_count, CHECK_OK);
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool accept_IN = decl_count == 1 &&
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          !(is_let && decl_props == kHasInitializers);
6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (peek() == i::Token::IN && accept_IN) {
6658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::IN, CHECK_OK);
6668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseExpression(true, CHECK_OK);
6678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::RPAREN, CHECK_OK);
6688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseStatement(CHECK_OK);
670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        return Statement::Default();
6718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
6728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    } else {
6738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      ParseExpression(false, CHECK_OK);
6748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      if (peek() == i::Token::IN) {
6758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::IN, CHECK_OK);
6768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseExpression(true, CHECK_OK);
6778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::RPAREN, CHECK_OK);
6788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseStatement(CHECK_OK);
680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        return Statement::Default();
6818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
6828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
6838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
6848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Parsed initializer at this point.
6868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::SEMICOLON, CHECK_OK);
6878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() != i::Token::SEMICOLON) {
6898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseExpression(true, CHECK_OK);
6908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
6918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::SEMICOLON, CHECK_OK);
6928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() != i::Token::RPAREN) {
6948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseExpression(true, CHECK_OK);
6958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
6968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
6978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ParseStatement(ok);
699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
7008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
7048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ThrowStatement ::
7058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'throw' [no line terminator] Expression ';'
7068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::THROW, CHECK_OK);
7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (scanner_->HasAnyLineTerminatorBeforeNext()) {
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    i::Scanner::Location pos = scanner_->location();
710589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(pos, "newline_after_throw", NULL);
7118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *ok = false;
712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Statement::Default();
7138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
7148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseExpression(true, CHECK_OK);
715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ExpectSemicolon(ok);
716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
7178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseTryStatement(bool* ok) {
7218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // TryStatement ::
7228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'try' Block Catch
7238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'try' Block Finally
7248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'try' Block Catch Finally
7258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //
7268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Catch ::
7278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'catch' '(' Identifier ')' Block
7288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //
7298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Finally ::
7308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'finally' Block
7318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // In preparsing, allow any number of catch/finally blocks, including zero
7338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // of both.
7348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::TRY, CHECK_OK);
7368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseBlock(CHECK_OK);
7388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  bool catch_or_finally_seen = false;
7408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::CATCH) {
7418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Consume(i::Token::CATCH);
7428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Expect(i::Token::LPAREN, CHECK_OK);
743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Identifier id = ParseIdentifier(CHECK_OK);
7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_classic_mode() && !id.IsValidStrictVariable()) {
745257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StrictModeIdentifierViolation(scanner_->location(),
746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    "strict_catch_variable",
747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    id,
748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    ok);
749257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Statement::Default();
750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
7518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Expect(i::Token::RPAREN, CHECK_OK);
7528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    scope_->EnterWith();
7538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseBlock(ok);
7548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    scope_->LeaveWith();
755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!*ok) Statement::Default();
7568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    catch_or_finally_seen = true;
7578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
7588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::FINALLY) {
7598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Consume(i::Token::FINALLY);
7608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseBlock(CHECK_OK);
7618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    catch_or_finally_seen = true;
7628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
7638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (!catch_or_finally_seen) {
7648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *ok = false;
7658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
766257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
7678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
7718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
7728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // contexts this is used as a statement which invokes the debugger as if a
7738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // break point is present.
7748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // DebuggerStatement ::
7758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'debugger' ';'
7768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::DEBUGGER, CHECK_OK);
778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ExpectSemicolon(ok);
779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Statement::Default();
7808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_OK
784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define CHECK_OK  ok);                     \
785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!*ok) return Expression::Default();  \
786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ((void)0
787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define DUMMY )  // to make indentation work
788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef DUMMY
789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Precedence = 1
792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
7938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Expression ::
7948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   AssignmentExpression
7958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Expression ',' AssignmentExpression
7968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
7988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (peek() == i::Token::COMMA) {
7998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Expect(i::Token::COMMA, CHECK_OK);
8008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseAssignmentExpression(accept_IN, CHECK_OK);
801257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    result = Expression::Default();
8028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
8038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return result;
8048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
8058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Precedence = 2
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                           bool* ok) {
8108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // AssignmentExpression ::
8118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ConditionalExpression
8128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
8138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Scanner::Location before = scanner_->peek_location();
8158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
8168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (!i::Token::IsAssignmentOp(peek())) {
8188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    // Parsed conditional expression only (no assignment).
8198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return expression;
8208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
8218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!is_classic_mode() &&
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      expression.IsIdentifier() &&
824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      expression.AsIdentifier().IsEvalOrArguments()) {
825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Scanner::Location after = scanner_->location();
826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ReportMessageAt(before.beg_pos, after.end_pos,
827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                    "strict_lhs_assignment", NULL);
828257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
8328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value op = Next();  // Get assignment operator.
8338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseAssignmentExpression(accept_IN, CHECK_OK);
8348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
835257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
8368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    scope_->AddProperty();
8378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
8388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
8408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
8418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Precedence = 3
844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                            bool* ok) {
8468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ConditionalExpression ::
8478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   LogicalOrExpression
8488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
8498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // We start using the binary expression parser for prec >= 4 only!
8518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
8528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() != i::Token::CONDITIONAL) return expression;
8538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Consume(i::Token::CONDITIONAL);
8548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // In parsing the first assignment expression in conditional
8558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // expressions we always accept the 'in' keyword; see ECMA-262,
8568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // section 11.12, page 58.
8578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseAssignmentExpression(true, CHECK_OK);
8588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::COLON, CHECK_OK);
8598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseAssignmentExpression(accept_IN, CHECK_OK);
860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
8618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
8628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangint PreParser::Precedence(i::Token::Value tok, bool accept_IN) {
8658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (tok == i::Token::IN && !accept_IN)
8668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return 0;  // 0 precedence will terminate binary expression parsing
8678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return i::Token::Precedence(tok);
8698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
8708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Precedence >= 4
873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseBinaryExpression(int prec,
874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                       bool accept_IN,
875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                       bool* ok) {
8768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression result = ParseUnaryExpression(CHECK_OK);
8778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
8788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    // prec1 >= 4
8798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    while (Precedence(peek(), accept_IN) == prec1) {
8808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
8818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = Expression::Default();
8838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
8848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
8858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return result;
8868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
8878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
8888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
8908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // UnaryExpression ::
8918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   PostfixExpression
8928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'delete' UnaryExpression
8938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'void' UnaryExpression
8948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'typeof' UnaryExpression
8958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '++' UnaryExpression
8968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '--' UnaryExpression
8978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '+' UnaryExpression
8988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '-' UnaryExpression
8998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '~' UnaryExpression
9008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '!' UnaryExpression
9018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value op = peek();
903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (i::Token::IsUnaryOp(op)) {
9048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    op = Next();
9058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseUnaryExpression(ok);
906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (i::Token::IsCountOp(op)) {
908257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    op = Next();
909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Scanner::Location before = scanner_->peek_location();
910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Expression expression = ParseUnaryExpression(CHECK_OK);
9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_classic_mode() &&
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        expression.IsIdentifier() &&
913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        expression.AsIdentifier().IsEvalOrArguments()) {
914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      i::Scanner::Location after = scanner_->location();
915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ReportMessageAt(before.beg_pos, after.end_pos,
916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      "strict_lhs_prefix", NULL);
917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      *ok = false;
918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
9208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } else {
9218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return ParsePostfixExpression(ok);
9228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
9238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
9248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
9278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // PostfixExpression ::
9288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   LeftHandSideExpression ('++' | '--')?
9298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Scanner::Location before = scanner_->peek_location();
9318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expression expression = ParseLeftHandSideExpression(CHECK_OK);
9323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
9338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      i::Token::IsCountOp(peek())) {
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!is_classic_mode() &&
9353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        expression.IsIdentifier() &&
936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        expression.AsIdentifier().IsEvalOrArguments()) {
937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      i::Scanner::Location after = scanner_->location();
938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ReportMessageAt(before.beg_pos, after.end_pos,
939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      "strict_lhs_postfix", NULL);
940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      *ok = false;
941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Expression::Default();
942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
9438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Next();
944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
9458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
9468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return expression;
9478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
9488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
9518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // LeftHandSideExpression ::
9528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   (NewExpression | MemberExpression) ...
9538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expression result = Expression::Default();
9558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::NEW) {
9568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    result = ParseNewExpression(CHECK_OK);
9578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } else {
9588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    result = ParseMemberExpression(CHECK_OK);
9598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
9608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (true) {
9628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    switch (peek()) {
9638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::LBRACK: {
9648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(i::Token::LBRACK);
9658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseExpression(true, CHECK_OK);
9668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::RBRACK, CHECK_OK);
967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (result.IsThis()) {
968257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::ThisProperty();
9698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        } else {
970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::Default();
9718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
9728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
9738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
9748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::LPAREN: {
9768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseArguments(CHECK_OK);
977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        result = Expression::Default();
9788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
9798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
9808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::PERIOD: {
9828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(i::Token::PERIOD);
9838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseIdentifierName(CHECK_OK);
984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (result.IsThis()) {
985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::ThisProperty();
9868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        } else {
987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::Default();
9888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
9898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
9908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
9918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      default:
9938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        return result;
9948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
9958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
9968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
9978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
999b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseNewExpression(bool* ok) {
10008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // NewExpression ::
10018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ('new')+ MemberExpression
10028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // The grammar for new expressions is pretty warped. The keyword
10048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // 'new' can either be a part of the new expression (where it isn't
10058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // followed by an argument list) or a part of the member expression,
10068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // where it must be followed by an argument list. To accommodate
10078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // this, we parse the 'new' keywords greedily and keep track of how
10088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // many we have parsed. This information is then passed on to the
10098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // member expression parser, which is only allowed to match argument
10108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // lists as long as it has 'new' prefixes left
10118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  unsigned new_count = 0;
10128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  do {
10138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Consume(i::Token::NEW);
10148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    new_count++;
10158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } while (peek() == i::Token::NEW);
10168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return ParseMemberWithNewPrefixesExpression(new_count, ok);
10188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
10198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
10228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return ParseMemberWithNewPrefixesExpression(0, ok);
10238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
10248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
10278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    unsigned new_count, bool* ok) {
10288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // MemberExpression ::
10298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   (PrimaryExpression | FunctionLiteral)
10308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //     ('[' Expression ']' | '.' Identifier | Arguments)*
10318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Parse the initial primary or function expression.
1033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expression result = Expression::Default();
10348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (peek() == i::Token::FUNCTION) {
10358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Consume(i::Token::FUNCTION);
1036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Identifier identifier = Identifier::Default();
10371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (peek_any_identifier()) {
1038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      identifier = ParseIdentifier(CHECK_OK);
10398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
10408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    result = ParseFunctionLiteral(CHECK_OK);
1041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1042257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StrictModeIdentifierViolation(scanner_->location(),
1043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    "strict_function_name",
1044257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    identifier,
1045257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    ok);
1046257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Expression::Default();
1047257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
10488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  } else {
10498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    result = ParsePrimaryExpression(CHECK_OK);
10508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
10518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (true) {
10538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    switch (peek()) {
10548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::LBRACK: {
10558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(i::Token::LBRACK);
10568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseExpression(true, CHECK_OK);
10578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Expect(i::Token::RBRACK, CHECK_OK);
1058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (result.IsThis()) {
1059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::ThisProperty();
10608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        } else {
1061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::Default();
10628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
10638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
10648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
10658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::PERIOD: {
10668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(i::Token::PERIOD);
10678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseIdentifierName(CHECK_OK);
1068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (result.IsThis()) {
1069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::ThisProperty();
10708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        } else {
1071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          result = Expression::Default();
10728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
10738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
10748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
10758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::LPAREN: {
10768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        if (new_count == 0) return result;
10778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        // Consume one of the new prefixes (already parsed).
10788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        ParseArguments(CHECK_OK);
10798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        new_count--;
1080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        result = Expression::Default();
10818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
10828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
10838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      default:
10848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        return result;
10858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
10868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
10878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
10888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
10898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
10918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // PrimaryExpression ::
10928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'this'
10938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'null'
10948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'true'
10958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   'false'
10968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Identifier
10978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   Number
10988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   String
10998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ArrayLiteral
11008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   ObjectLiteral
11018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   RegExpLiteral
11028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '(' Expression ')'
11038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expression result = Expression::Default();
11058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  switch (peek()) {
11068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::THIS: {
11078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
1108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = Expression::This();
11098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    case i::Token::FUTURE_RESERVED_WORD: {
11133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Next();
11143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::Scanner::Location location = scanner_->location();
11153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ReportMessageAt(location.beg_pos, location.end_pos,
11163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                      "reserved_word", NULL);
11173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      *ok = false;
11183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return Expression::Default();
11193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
11203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    case i::Token::FUTURE_STRICT_RESERVED_WORD:
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!is_classic_mode()) {
1123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Next();
1124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        i::Scanner::Location location = scanner_->location();
1125589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        ReportMessageAt(location, "strict_reserved_word", NULL);
1126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        *ok = false;
1127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        return Expression::Default();
1128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // FALLTHROUGH
1130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case i::Token::IDENTIFIER: {
1131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Identifier id = ParseIdentifier(CHECK_OK);
1132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = Expression::FromIdentifier(id);
11338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::NULL_LITERAL:
11378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::TRUE_LITERAL:
11388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::FALSE_LITERAL:
11398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::NUMBER: {
11408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
11418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::STRING: {
11448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
11458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = GetStringSymbol();
11468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::ASSIGN_DIV:
11508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseRegExpLiteral(true, CHECK_OK);
11518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::DIV:
11548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseRegExpLiteral(false, CHECK_OK);
11558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::LBRACK:
11588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseArrayLiteral(CHECK_OK);
11598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::LBRACE:
11628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseObjectLiteral(CHECK_OK);
11638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::LPAREN:
11668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Consume(i::Token::LPAREN);
1167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      parenthesized_function_ = (peek() == i::Token::FUNCTION);
11688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseExpression(true, CHECK_OK);
11698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::RPAREN, CHECK_OK);
1170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      result = result.Parenthesize();
11718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::Token::MOD:
11748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      result = ParseV8Intrinsic(CHECK_OK);
11758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      break;
11768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    default: {
11788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Next();
11798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      *ok = false;
1180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Expression::Default();
11818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
11838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return result;
11858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
11868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
11898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ArrayLiteral ::
11908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '[' Expression? (',' Expression?)* ']'
11918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LBRACK, CHECK_OK);
11928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (peek() != i::Token::RBRACK) {
11938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (peek() != i::Token::COMMA) {
11948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      ParseAssignmentExpression(true, CHECK_OK);
11958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (peek() != i::Token::RBRACK) {
11978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::COMMA, CHECK_OK);
11988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
11998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
12008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RBRACK, CHECK_OK);
12018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
12028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  scope_->NextMaterializedLiteralIndex();
1203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
12048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
12058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1206589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid PreParser::CheckDuplicate(DuplicateFinder* finder,
1207589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               i::Token::Value property,
1208589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               int type,
1209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               bool* ok) {
1210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int old_type;
1211589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (property == i::Token::NUMBER) {
1212589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    old_type = finder->AddNumber(scanner_->literal_ascii_string(), type);
1213589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else if (scanner_->is_literal_ascii()) {
1214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    old_type = finder->AddAsciiSymbol(scanner_->literal_ascii_string(),
1215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                      type);
1216589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    old_type = finder->AddUtf16Symbol(scanner_->literal_utf16_string(), type);
1218589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (HasConflict(old_type, type)) {
1220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (IsDataDataConflict(old_type, type)) {
1221589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Both are data properties.
12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (is_classic_mode()) return;
1223589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ReportMessageAt(scanner_->location(),
1224589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                      "strict_duplicate_property", NULL);
1225589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else if (IsDataAccessorConflict(old_type, type)) {
1226589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Both a data and an accessor property with the same name.
1227589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ReportMessageAt(scanner_->location(),
1228589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                      "accessor_data_property", NULL);
1229589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
1230589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ASSERT(IsAccessorAccessorConflict(old_type, type));
1231589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Both accessors of the same type.
1232589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ReportMessageAt(scanner_->location(),
1233589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                      "accessor_get_set", NULL);
1234589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1235589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    *ok = false;
1236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
12398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
12418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // ObjectLiteral ::
12428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '{' (
12438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //       ((IdentifierName | String | Number) ':' AssignmentExpression)
12448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
12458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //    )*[','] '}'
12468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
12478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LBRACE, CHECK_OK);
1248589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DuplicateFinder duplicate_finder(scanner_->unicode_cache());
12498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (peek() != i::Token::RBRACE) {
12508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    i::Token::Value next = peek();
12518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    switch (next) {
12521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      case i::Token::IDENTIFIER:
12533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      case i::Token::FUTURE_RESERVED_WORD:
12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      case i::Token::FUTURE_STRICT_RESERVED_WORD: {
12558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        bool is_getter = false;
12568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        bool is_setter = false;
12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
12588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        if ((is_getter || is_setter) && peek() != i::Token::COLON) {
12598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            i::Token::Value name = Next();
12609fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block            bool is_keyword = i::Token::IsKeyword(name);
12618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            if (name != i::Token::IDENTIFIER &&
12621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                name != i::Token::FUTURE_RESERVED_WORD &&
12633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
12648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                name != i::Token::NUMBER &&
12658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                name != i::Token::STRING &&
12669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                !is_keyword) {
12678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang              *ok = false;
1268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              return Expression::Default();
12698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            }
12709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block            if (!is_keyword) {
12719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block              LogSymbol();
12729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block            }
1273589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
1274589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            CheckDuplicate(&duplicate_finder, name, type, CHECK_OK);
12758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            ParseFunctionLiteral(CHECK_OK);
12768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            if (peek() != i::Token::RBRACE) {
12778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang              Expect(i::Token::COMMA, CHECK_OK);
12788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            }
12798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang            continue;  // restart the while
12808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
1281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
12828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
12838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      }
12848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::STRING:
12858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(next);
1286589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
12878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        GetStringSymbol();
12888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
12898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      case i::Token::NUMBER:
12908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        Consume(next);
1291589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
12928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        break;
12938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      default:
12948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        if (i::Token::IsKeyword(next)) {
12958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang          Consume(next);
1296589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
12978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        } else {
12988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang          // Unexpected token.
12998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang          *ok = false;
1300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          return Expression::Default();
13018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang        }
13028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
13038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Expect(i::Token::COLON, CHECK_OK);
13058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    ParseAssignmentExpression(true, CHECK_OK);
13068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    // TODO(1240767): Consider allowing trailing comma.
13088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
13098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
13108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RBRACE, CHECK_OK);
13118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  scope_->NextMaterializedLiteralIndex();
1313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
13148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
13158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                    bool* ok) {
13198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (!scanner_->ScanRegExpPattern(seen_equal)) {
13208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Next();
1321589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
13228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *ok = false;
1323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
13248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
13258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  scope_->NextMaterializedLiteralIndex();
13278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (!scanner_->ScanRegExpFlags()) {
13298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Next();
1330589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
13318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *ok = false;
1332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::Default();
13338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
13348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Next();
1335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
13368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
13378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Arguments PreParser::ParseArguments(bool* ok) {
13408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Arguments ::
13418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '(' (AssignmentExpression)*[','] ')'
13428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expect(i::Token::LPAREN, ok);
1344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!*ok) return -1;
13458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  bool done = (peek() == i::Token::RPAREN);
13468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int argc = 0;
13478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (!done) {
1348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ParseAssignmentExpression(true, ok);
1349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!*ok) return -1;
13508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    argc++;
13518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    done = (peek() == i::Token::RPAREN);
1352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!done) {
1353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Expect(i::Token::COMMA, ok);
1354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (!*ok) return -1;
1355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
13568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
1357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Expect(i::Token::RPAREN, ok);
13588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return argc;
13598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
13608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
13638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Function ::
13648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
13658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Parse function body.
13678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ScopeType outer_scope_type = scope_->type();
13688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  bool inside_with = scope_->IsInsideWith();
13698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Scope function_scope(&scope_, kFunctionScope);
13708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //  FormalParameterList ::
13718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //    '(' (Identifier)*[','] ')'
13728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::LPAREN, CHECK_OK);
1373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int start_position = scanner_->location().beg_pos;
13748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  bool done = (peek() == i::Token::RPAREN);
1375589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DuplicateFinder duplicate_finder(scanner_->unicode_cache());
13768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  while (!done) {
1377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Identifier id = ParseIdentifier(CHECK_OK);
1378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!id.IsValidStrictVariable()) {
1379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      StrictModeIdentifierViolation(scanner_->location(),
1380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    "strict_param_name",
1381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    id,
1382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    CHECK_OK);
1383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1384589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int prev_value;
1385589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (scanner_->is_literal_ascii()) {
1386589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      prev_value =
1387589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1);
1388589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
1389589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      prev_value =
13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1);
1391589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1392589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1393589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (prev_value != 0) {
1394589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      SetStrictModeViolation(scanner_->location(),
1395589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                             "strict_param_dupe",
1396589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                             CHECK_OK);
1397589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
13988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    done = (peek() == i::Token::RPAREN);
13998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (!done) {
14008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Expect(i::Token::COMMA, CHECK_OK);
14018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    }
14028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
14038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::RPAREN, CHECK_OK);
14048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Determine if the function will be lazily compiled.
14068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Currently only happens to top-level functions.
14078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Optimistically assume that all top-level functions are lazily compiled.
1408b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1409b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                             !inside_with && allow_lazy_ &&
1410b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                             !parenthesized_function_);
1411b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  parenthesized_function_ = false;
14128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expect(i::Token::LBRACE, CHECK_OK);
14148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (is_lazily_compiled) {
14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ParseLazyFunctionLiteralBody(CHECK_OK);
141685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  } else {
14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ParseSourceElements(i::Token::RBRACE, ok);
14188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
14193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expect(i::Token::RBRACE, CHECK_OK);
1420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!is_classic_mode()) {
1422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int end_position = scanner_->location().end_pos;
1423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CheckOctalLiteral(start_position, end_position, CHECK_OK);
1424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::StrictFunction();
1426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
14298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
14333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int body_start = scanner_->location().beg_pos;
14343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  log_->PauseRecording();
14353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ParseSourceElements(i::Token::RBRACE, ok);
14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  log_->ResumeRecording();
14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!*ok) return;
14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Position right after terminal '}'.
14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int body_end = scanner_->peek_location().end_pos;
14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  log_->LogFunction(body_start, body_end,
14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    scope_->materialized_literal_count(),
14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    scope_->expected_properties(),
14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    language_mode());
14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
14508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // CallRuntime ::
14518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //   '%' Identifier Arguments
14528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::MOD, CHECK_OK);
14533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!allow_natives_syntax_) {
14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    *ok = false;
14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Expression::Default();
14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
14578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  ParseIdentifier(CHECK_OK);
1458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ParseArguments(ok);
14598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::Default();
14618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_OK
1464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
14658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid PreParser::ExpectSemicolon(bool* ok) {
14678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Check for automatic semicolon insertion according to
14688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // the rules given in ECMA-262, section 7.9, page 21.
14698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value tok = peek();
14708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (tok == i::Token::SEMICOLON) {
14718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    Next();
14728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return;
14738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
14743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (scanner_->HasAnyLineTerminatorBeforeNext() ||
14758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok == i::Token::RBRACE ||
14768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      tok == i::Token::EOS) {
14778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return;
14788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
14798a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Expect(i::Token::SEMICOLON, ok);
14808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Blockvoid PreParser::LogSymbol() {
14848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int identifier_pos = scanner_->location().beg_pos;
14859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (scanner_->is_literal_ascii()) {
14869fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
14879fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  } else {
14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
14899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
14909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block}
14918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochPreParser::Expression PreParser::GetStringSymbol() {
1494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kUseStrictLength = 10;
1495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const char* kUseStrictChars = "use strict";
14969fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  LogSymbol();
1497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (scanner_->is_literal_ascii() &&
1498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      scanner_->literal_length() == kUseStrictLength &&
1499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      !scanner_->literal_contains_escapes() &&
1500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
1501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch               kUseStrictLength)) {
1502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Expression::UseStrictStringLiteral();
1503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Expression::StringLiteral();
15058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
15068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
15078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochPreParser::Identifier PreParser::GetIdentifierSymbol() {
15099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  LogSymbol();
1510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Identifier::FutureReserved();
15123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else if (scanner_->current_token() ==
15133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch             i::Token::FUTURE_STRICT_RESERVED_WORD) {
15143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return Identifier::FutureStrictReserved();
1515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (scanner_->is_literal_ascii()) {
1517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Detect strict-mode poison words.
1518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (scanner_->literal_length() == 4 &&
1519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
1520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Identifier::Eval();
1521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (scanner_->literal_length() == 9 &&
1523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
1524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return Identifier::Arguments();
1525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Identifier::Default();
15288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
15298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
15308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
15323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Token::Value next = Next();
15333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  switch (next) {
15343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    case i::Token::FUTURE_RESERVED_WORD: {
15353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::Scanner::Location location = scanner_->location();
15363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ReportMessageAt(location.beg_pos, location.end_pos,
15373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                      "reserved_word", NULL);
15383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      *ok = false;
15393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return GetIdentifierSymbol();
15403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
154185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    case i::Token::FUTURE_STRICT_RESERVED_WORD:
15423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!is_classic_mode()) {
15433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        i::Scanner::Location location = scanner_->location();
15443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ReportMessageAt(location.beg_pos, location.end_pos,
15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        "strict_reserved_word", NULL);
15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *ok = false;
15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // FALLTHROUGH
15493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    case i::Token::IDENTIFIER:
15503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return GetIdentifierSymbol();
15513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    default:
15523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      *ok = false;
15533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return Identifier::Default();
15541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
15558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
15568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
15578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid PreParser::SetStrictModeViolation(i::Scanner::Location location,
1559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       const char* type,
1560257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       bool* ok) {
15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!is_classic_mode()) {
1562589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(location, type, NULL);
1563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
1564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return;
1565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Delay report in case this later turns out to be strict code
1567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // (i.e., for function names and parameters prior to a "use strict"
1568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // directive).
1569589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // It's safe to overwrite an existing violation.
1570589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // It's either from a function that turned out to be non-strict,
1571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // or it's in the current function (and we just need to report
1572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // one error), or it's in a unclosed nesting function that wasn't
1573589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // strict (otherwise we would already be in strict mode).
1574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  strict_mode_violation_location_ = location;
1575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  strict_mode_violation_type_ = type;
1576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                int end_pos,
1581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                bool* ok) {
1582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Scanner::Location location = strict_mode_violation_location_;
1583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (location.IsValid() &&
1584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      location.beg_pos > beg_pos && location.end_pos < end_pos) {
1585589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(location, strict_mode_violation_type_, NULL);
1586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                              const char* eval_args_type,
1593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                              Identifier identifier,
1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                              bool* ok) {
1595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const char* type = eval_args_type;
1596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (identifier.IsFutureReserved()) {
15973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    type = "reserved_word";
15983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else if (identifier.IsFutureStrictReserved()) {
1599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    type = "strict_reserved_word";
1600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
16013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!is_classic_mode()) {
1602589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ReportMessageAt(location, type, NULL);
1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    *ok = false;
1604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return;
1605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  strict_mode_violation_location_ = location;
1607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  strict_mode_violation_type_ = type;
1608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochPreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
16128a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Token::Value next = Next();
16138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (i::Token::IsKeyword(next)) {
16148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    int pos = scanner_->location().beg_pos;
16158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    const char* keyword = i::Token::String(next);
16169fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
16179fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                                    i::StrLength(keyword)));
1618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Identifier::Default();
16198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
16201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (next == i::Token::IDENTIFIER ||
16213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      next == i::Token::FUTURE_RESERVED_WORD ||
16223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
16238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    return GetIdentifierSymbol();
16248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
16258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  *ok = false;
1626257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Identifier::Default();
16278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
16288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1629257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#undef CHECK_OK
1630257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
16318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
16328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// This function reads an identifier and determines whether or not it
16331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// is 'get' or 'set'.
16343fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochPreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
16353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                               bool* is_set,
16363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                               bool* ok) {
16373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Identifier result = ParseIdentifierName(ok);
1638257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!*ok) return Identifier::Default();
1639257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (scanner_->is_literal_ascii() &&
1640257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      scanner_->literal_length() == 3) {
16419fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    const char* token = scanner_->literal_ascii_string().start();
16428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *is_get = strncmp(token, "get", 3) == 0;
16438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    *is_set = !*is_get && strncmp(token, "set", 3) == 0;
16448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
16451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return result;
16461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
16471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
16481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockbool PreParser::peek_any_identifier() {
16491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Token::Value next = peek();
16501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return next == i::Token::IDENTIFIER ||
16513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch         next == i::Token::FUTURE_RESERVED_WORD ||
16523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch         next == i::Token::FUTURE_STRICT_RESERVED_WORD;
16538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
1654589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1655589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1656589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) {
1657589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return AddSymbol(i::Vector<const byte>::cast(key), true, value);
1658589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1659589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
16603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) {
1661589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return AddSymbol(i::Vector<const byte>::cast(key), false, value);
1662589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1663589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1664589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint DuplicateFinder::AddSymbol(i::Vector<const byte> key,
1665589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               bool is_ascii,
1666589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               int value) {
1667589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uint32_t hash = Hash(key, is_ascii);
1668589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  byte* encoding = BackupKey(key, is_ascii);
1669589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  i::HashMap::Entry* entry = map_.Lookup(encoding, hash, true);
1670589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
1671589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  entry->value =
1672589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value));
1673589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return old_value;
1674589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1675589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1676589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1677589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint DuplicateFinder::AddNumber(i::Vector<const char> key, int value) {
1678589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(key.length() > 0);
1679589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Quick check for already being in canonical form.
1680589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IsNumberCanonical(key)) {
1681589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return AddAsciiSymbol(key, value);
1682589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1684589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int flags = i::ALLOW_HEX | i::ALLOW_OCTALS;
1685589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  double double_value = StringToDouble(unicode_constants_, key, flags, 0.0);
1686589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int length;
1687589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  const char* string;
1688589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!isfinite(double_value)) {
1689589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    string = "Infinity";
1690589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    length = 8;  // strlen("Infinity");
1691589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
1692589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    string = DoubleToCString(double_value,
1693589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                             i::Vector<char>(number_buffer_, kBufferSize));
1694589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    length = i::StrLength(string);
1695589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1696589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return AddSymbol(i::Vector<const byte>(reinterpret_cast<const byte*>(string),
1697589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                         length), true, value);
1698589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1699589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1700589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1701589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbool DuplicateFinder::IsNumberCanonical(i::Vector<const char> number) {
1702589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Test for a safe approximation of number literals that are already
1703589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // in canonical form: max 15 digits, no leading zeroes, except an
1704589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // integer part that is a single zero, and no trailing zeros below
1705589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // the decimal point.
1706589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int pos = 0;
1707589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int length = number.length();
1708589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (number.length() > 15) return false;
1709589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (number[pos] == '0') {
1710589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    pos++;
1711589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
1712589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    while (pos < length &&
1713589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch           static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++;
1714589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1715589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (length == pos) return true;
1716589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (number[pos] != '.') return false;
1717589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  pos++;
1718589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  bool invalid_last_digit = true;
1719589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (pos < length) {
1720589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    byte digit = number[pos] - '0';
1721589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (digit > '9' - '0') return false;
1722589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    invalid_last_digit = (digit == 0);
1723589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    pos++;
1724589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1725589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return !invalid_last_digit;
1726589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1727589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1728589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1729589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochuint32_t DuplicateFinder::Hash(i::Vector<const byte> key, bool is_ascii) {
1730589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Primitive hash function, almost identical to the one used
1731589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // for strings (except that it's seeded by the length and ASCII-ness).
1732589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int length = key.length();
1733589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ;
1734589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (int i = 0; i < length; i++) {
1735589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uint32_t c = key[i];
1736589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    hash = (hash + c) * 1025;
1737589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    hash ^= (hash >> 6);
1738589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1739589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return hash;
1740589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1741589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1742589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1743589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbool DuplicateFinder::Match(void* first, void* second) {
1744589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Decode lengths.
1745589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Length + ASCII-bit is encoded as base 128, most significant heptet first,
1746589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // with a 8th bit being non-zero while there are more heptets.
1747589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The value encodes the number of bytes following, and whether the original
1748589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // was ASCII.
1749589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  byte* s1 = reinterpret_cast<byte*>(first);
1750589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  byte* s2 = reinterpret_cast<byte*>(second);
1751589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uint32_t length_ascii_field = 0;
1752589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  byte c1;
1753589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  do {
1754589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    c1 = *s1;
1755589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c1 != *s2) return false;
1756589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f);
1757589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    s1++;
1758589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    s2++;
1759589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } while ((c1 & 0x80) != 0);
1760589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int length = static_cast<int>(length_ascii_field >> 1);
1761589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return memcmp(s1, s2, length) == 0;
1762589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1763589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1764589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1765589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochbyte* DuplicateFinder::BackupKey(i::Vector<const byte> bytes,
1766589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                 bool is_ascii) {
1767589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uint32_t ascii_length = (bytes.length() << 1) | (is_ascii ? 1 : 0);
1768589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  backing_store_.StartSequence();
1769589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Emit ascii_length as base-128 encoded number, with the 7th bit set
1770589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // on the byte of every heptet except the last, least significant, one.
1771589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (ascii_length >= (1 << 7)) {
1772589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (ascii_length >= (1 << 14)) {
1773589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (ascii_length >= (1 << 21)) {
1774589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (ascii_length >= (1 << 28)) {
1775589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          backing_store_.Add(static_cast<byte>((ascii_length >> 28) | 0x80));
1776589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
1777589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        backing_store_.Add(static_cast<byte>((ascii_length >> 21) | 0x80u));
1778589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
1779589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u));
1780589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1781589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u));
1782589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1783589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  backing_store_.Add(static_cast<byte>(ascii_length & 0x7f));
1784589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1785589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  backing_store_.AddBlock(bytes);
1786589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return backing_store_.EndSequence().start();
1787589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
17888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} }  // v8::preparser
1789