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