Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <cmath>
     29 
     30 #include "../include/v8stdint.h"
     31 
     32 #include "allocation.h"
     33 #include "checks.h"
     34 #include "conversions.h"
     35 #include "conversions-inl.h"
     36 #include "globals.h"
     37 #include "hashmap.h"
     38 #include "list.h"
     39 #include "preparse-data-format.h"
     40 #include "preparse-data.h"
     41 #include "preparser.h"
     42 #include "unicode.h"
     43 #include "utils.h"
     44 
     45 #if V8_CC_MSVC && (_MSC_VER < 1800)
     46 namespace std {
     47 
     48 // Usually defined in math.h, but not in MSVC until VS2013+.
     49 // Abstracted to work
     50 int isfinite(double value);
     51 
     52 }  // namespace std
     53 #endif
     54 
     55 namespace v8 {
     56 namespace internal {
     57 
     58 PreParser::PreParseResult PreParser::PreParseLazyFunction(
     59     LanguageMode mode, bool is_generator, ParserRecorder* log) {
     60   log_ = log;
     61   // Lazy functions always have trivial outer scopes (no with/catch scopes).
     62   Scope top_scope(&scope_, kTopLevelScope);
     63   set_language_mode(mode);
     64   Scope function_scope(&scope_, kFunctionScope);
     65   function_scope.set_is_generator(is_generator);
     66   ASSERT_EQ(Token::LBRACE, scanner()->current_token());
     67   bool ok = true;
     68   int start_position = peek_position();
     69   ParseLazyFunctionLiteralBody(&ok);
     70   if (stack_overflow()) return kPreParseStackOverflow;
     71   if (!ok) {
     72     ReportUnexpectedToken(scanner()->current_token());
     73   } else {
     74     ASSERT_EQ(Token::RBRACE, scanner()->peek());
     75     if (!is_classic_mode()) {
     76       int end_pos = scanner()->location().end_pos;
     77       CheckOctalLiteral(start_position, end_pos, &ok);
     78       if (ok) {
     79         CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
     80       }
     81     }
     82   }
     83   return kPreParseSuccess;
     84 }
     85 
     86 
     87 // Preparsing checks a JavaScript program and emits preparse-data that helps
     88 // a later parsing to be faster.
     89 // See preparser-data.h for the data.
     90 
     91 // The PreParser checks that the syntax follows the grammar for JavaScript,
     92 // and collects some information about the program along the way.
     93 // The grammar check is only performed in order to understand the program
     94 // sufficiently to deduce some information about it, that can be used
     95 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
     96 // rather it is to speed up properly written and correct programs.
     97 // That means that contextual checks (like a label being declared where
     98 // it is used) are generally omitted.
     99 
    100 void PreParser::ReportUnexpectedToken(Token::Value token) {
    101   // We don't report stack overflows here, to avoid increasing the
    102   // stack depth even further.  Instead we report it after parsing is
    103   // over, in ParseProgram.
    104   if (token == Token::ILLEGAL && stack_overflow()) {
    105     return;
    106   }
    107   Scanner::Location source_location = scanner()->location();
    108 
    109   // Four of the tokens are treated specially
    110   switch (token) {
    111   case Token::EOS:
    112     return ReportMessageAt(source_location, "unexpected_eos", NULL);
    113   case Token::NUMBER:
    114     return ReportMessageAt(source_location, "unexpected_token_number", NULL);
    115   case Token::STRING:
    116     return ReportMessageAt(source_location, "unexpected_token_string", NULL);
    117   case Token::IDENTIFIER:
    118     return ReportMessageAt(source_location,
    119                            "unexpected_token_identifier", NULL);
    120   case Token::FUTURE_RESERVED_WORD:
    121     return ReportMessageAt(source_location, "unexpected_reserved", NULL);
    122   case Token::FUTURE_STRICT_RESERVED_WORD:
    123     return ReportMessageAt(source_location,
    124                            "unexpected_strict_reserved", NULL);
    125   default:
    126     const char* name = Token::String(token);
    127     ReportMessageAt(source_location, "unexpected_token", name);
    128   }
    129 }
    130 
    131 
    132 #define CHECK_OK  ok);                      \
    133   if (!*ok) return kUnknownSourceElements;  \
    134   ((void)0
    135 #define DUMMY )  // to make indentation work
    136 #undef DUMMY
    137 
    138 
    139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
    140   // (Ecma 262 5th Edition, clause 14):
    141   // SourceElement:
    142   //    Statement
    143   //    FunctionDeclaration
    144   //
    145   // In harmony mode we allow additionally the following productions
    146   // SourceElement:
    147   //    LetDeclaration
    148   //    ConstDeclaration
    149   //    GeneratorDeclaration
    150 
    151   switch (peek()) {
    152     case Token::FUNCTION:
    153       return ParseFunctionDeclaration(ok);
    154     case Token::LET:
    155     case Token::CONST:
    156       return ParseVariableStatement(kSourceElement, ok);
    157     default:
    158       return ParseStatement(ok);
    159   }
    160 }
    161 
    162 
    163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
    164                                                          bool* ok) {
    165   // SourceElements ::
    166   //   (Statement)* <end_token>
    167 
    168   bool allow_directive_prologue = true;
    169   while (peek() != end_token) {
    170     Statement statement = ParseSourceElement(CHECK_OK);
    171     if (allow_directive_prologue) {
    172       if (statement.IsUseStrictLiteral()) {
    173         set_language_mode(allow_harmony_scoping() ?
    174                           EXTENDED_MODE : STRICT_MODE);
    175       } else if (!statement.IsStringLiteral()) {
    176         allow_directive_prologue = false;
    177       }
    178     }
    179   }
    180   return kUnknownSourceElements;
    181 }
    182 
    183 
    184 #undef CHECK_OK
    185 #define CHECK_OK  ok);                   \
    186   if (!*ok) return Statement::Default();  \
    187   ((void)0
    188 #define DUMMY )  // to make indentation work
    189 #undef DUMMY
    190 
    191 
    192 PreParser::Statement PreParser::ParseStatement(bool* ok) {
    193   // Statement ::
    194   //   Block
    195   //   VariableStatement
    196   //   EmptyStatement
    197   //   ExpressionStatement
    198   //   IfStatement
    199   //   IterationStatement
    200   //   ContinueStatement
    201   //   BreakStatement
    202   //   ReturnStatement
    203   //   WithStatement
    204   //   LabelledStatement
    205   //   SwitchStatement
    206   //   ThrowStatement
    207   //   TryStatement
    208   //   DebuggerStatement
    209 
    210   // Note: Since labels can only be used by 'break' and 'continue'
    211   // statements, which themselves are only valid within blocks,
    212   // iterations or 'switch' statements (i.e., BreakableStatements),
    213   // labels can be simply ignored in all other cases; except for
    214   // trivial labeled break statements 'label: break label' which is
    215   // parsed into an empty statement.
    216 
    217   // Keep the source position of the statement
    218   switch (peek()) {
    219     case Token::LBRACE:
    220       return ParseBlock(ok);
    221 
    222     case Token::CONST:
    223     case Token::LET:
    224     case Token::VAR:
    225       return ParseVariableStatement(kStatement, ok);
    226 
    227     case Token::SEMICOLON:
    228       Next();
    229       return Statement::Default();
    230 
    231     case Token::IF:
    232       return ParseIfStatement(ok);
    233 
    234     case Token::DO:
    235       return ParseDoWhileStatement(ok);
    236 
    237     case Token::WHILE:
    238       return ParseWhileStatement(ok);
    239 
    240     case Token::FOR:
    241       return ParseForStatement(ok);
    242 
    243     case Token::CONTINUE:
    244       return ParseContinueStatement(ok);
    245 
    246     case Token::BREAK:
    247       return ParseBreakStatement(ok);
    248 
    249     case Token::RETURN:
    250       return ParseReturnStatement(ok);
    251 
    252     case Token::WITH:
    253       return ParseWithStatement(ok);
    254 
    255     case Token::SWITCH:
    256       return ParseSwitchStatement(ok);
    257 
    258     case Token::THROW:
    259       return ParseThrowStatement(ok);
    260 
    261     case Token::TRY:
    262       return ParseTryStatement(ok);
    263 
    264     case Token::FUNCTION: {
    265       Scanner::Location start_location = scanner()->peek_location();
    266       Statement statement = ParseFunctionDeclaration(CHECK_OK);
    267       Scanner::Location end_location = scanner()->location();
    268       if (!is_classic_mode()) {
    269         ReportMessageAt(start_location.beg_pos, end_location.end_pos,
    270                         "strict_function", NULL);
    271         *ok = false;
    272         return Statement::Default();
    273       } else {
    274         return statement;
    275       }
    276     }
    277 
    278     case Token::DEBUGGER:
    279       return ParseDebuggerStatement(ok);
    280 
    281     default:
    282       return ParseExpressionOrLabelledStatement(ok);
    283   }
    284 }
    285 
    286 
    287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
    288   // FunctionDeclaration ::
    289   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
    290   // GeneratorDeclaration ::
    291   //   'function' '*' Identifier '(' FormalParameterListopt ')'
    292   //      '{' FunctionBody '}'
    293   Expect(Token::FUNCTION, CHECK_OK);
    294 
    295   bool is_generator = allow_generators() && Check(Token::MUL);
    296   Identifier identifier = ParseIdentifier(CHECK_OK);
    297   Scanner::Location location = scanner()->location();
    298 
    299   Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
    300 
    301   if (function_value.IsStrictFunction() &&
    302       !identifier.IsValidStrictVariable()) {
    303     // Strict mode violation, using either reserved word or eval/arguments
    304     // as name of strict function.
    305     const char* type = "strict_function_name";
    306     if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
    307       type = "strict_reserved_word";
    308     }
    309     ReportMessageAt(location, type, NULL);
    310     *ok = false;
    311   }
    312   return Statement::FunctionDeclaration();
    313 }
    314 
    315 
    316 PreParser::Statement PreParser::ParseBlock(bool* ok) {
    317   // Block ::
    318   //   '{' Statement* '}'
    319 
    320   // Note that a Block does not introduce a new execution scope!
    321   // (ECMA-262, 3rd, 12.2)
    322   //
    323   Expect(Token::LBRACE, CHECK_OK);
    324   while (peek() != Token::RBRACE) {
    325     if (is_extended_mode()) {
    326       ParseSourceElement(CHECK_OK);
    327     } else {
    328       ParseStatement(CHECK_OK);
    329     }
    330   }
    331   Expect(Token::RBRACE, ok);
    332   return Statement::Default();
    333 }
    334 
    335 
    336 PreParser::Statement PreParser::ParseVariableStatement(
    337     VariableDeclarationContext var_context,
    338     bool* ok) {
    339   // VariableStatement ::
    340   //   VariableDeclarations ';'
    341 
    342   Statement result = ParseVariableDeclarations(var_context,
    343                                                NULL,
    344                                                NULL,
    345                                                CHECK_OK);
    346   ExpectSemicolon(CHECK_OK);
    347   return result;
    348 }
    349 
    350 
    351 // If the variable declaration declares exactly one non-const
    352 // variable, then *var is set to that variable. In all other cases,
    353 // *var is untouched; in particular, it is the caller's responsibility
    354 // to initialize it properly. This mechanism is also used for the parsing
    355 // of 'for-in' loops.
    356 PreParser::Statement PreParser::ParseVariableDeclarations(
    357     VariableDeclarationContext var_context,
    358     VariableDeclarationProperties* decl_props,
    359     int* num_decl,
    360     bool* ok) {
    361   // VariableDeclarations ::
    362   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
    363   //
    364   // The ES6 Draft Rev3 specifies the following grammar for const declarations
    365   //
    366   // ConstDeclaration ::
    367   //   const ConstBinding (',' ConstBinding)* ';'
    368   // ConstBinding ::
    369   //   Identifier '=' AssignmentExpression
    370   //
    371   // TODO(ES6):
    372   // ConstBinding ::
    373   //   BindingPattern '=' AssignmentExpression
    374   bool require_initializer = false;
    375   if (peek() == Token::VAR) {
    376     Consume(Token::VAR);
    377   } else if (peek() == Token::CONST) {
    378     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
    379     //
    380     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
    381     //
    382     // * It is a Syntax Error if the code that matches this production is not
    383     //   contained in extended code.
    384     //
    385     // However disallowing const in classic mode will break compatibility with
    386     // existing pages. Therefore we keep allowing const with the old
    387     // non-harmony semantics in classic mode.
    388     Consume(Token::CONST);
    389     switch (language_mode()) {
    390       case CLASSIC_MODE:
    391         break;
    392       case STRICT_MODE: {
    393         Scanner::Location location = scanner()->peek_location();
    394         ReportMessageAt(location, "strict_const", NULL);
    395         *ok = false;
    396         return Statement::Default();
    397       }
    398       case EXTENDED_MODE:
    399         if (var_context != kSourceElement &&
    400             var_context != kForStatement) {
    401           Scanner::Location location = scanner()->peek_location();
    402           ReportMessageAt(location.beg_pos, location.end_pos,
    403                           "unprotected_const", NULL);
    404           *ok = false;
    405           return Statement::Default();
    406         }
    407         require_initializer = true;
    408         break;
    409     }
    410   } else if (peek() == Token::LET) {
    411     // ES6 Draft Rev4 section 12.2.1:
    412     //
    413     // LetDeclaration : let LetBindingList ;
    414     //
    415     // * It is a Syntax Error if the code that matches this production is not
    416     //   contained in extended code.
    417     if (!is_extended_mode()) {
    418       Scanner::Location location = scanner()->peek_location();
    419       ReportMessageAt(location.beg_pos, location.end_pos,
    420                       "illegal_let", NULL);
    421       *ok = false;
    422       return Statement::Default();
    423     }
    424     Consume(Token::LET);
    425     if (var_context != kSourceElement &&
    426         var_context != kForStatement) {
    427       Scanner::Location location = scanner()->peek_location();
    428       ReportMessageAt(location.beg_pos, location.end_pos,
    429                       "unprotected_let", NULL);
    430       *ok = false;
    431       return Statement::Default();
    432     }
    433   } else {
    434     *ok = false;
    435     return Statement::Default();
    436   }
    437 
    438   // The scope of a var/const declared variable anywhere inside a function
    439   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
    440   // of a let declared variable is the scope of the immediately enclosing
    441   // block.
    442   int nvars = 0;  // the number of variables declared
    443   do {
    444     // Parse variable name.
    445     if (nvars > 0) Consume(Token::COMMA);
    446     Identifier identifier  = ParseIdentifier(CHECK_OK);
    447     if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
    448       StrictModeIdentifierViolation(scanner()->location(),
    449                                     "strict_var_name",
    450                                     identifier,
    451                                     ok);
    452       return Statement::Default();
    453     }
    454     nvars++;
    455     if (peek() == Token::ASSIGN || require_initializer) {
    456       Expect(Token::ASSIGN, CHECK_OK);
    457       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
    458       if (decl_props != NULL) *decl_props = kHasInitializers;
    459     }
    460   } while (peek() == Token::COMMA);
    461 
    462   if (num_decl != NULL) *num_decl = nvars;
    463   return Statement::Default();
    464 }
    465 
    466 
    467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
    468   // ExpressionStatement | LabelledStatement ::
    469   //   Expression ';'
    470   //   Identifier ':' Statement
    471 
    472   Expression expr = ParseExpression(true, CHECK_OK);
    473   if (expr.IsRawIdentifier()) {
    474     ASSERT(!expr.AsIdentifier().IsFutureReserved());
    475     ASSERT(is_classic_mode() ||
    476            (!expr.AsIdentifier().IsFutureStrictReserved() &&
    477             !expr.AsIdentifier().IsYield()));
    478     if (peek() == Token::COLON) {
    479       Consume(Token::COLON);
    480       return ParseStatement(ok);
    481     }
    482     // Preparsing is disabled for extensions (because the extension details
    483     // aren't passed to lazily compiled functions), so we don't
    484     // accept "native function" in the preparser.
    485   }
    486   // Parsed expression statement.
    487   ExpectSemicolon(CHECK_OK);
    488   return Statement::ExpressionStatement(expr);
    489 }
    490 
    491 
    492 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
    493   // IfStatement ::
    494   //   'if' '(' Expression ')' Statement ('else' Statement)?
    495 
    496   Expect(Token::IF, CHECK_OK);
    497   Expect(Token::LPAREN, CHECK_OK);
    498   ParseExpression(true, CHECK_OK);
    499   Expect(Token::RPAREN, CHECK_OK);
    500   ParseStatement(CHECK_OK);
    501   if (peek() == Token::ELSE) {
    502     Next();
    503     ParseStatement(CHECK_OK);
    504   }
    505   return Statement::Default();
    506 }
    507 
    508 
    509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
    510   // ContinueStatement ::
    511   //   'continue' [no line terminator] Identifier? ';'
    512 
    513   Expect(Token::CONTINUE, CHECK_OK);
    514   Token::Value tok = peek();
    515   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    516       tok != Token::SEMICOLON &&
    517       tok != Token::RBRACE &&
    518       tok != Token::EOS) {
    519     ParseIdentifier(CHECK_OK);
    520   }
    521   ExpectSemicolon(CHECK_OK);
    522   return Statement::Default();
    523 }
    524 
    525 
    526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
    527   // BreakStatement ::
    528   //   'break' [no line terminator] Identifier? ';'
    529 
    530   Expect(Token::BREAK, CHECK_OK);
    531   Token::Value tok = peek();
    532   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    533       tok != Token::SEMICOLON &&
    534       tok != Token::RBRACE &&
    535       tok != Token::EOS) {
    536     ParseIdentifier(CHECK_OK);
    537   }
    538   ExpectSemicolon(CHECK_OK);
    539   return Statement::Default();
    540 }
    541 
    542 
    543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
    544   // ReturnStatement ::
    545   //   'return' [no line terminator] Expression? ';'
    546 
    547   // Consume the return token. It is necessary to do the before
    548   // reporting any errors on it, because of the way errors are
    549   // reported (underlining).
    550   Expect(Token::RETURN, CHECK_OK);
    551 
    552   // An ECMAScript program is considered syntactically incorrect if it
    553   // contains a return statement that is not within the body of a
    554   // function. See ECMA-262, section 12.9, page 67.
    555   // This is not handled during preparsing.
    556 
    557   Token::Value tok = peek();
    558   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    559       tok != Token::SEMICOLON &&
    560       tok != Token::RBRACE &&
    561       tok != Token::EOS) {
    562     ParseExpression(true, CHECK_OK);
    563   }
    564   ExpectSemicolon(CHECK_OK);
    565   return Statement::Default();
    566 }
    567 
    568 
    569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
    570   // WithStatement ::
    571   //   'with' '(' Expression ')' Statement
    572   Expect(Token::WITH, CHECK_OK);
    573   if (!is_classic_mode()) {
    574     Scanner::Location location = scanner()->location();
    575     ReportMessageAt(location, "strict_mode_with", NULL);
    576     *ok = false;
    577     return Statement::Default();
    578   }
    579   Expect(Token::LPAREN, CHECK_OK);
    580   ParseExpression(true, CHECK_OK);
    581   Expect(Token::RPAREN, CHECK_OK);
    582 
    583   Scope::InsideWith iw(scope_);
    584   ParseStatement(CHECK_OK);
    585   return Statement::Default();
    586 }
    587 
    588 
    589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
    590   // SwitchStatement ::
    591   //   'switch' '(' Expression ')' '{' CaseClause* '}'
    592 
    593   Expect(Token::SWITCH, CHECK_OK);
    594   Expect(Token::LPAREN, CHECK_OK);
    595   ParseExpression(true, CHECK_OK);
    596   Expect(Token::RPAREN, CHECK_OK);
    597 
    598   Expect(Token::LBRACE, CHECK_OK);
    599   Token::Value token = peek();
    600   while (token != Token::RBRACE) {
    601     if (token == Token::CASE) {
    602       Expect(Token::CASE, CHECK_OK);
    603       ParseExpression(true, CHECK_OK);
    604     } else {
    605       Expect(Token::DEFAULT, CHECK_OK);
    606     }
    607     Expect(Token::COLON, CHECK_OK);
    608     token = peek();
    609     while (token != Token::CASE &&
    610            token != Token::DEFAULT &&
    611            token != Token::RBRACE) {
    612       ParseStatement(CHECK_OK);
    613       token = peek();
    614     }
    615   }
    616   Expect(Token::RBRACE, ok);
    617   return Statement::Default();
    618 }
    619 
    620 
    621 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
    622   // DoStatement ::
    623   //   'do' Statement 'while' '(' Expression ')' ';'
    624 
    625   Expect(Token::DO, CHECK_OK);
    626   ParseStatement(CHECK_OK);
    627   Expect(Token::WHILE, CHECK_OK);
    628   Expect(Token::LPAREN, CHECK_OK);
    629   ParseExpression(true, CHECK_OK);
    630   Expect(Token::RPAREN, ok);
    631   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
    632   return Statement::Default();
    633 }
    634 
    635 
    636 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
    637   // WhileStatement ::
    638   //   'while' '(' Expression ')' Statement
    639 
    640   Expect(Token::WHILE, CHECK_OK);
    641   Expect(Token::LPAREN, CHECK_OK);
    642   ParseExpression(true, CHECK_OK);
    643   Expect(Token::RPAREN, CHECK_OK);
    644   ParseStatement(ok);
    645   return Statement::Default();
    646 }
    647 
    648 
    649 bool PreParser::CheckInOrOf(bool accept_OF) {
    650   if (Check(Token::IN) ||
    651       (allow_for_of() && accept_OF &&
    652        CheckContextualKeyword(CStrVector("of")))) {
    653     return true;
    654   }
    655   return false;
    656 }
    657 
    658 
    659 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
    660   // ForStatement ::
    661   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
    662 
    663   Expect(Token::FOR, CHECK_OK);
    664   Expect(Token::LPAREN, CHECK_OK);
    665   if (peek() != Token::SEMICOLON) {
    666     if (peek() == Token::VAR || peek() == Token::CONST ||
    667         peek() == Token::LET) {
    668       bool is_let = peek() == Token::LET;
    669       int decl_count;
    670       VariableDeclarationProperties decl_props = kHasNoInitializers;
    671       ParseVariableDeclarations(
    672           kForStatement, &decl_props, &decl_count, CHECK_OK);
    673       bool has_initializers = decl_props == kHasInitializers;
    674       bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
    675       bool accept_OF = !has_initializers;
    676       if (accept_IN && CheckInOrOf(accept_OF)) {
    677         ParseExpression(true, CHECK_OK);
    678         Expect(Token::RPAREN, CHECK_OK);
    679 
    680         ParseStatement(CHECK_OK);
    681         return Statement::Default();
    682       }
    683     } else {
    684       Expression lhs = ParseExpression(false, CHECK_OK);
    685       if (CheckInOrOf(lhs.IsIdentifier())) {
    686         ParseExpression(true, CHECK_OK);
    687         Expect(Token::RPAREN, CHECK_OK);
    688 
    689         ParseStatement(CHECK_OK);
    690         return Statement::Default();
    691       }
    692     }
    693   }
    694 
    695   // Parsed initializer at this point.
    696   Expect(Token::SEMICOLON, CHECK_OK);
    697 
    698   if (peek() != Token::SEMICOLON) {
    699     ParseExpression(true, CHECK_OK);
    700   }
    701   Expect(Token::SEMICOLON, CHECK_OK);
    702 
    703   if (peek() != Token::RPAREN) {
    704     ParseExpression(true, CHECK_OK);
    705   }
    706   Expect(Token::RPAREN, CHECK_OK);
    707 
    708   ParseStatement(ok);
    709   return Statement::Default();
    710 }
    711 
    712 
    713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
    714   // ThrowStatement ::
    715   //   'throw' [no line terminator] Expression ';'
    716 
    717   Expect(Token::THROW, CHECK_OK);
    718   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
    719     Scanner::Location pos = scanner()->location();
    720     ReportMessageAt(pos, "newline_after_throw", NULL);
    721     *ok = false;
    722     return Statement::Default();
    723   }
    724   ParseExpression(true, CHECK_OK);
    725   ExpectSemicolon(ok);
    726   return Statement::Default();
    727 }
    728 
    729 
    730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
    731   // TryStatement ::
    732   //   'try' Block Catch
    733   //   'try' Block Finally
    734   //   'try' Block Catch Finally
    735   //
    736   // Catch ::
    737   //   'catch' '(' Identifier ')' Block
    738   //
    739   // Finally ::
    740   //   'finally' Block
    741 
    742   // In preparsing, allow any number of catch/finally blocks, including zero
    743   // of both.
    744 
    745   Expect(Token::TRY, CHECK_OK);
    746 
    747   ParseBlock(CHECK_OK);
    748 
    749   bool catch_or_finally_seen = false;
    750   if (peek() == Token::CATCH) {
    751     Consume(Token::CATCH);
    752     Expect(Token::LPAREN, CHECK_OK);
    753     Identifier id = ParseIdentifier(CHECK_OK);
    754     if (!is_classic_mode() && !id.IsValidStrictVariable()) {
    755       StrictModeIdentifierViolation(scanner()->location(),
    756                                     "strict_catch_variable",
    757                                     id,
    758                                     ok);
    759       return Statement::Default();
    760     }
    761     Expect(Token::RPAREN, CHECK_OK);
    762     { Scope::InsideWith iw(scope_);
    763       ParseBlock(CHECK_OK);
    764     }
    765     catch_or_finally_seen = true;
    766   }
    767   if (peek() == Token::FINALLY) {
    768     Consume(Token::FINALLY);
    769     ParseBlock(CHECK_OK);
    770     catch_or_finally_seen = true;
    771   }
    772   if (!catch_or_finally_seen) {
    773     *ok = false;
    774   }
    775   return Statement::Default();
    776 }
    777 
    778 
    779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
    780   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
    781   // contexts this is used as a statement which invokes the debugger as if a
    782   // break point is present.
    783   // DebuggerStatement ::
    784   //   'debugger' ';'
    785 
    786   Expect(Token::DEBUGGER, CHECK_OK);
    787   ExpectSemicolon(ok);
    788   return Statement::Default();
    789 }
    790 
    791 
    792 #undef CHECK_OK
    793 #define CHECK_OK  ok);                     \
    794   if (!*ok) return Expression::Default();  \
    795   ((void)0
    796 #define DUMMY )  // to make indentation work
    797 #undef DUMMY
    798 
    799 
    800 // Precedence = 1
    801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
    802   // Expression ::
    803   //   AssignmentExpression
    804   //   Expression ',' AssignmentExpression
    805 
    806   Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
    807   while (peek() == Token::COMMA) {
    808     Expect(Token::COMMA, CHECK_OK);
    809     ParseAssignmentExpression(accept_IN, CHECK_OK);
    810     result = Expression::Default();
    811   }
    812   return result;
    813 }
    814 
    815 
    816 // Precedence = 2
    817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
    818                                                            bool* ok) {
    819   // AssignmentExpression ::
    820   //   ConditionalExpression
    821   //   YieldExpression
    822   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
    823 
    824   if (scope_->is_generator() && peek() == Token::YIELD) {
    825     return ParseYieldExpression(ok);
    826   }
    827 
    828   Scanner::Location before = scanner()->peek_location();
    829   Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
    830 
    831   if (!Token::IsAssignmentOp(peek())) {
    832     // Parsed conditional expression only (no assignment).
    833     return expression;
    834   }
    835 
    836   if (!is_classic_mode() &&
    837       expression.IsIdentifier() &&
    838       expression.AsIdentifier().IsEvalOrArguments()) {
    839     Scanner::Location after = scanner()->location();
    840     ReportMessageAt(before.beg_pos, after.end_pos,
    841                     "strict_lhs_assignment", NULL);
    842     *ok = false;
    843     return Expression::Default();
    844   }
    845 
    846   Token::Value op = Next();  // Get assignment operator.
    847   ParseAssignmentExpression(accept_IN, CHECK_OK);
    848 
    849   if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
    850     scope_->AddProperty();
    851   }
    852 
    853   return Expression::Default();
    854 }
    855 
    856 
    857 // Precedence = 3
    858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
    859   // YieldExpression ::
    860   //   'yield' '*'? AssignmentExpression
    861   Consume(Token::YIELD);
    862   Check(Token::MUL);
    863 
    864   ParseAssignmentExpression(false, CHECK_OK);
    865 
    866   return Expression::Default();
    867 }
    868 
    869 
    870 // Precedence = 3
    871 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
    872                                                             bool* ok) {
    873   // ConditionalExpression ::
    874   //   LogicalOrExpression
    875   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
    876 
    877   // We start using the binary expression parser for prec >= 4 only!
    878   Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
    879   if (peek() != Token::CONDITIONAL) return expression;
    880   Consume(Token::CONDITIONAL);
    881   // In parsing the first assignment expression in conditional
    882   // expressions we always accept the 'in' keyword; see ECMA-262,
    883   // section 11.12, page 58.
    884   ParseAssignmentExpression(true, CHECK_OK);
    885   Expect(Token::COLON, CHECK_OK);
    886   ParseAssignmentExpression(accept_IN, CHECK_OK);
    887   return Expression::Default();
    888 }
    889 
    890 
    891 // Precedence >= 4
    892 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
    893                                                        bool accept_IN,
    894                                                        bool* ok) {
    895   Expression result = ParseUnaryExpression(CHECK_OK);
    896   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
    897     // prec1 >= 4
    898     while (Precedence(peek(), accept_IN) == prec1) {
    899       Next();
    900       ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
    901       result = Expression::Default();
    902     }
    903   }
    904   return result;
    905 }
    906 
    907 
    908 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
    909   // UnaryExpression ::
    910   //   PostfixExpression
    911   //   'delete' UnaryExpression
    912   //   'void' UnaryExpression
    913   //   'typeof' UnaryExpression
    914   //   '++' UnaryExpression
    915   //   '--' UnaryExpression
    916   //   '+' UnaryExpression
    917   //   '-' UnaryExpression
    918   //   '~' UnaryExpression
    919   //   '!' UnaryExpression
    920 
    921   Token::Value op = peek();
    922   if (Token::IsUnaryOp(op)) {
    923     op = Next();
    924     ParseUnaryExpression(ok);
    925     return Expression::Default();
    926   } else if (Token::IsCountOp(op)) {
    927     op = Next();
    928     Scanner::Location before = scanner()->peek_location();
    929     Expression expression = ParseUnaryExpression(CHECK_OK);
    930     if (!is_classic_mode() &&
    931         expression.IsIdentifier() &&
    932         expression.AsIdentifier().IsEvalOrArguments()) {
    933       Scanner::Location after = scanner()->location();
    934       ReportMessageAt(before.beg_pos, after.end_pos,
    935                       "strict_lhs_prefix", NULL);
    936       *ok = false;
    937     }
    938     return Expression::Default();
    939   } else {
    940     return ParsePostfixExpression(ok);
    941   }
    942 }
    943 
    944 
    945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
    946   // PostfixExpression ::
    947   //   LeftHandSideExpression ('++' | '--')?
    948 
    949   Scanner::Location before = scanner()->peek_location();
    950   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
    951   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    952       Token::IsCountOp(peek())) {
    953     if (!is_classic_mode() &&
    954         expression.IsIdentifier() &&
    955         expression.AsIdentifier().IsEvalOrArguments()) {
    956       Scanner::Location after = scanner()->location();
    957       ReportMessageAt(before.beg_pos, after.end_pos,
    958                       "strict_lhs_postfix", NULL);
    959       *ok = false;
    960       return Expression::Default();
    961     }
    962     Next();
    963     return Expression::Default();
    964   }
    965   return expression;
    966 }
    967 
    968 
    969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
    970   // LeftHandSideExpression ::
    971   //   (NewExpression | MemberExpression) ...
    972 
    973   Expression result = Expression::Default();
    974   if (peek() == Token::NEW) {
    975     result = ParseNewExpression(CHECK_OK);
    976   } else {
    977     result = ParseMemberExpression(CHECK_OK);
    978   }
    979 
    980   while (true) {
    981     switch (peek()) {
    982       case Token::LBRACK: {
    983         Consume(Token::LBRACK);
    984         ParseExpression(true, CHECK_OK);
    985         Expect(Token::RBRACK, CHECK_OK);
    986         if (result.IsThis()) {
    987           result = Expression::ThisProperty();
    988         } else {
    989           result = Expression::Default();
    990         }
    991         break;
    992       }
    993 
    994       case Token::LPAREN: {
    995         ParseArguments(CHECK_OK);
    996         result = Expression::Default();
    997         break;
    998       }
    999 
   1000       case Token::PERIOD: {
   1001         Consume(Token::PERIOD);
   1002         ParseIdentifierName(CHECK_OK);
   1003         if (result.IsThis()) {
   1004           result = Expression::ThisProperty();
   1005         } else {
   1006           result = Expression::Default();
   1007         }
   1008         break;
   1009       }
   1010 
   1011       default:
   1012         return result;
   1013     }
   1014   }
   1015 }
   1016 
   1017 
   1018 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
   1019   // NewExpression ::
   1020   //   ('new')+ MemberExpression
   1021 
   1022   // The grammar for new expressions is pretty warped. The keyword
   1023   // 'new' can either be a part of the new expression (where it isn't
   1024   // followed by an argument list) or a part of the member expression,
   1025   // where it must be followed by an argument list. To accommodate
   1026   // this, we parse the 'new' keywords greedily and keep track of how
   1027   // many we have parsed. This information is then passed on to the
   1028   // member expression parser, which is only allowed to match argument
   1029   // lists as long as it has 'new' prefixes left
   1030   unsigned new_count = 0;
   1031   do {
   1032     Consume(Token::NEW);
   1033     new_count++;
   1034   } while (peek() == Token::NEW);
   1035 
   1036   return ParseMemberWithNewPrefixesExpression(new_count, ok);
   1037 }
   1038 
   1039 
   1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
   1041   return ParseMemberWithNewPrefixesExpression(0, ok);
   1042 }
   1043 
   1044 
   1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
   1046     unsigned new_count, bool* ok) {
   1047   // MemberExpression ::
   1048   //   (PrimaryExpression | FunctionLiteral)
   1049   //     ('[' Expression ']' | '.' Identifier | Arguments)*
   1050 
   1051   // Parse the initial primary or function expression.
   1052   Expression result = Expression::Default();
   1053   if (peek() == Token::FUNCTION) {
   1054     Consume(Token::FUNCTION);
   1055 
   1056     bool is_generator = allow_generators() && Check(Token::MUL);
   1057     Identifier identifier = Identifier::Default();
   1058     if (peek_any_identifier()) {
   1059       identifier = ParseIdentifier(CHECK_OK);
   1060     }
   1061     result = ParseFunctionLiteral(is_generator, CHECK_OK);
   1062     if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
   1063       StrictModeIdentifierViolation(scanner()->location(),
   1064                                     "strict_function_name",
   1065                                     identifier,
   1066                                     ok);
   1067       return Expression::Default();
   1068     }
   1069   } else {
   1070     result = ParsePrimaryExpression(CHECK_OK);
   1071   }
   1072 
   1073   while (true) {
   1074     switch (peek()) {
   1075       case Token::LBRACK: {
   1076         Consume(Token::LBRACK);
   1077         ParseExpression(true, CHECK_OK);
   1078         Expect(Token::RBRACK, CHECK_OK);
   1079         if (result.IsThis()) {
   1080           result = Expression::ThisProperty();
   1081         } else {
   1082           result = Expression::Default();
   1083         }
   1084         break;
   1085       }
   1086       case Token::PERIOD: {
   1087         Consume(Token::PERIOD);
   1088         ParseIdentifierName(CHECK_OK);
   1089         if (result.IsThis()) {
   1090           result = Expression::ThisProperty();
   1091         } else {
   1092           result = Expression::Default();
   1093         }
   1094         break;
   1095       }
   1096       case Token::LPAREN: {
   1097         if (new_count == 0) return result;
   1098         // Consume one of the new prefixes (already parsed).
   1099         ParseArguments(CHECK_OK);
   1100         new_count--;
   1101         result = Expression::Default();
   1102         break;
   1103       }
   1104       default:
   1105         return result;
   1106     }
   1107   }
   1108 }
   1109 
   1110 
   1111 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
   1112   // PrimaryExpression ::
   1113   //   'this'
   1114   //   'null'
   1115   //   'true'
   1116   //   'false'
   1117   //   Identifier
   1118   //   Number
   1119   //   String
   1120   //   ArrayLiteral
   1121   //   ObjectLiteral
   1122   //   RegExpLiteral
   1123   //   '(' Expression ')'
   1124 
   1125   Expression result = Expression::Default();
   1126   switch (peek()) {
   1127     case Token::THIS: {
   1128       Next();
   1129       result = Expression::This();
   1130       break;
   1131     }
   1132 
   1133     case Token::FUTURE_RESERVED_WORD:
   1134     case Token::FUTURE_STRICT_RESERVED_WORD:
   1135     case Token::YIELD:
   1136     case Token::IDENTIFIER: {
   1137       Identifier id = ParseIdentifier(CHECK_OK);
   1138       result = Expression::FromIdentifier(id);
   1139       break;
   1140     }
   1141 
   1142     case Token::NULL_LITERAL:
   1143     case Token::TRUE_LITERAL:
   1144     case Token::FALSE_LITERAL:
   1145     case Token::NUMBER: {
   1146       Next();
   1147       break;
   1148     }
   1149     case Token::STRING: {
   1150       Next();
   1151       result = GetStringSymbol();
   1152       break;
   1153     }
   1154 
   1155     case Token::ASSIGN_DIV:
   1156       result = ParseRegExpLiteral(true, CHECK_OK);
   1157       break;
   1158 
   1159     case Token::DIV:
   1160       result = ParseRegExpLiteral(false, CHECK_OK);
   1161       break;
   1162 
   1163     case Token::LBRACK:
   1164       result = ParseArrayLiteral(CHECK_OK);
   1165       break;
   1166 
   1167     case Token::LBRACE:
   1168       result = ParseObjectLiteral(CHECK_OK);
   1169       break;
   1170 
   1171     case Token::LPAREN:
   1172       Consume(Token::LPAREN);
   1173       parenthesized_function_ = (peek() == Token::FUNCTION);
   1174       result = ParseExpression(true, CHECK_OK);
   1175       Expect(Token::RPAREN, CHECK_OK);
   1176       result = result.Parenthesize();
   1177       break;
   1178 
   1179     case Token::MOD:
   1180       result = ParseV8Intrinsic(CHECK_OK);
   1181       break;
   1182 
   1183     default: {
   1184       Next();
   1185       *ok = false;
   1186       return Expression::Default();
   1187     }
   1188   }
   1189 
   1190   return result;
   1191 }
   1192 
   1193 
   1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
   1195   // ArrayLiteral ::
   1196   //   '[' Expression? (',' Expression?)* ']'
   1197   Expect(Token::LBRACK, CHECK_OK);
   1198   while (peek() != Token::RBRACK) {
   1199     if (peek() != Token::COMMA) {
   1200       ParseAssignmentExpression(true, CHECK_OK);
   1201     }
   1202     if (peek() != Token::RBRACK) {
   1203       Expect(Token::COMMA, CHECK_OK);
   1204     }
   1205   }
   1206   Expect(Token::RBRACK, CHECK_OK);
   1207 
   1208   scope_->NextMaterializedLiteralIndex();
   1209   return Expression::Default();
   1210 }
   1211 
   1212 
   1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
   1214   // ObjectLiteral ::
   1215   //   '{' (
   1216   //       ((IdentifierName | String | Number) ':' AssignmentExpression)
   1217   //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
   1218   //    )*[','] '}'
   1219 
   1220   ObjectLiteralChecker checker(this, language_mode());
   1221 
   1222   Expect(Token::LBRACE, CHECK_OK);
   1223   while (peek() != Token::RBRACE) {
   1224     Token::Value next = peek();
   1225     switch (next) {
   1226       case Token::IDENTIFIER:
   1227       case Token::FUTURE_RESERVED_WORD:
   1228       case Token::FUTURE_STRICT_RESERVED_WORD: {
   1229         bool is_getter = false;
   1230         bool is_setter = false;
   1231         ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
   1232         if ((is_getter || is_setter) && peek() != Token::COLON) {
   1233             Token::Value name = Next();
   1234             bool is_keyword = Token::IsKeyword(name);
   1235             if (name != Token::IDENTIFIER &&
   1236                 name != Token::FUTURE_RESERVED_WORD &&
   1237                 name != Token::FUTURE_STRICT_RESERVED_WORD &&
   1238                 name != Token::NUMBER &&
   1239                 name != Token::STRING &&
   1240                 !is_keyword) {
   1241               *ok = false;
   1242               return Expression::Default();
   1243             }
   1244             if (!is_keyword) {
   1245               LogSymbol();
   1246             }
   1247             PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
   1248             checker.CheckProperty(name, type, CHECK_OK);
   1249             ParseFunctionLiteral(false, CHECK_OK);
   1250             if (peek() != Token::RBRACE) {
   1251               Expect(Token::COMMA, CHECK_OK);
   1252             }
   1253             continue;  // restart the while
   1254         }
   1255         checker.CheckProperty(next, kValueProperty, CHECK_OK);
   1256         break;
   1257       }
   1258       case Token::STRING:
   1259         Consume(next);
   1260         checker.CheckProperty(next, kValueProperty, CHECK_OK);
   1261         GetStringSymbol();
   1262         break;
   1263       case Token::NUMBER:
   1264         Consume(next);
   1265         checker.CheckProperty(next, kValueProperty, CHECK_OK);
   1266         break;
   1267       default:
   1268         if (Token::IsKeyword(next)) {
   1269           Consume(next);
   1270           checker.CheckProperty(next, kValueProperty, CHECK_OK);
   1271         } else {
   1272           // Unexpected token.
   1273           *ok = false;
   1274           return Expression::Default();
   1275         }
   1276     }
   1277 
   1278     Expect(Token::COLON, CHECK_OK);
   1279     ParseAssignmentExpression(true, CHECK_OK);
   1280 
   1281     // TODO(1240767): Consider allowing trailing comma.
   1282     if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
   1283   }
   1284   Expect(Token::RBRACE, CHECK_OK);
   1285 
   1286   scope_->NextMaterializedLiteralIndex();
   1287   return Expression::Default();
   1288 }
   1289 
   1290 
   1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
   1292                                                     bool* ok) {
   1293   if (!scanner()->ScanRegExpPattern(seen_equal)) {
   1294     Next();
   1295     ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
   1296     *ok = false;
   1297     return Expression::Default();
   1298   }
   1299 
   1300   scope_->NextMaterializedLiteralIndex();
   1301 
   1302   if (!scanner()->ScanRegExpFlags()) {
   1303     Next();
   1304     ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
   1305     *ok = false;
   1306     return Expression::Default();
   1307   }
   1308   Next();
   1309   return Expression::Default();
   1310 }
   1311 
   1312 
   1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
   1314   // Arguments ::
   1315   //   '(' (AssignmentExpression)*[','] ')'
   1316 
   1317   Expect(Token::LPAREN, ok);
   1318   if (!*ok) return -1;
   1319   bool done = (peek() == Token::RPAREN);
   1320   int argc = 0;
   1321   while (!done) {
   1322     ParseAssignmentExpression(true, ok);
   1323     if (!*ok) return -1;
   1324     argc++;
   1325     done = (peek() == Token::RPAREN);
   1326     if (!done) {
   1327       Expect(Token::COMMA, ok);
   1328       if (!*ok) return -1;
   1329     }
   1330   }
   1331   Expect(Token::RPAREN, ok);
   1332   return argc;
   1333 }
   1334 
   1335 
   1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
   1337                                                       bool* ok) {
   1338   // Function ::
   1339   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
   1340 
   1341   // Parse function body.
   1342   ScopeType outer_scope_type = scope_->type();
   1343   bool inside_with = scope_->IsInsideWith();
   1344   Scope function_scope(&scope_, kFunctionScope);
   1345   function_scope.set_is_generator(is_generator);
   1346   //  FormalParameterList ::
   1347   //    '(' (Identifier)*[','] ')'
   1348   Expect(Token::LPAREN, CHECK_OK);
   1349   int start_position = position();
   1350   bool done = (peek() == Token::RPAREN);
   1351   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
   1352   while (!done) {
   1353     Identifier id = ParseIdentifier(CHECK_OK);
   1354     if (!id.IsValidStrictVariable()) {
   1355       StrictModeIdentifierViolation(scanner()->location(),
   1356                                     "strict_param_name",
   1357                                     id,
   1358                                     CHECK_OK);
   1359     }
   1360     int prev_value;
   1361     if (scanner()->is_literal_ascii()) {
   1362       prev_value =
   1363           duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
   1364     } else {
   1365       prev_value =
   1366           duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
   1367     }
   1368 
   1369     if (prev_value != 0) {
   1370       SetStrictModeViolation(scanner()->location(),
   1371                              "strict_param_dupe",
   1372                              CHECK_OK);
   1373     }
   1374     done = (peek() == Token::RPAREN);
   1375     if (!done) {
   1376       Expect(Token::COMMA, CHECK_OK);
   1377     }
   1378   }
   1379   Expect(Token::RPAREN, CHECK_OK);
   1380 
   1381   // Determine if the function will be lazily compiled.
   1382   // Currently only happens to top-level functions.
   1383   // Optimistically assume that all top-level functions are lazily compiled.
   1384   bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
   1385                              !inside_with && allow_lazy() &&
   1386                              !parenthesized_function_);
   1387   parenthesized_function_ = false;
   1388 
   1389   Expect(Token::LBRACE, CHECK_OK);
   1390   if (is_lazily_compiled) {
   1391     ParseLazyFunctionLiteralBody(CHECK_OK);
   1392   } else {
   1393     ParseSourceElements(Token::RBRACE, ok);
   1394   }
   1395   Expect(Token::RBRACE, CHECK_OK);
   1396 
   1397   if (!is_classic_mode()) {
   1398     int end_position = scanner()->location().end_pos;
   1399     CheckOctalLiteral(start_position, end_position, CHECK_OK);
   1400     CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
   1401     return Expression::StrictFunction();
   1402   }
   1403 
   1404   return Expression::Default();
   1405 }
   1406 
   1407 
   1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
   1409   int body_start = position();
   1410   log_->PauseRecording();
   1411   ParseSourceElements(Token::RBRACE, ok);
   1412   log_->ResumeRecording();
   1413   if (!*ok) return;
   1414 
   1415   // Position right after terminal '}'.
   1416   ASSERT_EQ(Token::RBRACE, scanner()->peek());
   1417   int body_end = scanner()->peek_location().end_pos;
   1418   log_->LogFunction(body_start, body_end,
   1419                     scope_->materialized_literal_count(),
   1420                     scope_->expected_properties(),
   1421                     language_mode());
   1422 }
   1423 
   1424 
   1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
   1426   // CallRuntime ::
   1427   //   '%' Identifier Arguments
   1428   Expect(Token::MOD, CHECK_OK);
   1429   if (!allow_natives_syntax()) {
   1430     *ok = false;
   1431     return Expression::Default();
   1432   }
   1433   ParseIdentifier(CHECK_OK);
   1434   ParseArguments(ok);
   1435 
   1436   return Expression::Default();
   1437 }
   1438 
   1439 #undef CHECK_OK
   1440 
   1441 
   1442 void PreParser::LogSymbol() {
   1443   int identifier_pos = position();
   1444   if (scanner()->is_literal_ascii()) {
   1445     log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
   1446   } else {
   1447     log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
   1448   }
   1449 }
   1450 
   1451 
   1452 PreParser::Expression PreParser::GetStringSymbol() {
   1453   const int kUseStrictLength = 10;
   1454   const char* kUseStrictChars = "use strict";
   1455   LogSymbol();
   1456   if (scanner()->is_literal_ascii() &&
   1457       scanner()->literal_length() == kUseStrictLength &&
   1458       !scanner()->literal_contains_escapes() &&
   1459       !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
   1460                kUseStrictLength)) {
   1461     return Expression::UseStrictStringLiteral();
   1462   }
   1463   return Expression::StringLiteral();
   1464 }
   1465 
   1466 
   1467 PreParser::Identifier PreParser::GetIdentifierSymbol() {
   1468   LogSymbol();
   1469   if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
   1470     return Identifier::FutureReserved();
   1471   } else if (scanner()->current_token() ==
   1472              Token::FUTURE_STRICT_RESERVED_WORD) {
   1473     return Identifier::FutureStrictReserved();
   1474   } else if (scanner()->current_token() == Token::YIELD) {
   1475     return Identifier::Yield();
   1476   }
   1477   if (scanner()->is_literal_ascii()) {
   1478     // Detect strict-mode poison words.
   1479     if (scanner()->literal_length() == 4 &&
   1480         !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
   1481       return Identifier::Eval();
   1482     }
   1483     if (scanner()->literal_length() == 9 &&
   1484         !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
   1485       return Identifier::Arguments();
   1486     }
   1487   }
   1488   return Identifier::Default();
   1489 }
   1490 
   1491 
   1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
   1493   Token::Value next = Next();
   1494   switch (next) {
   1495     case Token::FUTURE_RESERVED_WORD: {
   1496       Scanner::Location location = scanner()->location();
   1497       ReportMessageAt(location.beg_pos, location.end_pos,
   1498                       "reserved_word", NULL);
   1499       *ok = false;
   1500       return GetIdentifierSymbol();
   1501     }
   1502     case Token::YIELD:
   1503       if (scope_->is_generator()) {
   1504         // 'yield' in a generator is only valid as part of a YieldExpression.
   1505         ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
   1506         *ok = false;
   1507         return Identifier::Yield();
   1508       }
   1509       // FALLTHROUGH
   1510     case Token::FUTURE_STRICT_RESERVED_WORD:
   1511       if (!is_classic_mode()) {
   1512         Scanner::Location location = scanner()->location();
   1513         ReportMessageAt(location.beg_pos, location.end_pos,
   1514                         "strict_reserved_word", NULL);
   1515         *ok = false;
   1516       }
   1517       // FALLTHROUGH
   1518     case Token::IDENTIFIER:
   1519       return GetIdentifierSymbol();
   1520     default:
   1521       *ok = false;
   1522       return Identifier::Default();
   1523   }
   1524 }
   1525 
   1526 
   1527 void PreParser::SetStrictModeViolation(Scanner::Location location,
   1528                                        const char* type,
   1529                                        bool* ok) {
   1530   if (!is_classic_mode()) {
   1531     ReportMessageAt(location, type, NULL);
   1532     *ok = false;
   1533     return;
   1534   }
   1535   // Delay report in case this later turns out to be strict code
   1536   // (i.e., for function names and parameters prior to a "use strict"
   1537   // directive).
   1538   // It's safe to overwrite an existing violation.
   1539   // It's either from a function that turned out to be non-strict,
   1540   // or it's in the current function (and we just need to report
   1541   // one error), or it's in a unclosed nesting function that wasn't
   1542   // strict (otherwise we would already be in strict mode).
   1543   strict_mode_violation_location_ = location;
   1544   strict_mode_violation_type_ = type;
   1545 }
   1546 
   1547 
   1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
   1549                                                 int end_pos,
   1550                                                 bool* ok) {
   1551   Scanner::Location location = strict_mode_violation_location_;
   1552   if (location.IsValid() &&
   1553       location.beg_pos > beg_pos && location.end_pos < end_pos) {
   1554     ReportMessageAt(location, strict_mode_violation_type_, NULL);
   1555     *ok = false;
   1556   }
   1557 }
   1558 
   1559 
   1560 void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
   1561                                               const char* eval_args_type,
   1562                                               Identifier identifier,
   1563                                               bool* ok) {
   1564   const char* type = eval_args_type;
   1565   if (identifier.IsFutureReserved()) {
   1566     type = "reserved_word";
   1567   } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
   1568     type = "strict_reserved_word";
   1569   }
   1570   if (!is_classic_mode()) {
   1571     ReportMessageAt(location, type, NULL);
   1572     *ok = false;
   1573     return;
   1574   }
   1575   strict_mode_violation_location_ = location;
   1576   strict_mode_violation_type_ = type;
   1577 }
   1578 
   1579 
   1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
   1581   Token::Value next = Next();
   1582   if (Token::IsKeyword(next)) {
   1583     int pos = position();
   1584     const char* keyword = Token::String(next);
   1585     log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword)));
   1586     return Identifier::Default();
   1587   }
   1588   if (next == Token::IDENTIFIER ||
   1589       next == Token::FUTURE_RESERVED_WORD ||
   1590       next == Token::FUTURE_STRICT_RESERVED_WORD) {
   1591     return GetIdentifierSymbol();
   1592   }
   1593   *ok = false;
   1594   return Identifier::Default();
   1595 }
   1596 
   1597 #undef CHECK_OK
   1598 
   1599 
   1600 // This function reads an identifier and determines whether or not it
   1601 // is 'get' or 'set'.
   1602 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
   1603                                                                bool* is_set,
   1604                                                                bool* ok) {
   1605   Identifier result = ParseIdentifierName(ok);
   1606   if (!*ok) return Identifier::Default();
   1607   if (scanner()->is_literal_ascii() &&
   1608       scanner()->literal_length() == 3) {
   1609     const char* token = scanner()->literal_ascii_string().start();
   1610     *is_get = strncmp(token, "get", 3) == 0;
   1611     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
   1612   }
   1613   return result;
   1614 }
   1615 
   1616 
   1617 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property,
   1618                                                     PropertyKind type,
   1619                                                     bool* ok) {
   1620   int old;
   1621   if (property == Token::NUMBER) {
   1622     old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
   1623   } else if (scanner()->is_literal_ascii()) {
   1624     old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
   1625   } else {
   1626     old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type);
   1627   }
   1628   PropertyKind old_type = static_cast<PropertyKind>(old);
   1629   if (HasConflict(old_type, type)) {
   1630     if (IsDataDataConflict(old_type, type)) {
   1631       // Both are data properties.
   1632       if (language_mode_ == CLASSIC_MODE) return;
   1633       parser()->ReportMessageAt(scanner()->location(),
   1634                                "strict_duplicate_property");
   1635     } else if (IsDataAccessorConflict(old_type, type)) {
   1636       // Both a data and an accessor property with the same name.
   1637       parser()->ReportMessageAt(scanner()->location(),
   1638                                "accessor_data_property");
   1639     } else {
   1640       ASSERT(IsAccessorAccessorConflict(old_type, type));
   1641       // Both accessors of the same type.
   1642       parser()->ReportMessageAt(scanner()->location(),
   1643                                "accessor_get_set");
   1644     }
   1645     *ok = false;
   1646   }
   1647 }
   1648 
   1649 } }  // v8::internal
   1650