Home | History | Annotate | Download | only in parsing
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <cmath>
      6 
      7 #include "src/allocation.h"
      8 #include "src/base/logging.h"
      9 #include "src/conversions-inl.h"
     10 #include "src/conversions.h"
     11 #include "src/globals.h"
     12 #include "src/hashmap.h"
     13 #include "src/list.h"
     14 #include "src/parsing/parser-base.h"
     15 #include "src/parsing/preparse-data.h"
     16 #include "src/parsing/preparse-data-format.h"
     17 #include "src/parsing/preparser.h"
     18 #include "src/unicode.h"
     19 #include "src/utils.h"
     20 
     21 namespace v8 {
     22 namespace internal {
     23 
     24 void PreParserTraits::ReportMessageAt(Scanner::Location location,
     25                                       MessageTemplate::Template message,
     26                                       const char* arg,
     27                                       ParseErrorType error_type) {
     28   ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type);
     29 }
     30 
     31 
     32 void PreParserTraits::ReportMessageAt(int start_pos, int end_pos,
     33                                       MessageTemplate::Template message,
     34                                       const char* arg,
     35                                       ParseErrorType error_type) {
     36   pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, error_type);
     37 }
     38 
     39 
     40 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
     41   if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
     42     return PreParserIdentifier::FutureReserved();
     43   } else if (scanner->current_token() ==
     44              Token::FUTURE_STRICT_RESERVED_WORD) {
     45     return PreParserIdentifier::FutureStrictReserved();
     46   } else if (scanner->current_token() == Token::LET) {
     47     return PreParserIdentifier::Let();
     48   } else if (scanner->current_token() == Token::STATIC) {
     49     return PreParserIdentifier::Static();
     50   } else if (scanner->current_token() == Token::YIELD) {
     51     return PreParserIdentifier::Yield();
     52   }
     53   if (scanner->UnescapedLiteralMatches("eval", 4)) {
     54     return PreParserIdentifier::Eval();
     55   }
     56   if (scanner->UnescapedLiteralMatches("arguments", 9)) {
     57     return PreParserIdentifier::Arguments();
     58   }
     59   if (scanner->UnescapedLiteralMatches("undefined", 9)) {
     60     return PreParserIdentifier::Undefined();
     61   }
     62   if (scanner->LiteralMatches("prototype", 9)) {
     63     return PreParserIdentifier::Prototype();
     64   }
     65   if (scanner->LiteralMatches("constructor", 11)) {
     66     return PreParserIdentifier::Constructor();
     67   }
     68   return PreParserIdentifier::Default();
     69 }
     70 
     71 
     72 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
     73   return PreParserIdentifier::Default();
     74 }
     75 
     76 
     77 PreParserExpression PreParserTraits::ExpressionFromString(
     78     int pos, Scanner* scanner, PreParserFactory* factory) {
     79   if (scanner->UnescapedLiteralMatches("use strict", 10)) {
     80     return PreParserExpression::UseStrictStringLiteral();
     81   } else if (scanner->UnescapedLiteralMatches("use strong", 10)) {
     82     return PreParserExpression::UseStrongStringLiteral();
     83   }
     84   return PreParserExpression::StringLiteral();
     85 }
     86 
     87 
     88 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
     89   return pre_parser_->ParseV8Intrinsic(ok);
     90 }
     91 
     92 
     93 PreParserExpression PreParserTraits::ParseFunctionLiteral(
     94     PreParserIdentifier name, Scanner::Location function_name_location,
     95     FunctionNameValidity function_name_validity, FunctionKind kind,
     96     int function_token_position, FunctionLiteral::FunctionType type,
     97     FunctionLiteral::ArityRestriction arity_restriction,
     98     LanguageMode language_mode, bool* ok) {
     99   return pre_parser_->ParseFunctionLiteral(
    100       name, function_name_location, function_name_validity, kind,
    101       function_token_position, type, arity_restriction, language_mode, ok);
    102 }
    103 
    104 
    105 PreParser::PreParseResult PreParser::PreParseLazyFunction(
    106     LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
    107     ParserRecorder* log, Scanner::BookmarkScope* bookmark) {
    108   log_ = log;
    109   // Lazy functions always have trivial outer scopes (no with/catch scopes).
    110   Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE);
    111   PreParserFactory top_factory(NULL);
    112   FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction,
    113                           &top_factory);
    114   scope_->SetLanguageMode(language_mode);
    115   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
    116   if (!has_simple_parameters) function_scope->SetHasNonSimpleParameters();
    117   PreParserFactory function_factory(NULL);
    118   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
    119                                &function_factory);
    120   DCHECK_EQ(Token::LBRACE, scanner()->current_token());
    121   bool ok = true;
    122   int start_position = peek_position();
    123   ParseLazyFunctionLiteralBody(&ok, bookmark);
    124   if (bookmark && bookmark->HasBeenReset()) {
    125     // Do nothing, as we've just aborted scanning this function.
    126   } else if (stack_overflow()) {
    127     return kPreParseStackOverflow;
    128   } else if (!ok) {
    129     ReportUnexpectedToken(scanner()->current_token());
    130   } else {
    131     DCHECK_EQ(Token::RBRACE, scanner()->peek());
    132     if (is_strict(scope_->language_mode())) {
    133       int end_pos = scanner()->location().end_pos;
    134       CheckStrictOctalLiteral(start_position, end_pos, &ok);
    135       if (!ok) return kPreParseSuccess;
    136 
    137       if (is_strong(scope_->language_mode()) && IsSubclassConstructor(kind)) {
    138         if (!function_state.super_location().IsValid()) {
    139           ReportMessageAt(Scanner::Location(start_position, start_position + 1),
    140                           MessageTemplate::kStrongSuperCallMissing,
    141                           kReferenceError);
    142           return kPreParseSuccess;
    143         }
    144       }
    145     }
    146   }
    147   return kPreParseSuccess;
    148 }
    149 
    150 
    151 PreParserExpression PreParserTraits::ParseClassLiteral(
    152     PreParserIdentifier name, Scanner::Location class_name_location,
    153     bool name_is_strict_reserved, int pos, bool* ok) {
    154   return pre_parser_->ParseClassLiteral(name, class_name_location,
    155                                         name_is_strict_reserved, pos, ok);
    156 }
    157 
    158 
    159 // Preparsing checks a JavaScript program and emits preparse-data that helps
    160 // a later parsing to be faster.
    161 // See preparser-data.h for the data.
    162 
    163 // The PreParser checks that the syntax follows the grammar for JavaScript,
    164 // and collects some information about the program along the way.
    165 // The grammar check is only performed in order to understand the program
    166 // sufficiently to deduce some information about it, that can be used
    167 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
    168 // rather it is to speed up properly written and correct programs.
    169 // That means that contextual checks (like a label being declared where
    170 // it is used) are generally omitted.
    171 
    172 
    173 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
    174   // ECMA 262 6th Edition
    175   // StatementListItem[Yield, Return] :
    176   //   Statement[?Yield, ?Return]
    177   //   Declaration[?Yield]
    178   //
    179   // Declaration[Yield] :
    180   //   HoistableDeclaration[?Yield]
    181   //   ClassDeclaration[?Yield]
    182   //   LexicalDeclaration[In, ?Yield]
    183   //
    184   // HoistableDeclaration[Yield, Default] :
    185   //   FunctionDeclaration[?Yield, ?Default]
    186   //   GeneratorDeclaration[?Yield, ?Default]
    187   //
    188   // LexicalDeclaration[In, Yield] :
    189   //   LetOrConst BindingList[?In, ?Yield] ;
    190 
    191   switch (peek()) {
    192     case Token::FUNCTION:
    193       return ParseFunctionDeclaration(ok);
    194     case Token::CLASS:
    195       return ParseClassDeclaration(ok);
    196     case Token::CONST:
    197       if (allow_const()) {
    198         return ParseVariableStatement(kStatementListItem, ok);
    199       }
    200       break;
    201     case Token::LET:
    202       if (IsNextLetKeyword()) {
    203         return ParseVariableStatement(kStatementListItem, ok);
    204       }
    205       break;
    206     default:
    207       break;
    208   }
    209   return ParseStatement(ok);
    210 }
    211 
    212 
    213 void PreParser::ParseStatementList(int end_token, bool* ok,
    214                                    Scanner::BookmarkScope* bookmark) {
    215   // SourceElements ::
    216   //   (Statement)* <end_token>
    217 
    218   // Bookkeeping for trial parse if bookmark is set:
    219   DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
    220   bool maybe_reset = bookmark != nullptr;
    221   int count_statements = 0;
    222 
    223   bool directive_prologue = true;
    224   while (peek() != end_token) {
    225     if (directive_prologue && peek() != Token::STRING) {
    226       directive_prologue = false;
    227     }
    228     bool starts_with_identifier = peek() == Token::IDENTIFIER;
    229     Scanner::Location token_loc = scanner()->peek_location();
    230     Scanner::Location old_this_loc = function_state_->this_location();
    231     Scanner::Location old_super_loc = function_state_->super_location();
    232     Statement statement = ParseStatementListItem(ok);
    233     if (!*ok) return;
    234 
    235     if (is_strong(language_mode()) && scope_->is_function_scope() &&
    236         IsClassConstructor(function_state_->kind())) {
    237       Scanner::Location this_loc = function_state_->this_location();
    238       Scanner::Location super_loc = function_state_->super_location();
    239       if (this_loc.beg_pos != old_this_loc.beg_pos &&
    240           this_loc.beg_pos != token_loc.beg_pos) {
    241         ReportMessageAt(this_loc, MessageTemplate::kStrongConstructorThis);
    242         *ok = false;
    243         return;
    244       }
    245       if (super_loc.beg_pos != old_super_loc.beg_pos &&
    246           super_loc.beg_pos != token_loc.beg_pos) {
    247         ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
    248         *ok = false;
    249         return;
    250       }
    251     }
    252 
    253     if (directive_prologue) {
    254       bool use_strict_found = statement.IsUseStrictLiteral();
    255       bool use_strong_found =
    256           statement.IsUseStrongLiteral() && allow_strong_mode();
    257 
    258       if (use_strict_found) {
    259         scope_->SetLanguageMode(
    260             static_cast<LanguageMode>(scope_->language_mode() | STRICT));
    261       } else if (use_strong_found) {
    262         scope_->SetLanguageMode(static_cast<LanguageMode>(
    263             scope_->language_mode() | STRONG));
    264         if (IsClassConstructor(function_state_->kind())) {
    265           // "use strong" cannot occur in a class constructor body, to avoid
    266           // unintuitive strong class object semantics.
    267           PreParserTraits::ReportMessageAt(
    268               token_loc, MessageTemplate::kStrongConstructorDirective);
    269           *ok = false;
    270           return;
    271         }
    272       } else if (!statement.IsStringLiteral()) {
    273         directive_prologue = false;
    274       }
    275 
    276       if ((use_strict_found || use_strong_found) &&
    277           !scope_->HasSimpleParameters()) {
    278         // TC39 deemed "use strict" directives to be an error when occurring
    279         // in the body of a function with non-simple parameter list, on
    280         // 29/7/2015. https://goo.gl/ueA7Ln
    281         //
    282         // In V8, this also applies to "use strong " directives.
    283         PreParserTraits::ReportMessageAt(
    284             token_loc, MessageTemplate::kIllegalLanguageModeDirective,
    285             use_strict_found ? "use strict" : "use strong");
    286         *ok = false;
    287         return;
    288       }
    289     }
    290 
    291     // If we're allowed to reset to a bookmark, we will do so when we see a long
    292     // and trivial function.
    293     // Our current definition of 'long and trivial' is:
    294     // - over 200 statements
    295     // - all starting with an identifier (i.e., no if, for, while, etc.)
    296     if (maybe_reset && (!starts_with_identifier ||
    297                         ++count_statements > kLazyParseTrialLimit)) {
    298       if (count_statements > kLazyParseTrialLimit) {
    299         bookmark->Reset();
    300         return;
    301       }
    302       maybe_reset = false;
    303     }
    304   }
    305 }
    306 
    307 
    308 #define CHECK_OK  ok);                   \
    309   if (!*ok) return Statement::Default();  \
    310   ((void)0
    311 #define DUMMY )  // to make indentation work
    312 #undef DUMMY
    313 
    314 
    315 PreParser::Statement PreParser::ParseStatement(bool* ok) {
    316   // Statement ::
    317   //   EmptyStatement
    318   //   ...
    319 
    320   if (peek() == Token::SEMICOLON) {
    321     Next();
    322     return Statement::Default();
    323   }
    324   return ParseSubStatement(ok);
    325 }
    326 
    327 
    328 PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
    329   // Statement ::
    330   //   Block
    331   //   VariableStatement
    332   //   EmptyStatement
    333   //   ExpressionStatement
    334   //   IfStatement
    335   //   IterationStatement
    336   //   ContinueStatement
    337   //   BreakStatement
    338   //   ReturnStatement
    339   //   WithStatement
    340   //   LabelledStatement
    341   //   SwitchStatement
    342   //   ThrowStatement
    343   //   TryStatement
    344   //   DebuggerStatement
    345 
    346   // Note: Since labels can only be used by 'break' and 'continue'
    347   // statements, which themselves are only valid within blocks,
    348   // iterations or 'switch' statements (i.e., BreakableStatements),
    349   // labels can be simply ignored in all other cases; except for
    350   // trivial labeled break statements 'label: break label' which is
    351   // parsed into an empty statement.
    352 
    353   // Keep the source position of the statement
    354   switch (peek()) {
    355     case Token::LBRACE:
    356       return ParseBlock(ok);
    357 
    358     case Token::SEMICOLON:
    359       if (is_strong(language_mode())) {
    360         PreParserTraits::ReportMessageAt(scanner()->peek_location(),
    361                                          MessageTemplate::kStrongEmpty);
    362         *ok = false;
    363         return Statement::Default();
    364       }
    365       Next();
    366       return Statement::Default();
    367 
    368     case Token::IF:
    369       return ParseIfStatement(ok);
    370 
    371     case Token::DO:
    372       return ParseDoWhileStatement(ok);
    373 
    374     case Token::WHILE:
    375       return ParseWhileStatement(ok);
    376 
    377     case Token::FOR:
    378       return ParseForStatement(ok);
    379 
    380     case Token::CONTINUE:
    381       return ParseContinueStatement(ok);
    382 
    383     case Token::BREAK:
    384       return ParseBreakStatement(ok);
    385 
    386     case Token::RETURN:
    387       return ParseReturnStatement(ok);
    388 
    389     case Token::WITH:
    390       return ParseWithStatement(ok);
    391 
    392     case Token::SWITCH:
    393       return ParseSwitchStatement(ok);
    394 
    395     case Token::THROW:
    396       return ParseThrowStatement(ok);
    397 
    398     case Token::TRY:
    399       return ParseTryStatement(ok);
    400 
    401     case Token::FUNCTION: {
    402       Scanner::Location start_location = scanner()->peek_location();
    403       Statement statement = ParseFunctionDeclaration(CHECK_OK);
    404       Scanner::Location end_location = scanner()->location();
    405       if (is_strict(language_mode())) {
    406         PreParserTraits::ReportMessageAt(start_location.beg_pos,
    407                                          end_location.end_pos,
    408                                          MessageTemplate::kStrictFunction);
    409         *ok = false;
    410         return Statement::Default();
    411       } else {
    412         return statement;
    413       }
    414     }
    415 
    416     case Token::DEBUGGER:
    417       return ParseDebuggerStatement(ok);
    418 
    419     case Token::VAR:
    420       return ParseVariableStatement(kStatement, ok);
    421 
    422     case Token::CONST:
    423       // In ES6 CONST is not allowed as a Statement, only as a
    424       // LexicalDeclaration, however we continue to allow it in sloppy mode for
    425       // backwards compatibility.
    426       if (is_sloppy(language_mode()) && allow_legacy_const()) {
    427         return ParseVariableStatement(kStatement, ok);
    428       }
    429 
    430     // Fall through.
    431     default:
    432       return ParseExpressionOrLabelledStatement(ok);
    433   }
    434 }
    435 
    436 
    437 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
    438   // FunctionDeclaration ::
    439   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
    440   // GeneratorDeclaration ::
    441   //   'function' '*' Identifier '(' FormalParameterListopt ')'
    442   //      '{' FunctionBody '}'
    443   Expect(Token::FUNCTION, CHECK_OK);
    444   int pos = position();
    445   bool is_generator = Check(Token::MUL);
    446   bool is_strict_reserved = false;
    447   Identifier name = ParseIdentifierOrStrictReservedWord(
    448       &is_strict_reserved, CHECK_OK);
    449   ParseFunctionLiteral(name, scanner()->location(),
    450                        is_strict_reserved ? kFunctionNameIsStrictReserved
    451                                           : kFunctionNameValidityUnknown,
    452                        is_generator ? FunctionKind::kGeneratorFunction
    453                                     : FunctionKind::kNormalFunction,
    454                        pos, FunctionLiteral::kDeclaration,
    455                        FunctionLiteral::kNormalArity, language_mode(),
    456                        CHECK_OK);
    457   return Statement::FunctionDeclaration();
    458 }
    459 
    460 
    461 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
    462   Expect(Token::CLASS, CHECK_OK);
    463   if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
    464     ReportMessage(MessageTemplate::kSloppyLexical);
    465     *ok = false;
    466     return Statement::Default();
    467   }
    468 
    469   int pos = position();
    470   bool is_strict_reserved = false;
    471   Identifier name =
    472       ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
    473   ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
    474                     CHECK_OK);
    475   return Statement::Default();
    476 }
    477 
    478 
    479 PreParser::Statement PreParser::ParseBlock(bool* ok) {
    480   // Block ::
    481   //   '{' StatementList '}'
    482 
    483   Expect(Token::LBRACE, CHECK_OK);
    484   Statement final = Statement::Default();
    485   while (peek() != Token::RBRACE) {
    486     final = ParseStatementListItem(CHECK_OK);
    487   }
    488   Expect(Token::RBRACE, ok);
    489   return final;
    490 }
    491 
    492 
    493 PreParser::Statement PreParser::ParseVariableStatement(
    494     VariableDeclarationContext var_context,
    495     bool* ok) {
    496   // VariableStatement ::
    497   //   VariableDeclarations ';'
    498 
    499   Statement result = ParseVariableDeclarations(
    500       var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK);
    501   ExpectSemicolon(CHECK_OK);
    502   return result;
    503 }
    504 
    505 
    506 // If the variable declaration declares exactly one non-const
    507 // variable, then *var is set to that variable. In all other cases,
    508 // *var is untouched; in particular, it is the caller's responsibility
    509 // to initialize it properly. This mechanism is also used for the parsing
    510 // of 'for-in' loops.
    511 PreParser::Statement PreParser::ParseVariableDeclarations(
    512     VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
    513     bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
    514     Scanner::Location* bindings_loc, bool* ok) {
    515   // VariableDeclarations ::
    516   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
    517   //
    518   // The ES6 Draft Rev3 specifies the following grammar for const declarations
    519   //
    520   // ConstDeclaration ::
    521   //   const ConstBinding (',' ConstBinding)* ';'
    522   // ConstBinding ::
    523   //   Identifier '=' AssignmentExpression
    524   //
    525   // TODO(ES6):
    526   // ConstBinding ::
    527   //   BindingPattern '=' AssignmentExpression
    528   bool require_initializer = false;
    529   bool lexical = false;
    530   bool is_pattern = false;
    531   if (peek() == Token::VAR) {
    532     if (is_strong(language_mode())) {
    533       Scanner::Location location = scanner()->peek_location();
    534       ReportMessageAt(location, MessageTemplate::kStrongVar);
    535       *ok = false;
    536       return Statement::Default();
    537     }
    538     Consume(Token::VAR);
    539   } else if (peek() == Token::CONST && allow_const()) {
    540     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
    541     //
    542     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
    543     //
    544     // * It is a Syntax Error if the code that matches this production is not
    545     //   contained in extended code.
    546     //
    547     // However disallowing const in sloppy mode will break compatibility with
    548     // existing pages. Therefore we keep allowing const with the old
    549     // non-harmony semantics in sloppy mode.
    550     Consume(Token::CONST);
    551     if (is_strict(language_mode()) ||
    552         (allow_harmony_sloppy() && !allow_legacy_const())) {
    553       DCHECK(var_context != kStatement);
    554       require_initializer = true;
    555       lexical = true;
    556     }
    557   } else if (peek() == Token::LET && allow_let()) {
    558     Consume(Token::LET);
    559     DCHECK(var_context != kStatement);
    560     lexical = true;
    561   } else {
    562     *ok = false;
    563     return Statement::Default();
    564   }
    565 
    566   // The scope of a var/const declared variable anywhere inside a function
    567   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
    568   // of a let declared variable is the scope of the immediately enclosing
    569   // block.
    570   int nvars = 0;  // the number of variables declared
    571   int bindings_start = peek_position();
    572   do {
    573     // Parse binding pattern.
    574     if (nvars > 0) Consume(Token::COMMA);
    575     int decl_pos = peek_position();
    576     PreParserExpression pattern = PreParserExpression::Default();
    577     {
    578       ExpressionClassifier pattern_classifier;
    579       Token::Value next = peek();
    580       pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
    581 
    582       ValidateBindingPattern(&pattern_classifier, CHECK_OK);
    583       if (lexical) {
    584         ValidateLetPattern(&pattern_classifier, CHECK_OK);
    585       }
    586 
    587       if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) {
    588         ReportUnexpectedToken(next);
    589         *ok = false;
    590         return Statement::Default();
    591       }
    592     }
    593 
    594     is_pattern = (pattern.IsObjectLiteral() || pattern.IsArrayLiteral()) &&
    595                  !pattern.is_parenthesized();
    596 
    597     bool is_for_iteration_variable =
    598         var_context == kForStatement &&
    599         (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
    600 
    601     Scanner::Location variable_loc = scanner()->location();
    602     nvars++;
    603     if (Check(Token::ASSIGN)) {
    604       ExpressionClassifier classifier;
    605       ParseAssignmentExpression(var_context != kForStatement, &classifier,
    606                                 CHECK_OK);
    607       ValidateExpression(&classifier, CHECK_OK);
    608 
    609       variable_loc.end_pos = scanner()->location().end_pos;
    610       if (first_initializer_loc && !first_initializer_loc->IsValid()) {
    611         *first_initializer_loc = variable_loc;
    612       }
    613     } else if ((require_initializer || is_pattern) &&
    614                !is_for_iteration_variable) {
    615       PreParserTraits::ReportMessageAt(
    616           Scanner::Location(decl_pos, scanner()->location().end_pos),
    617           MessageTemplate::kDeclarationMissingInitializer,
    618           is_pattern ? "destructuring" : "const");
    619       *ok = false;
    620       return Statement::Default();
    621     }
    622   } while (peek() == Token::COMMA);
    623 
    624   if (bindings_loc) {
    625     *bindings_loc =
    626         Scanner::Location(bindings_start, scanner()->location().end_pos);
    627   }
    628 
    629   if (num_decl != nullptr) *num_decl = nvars;
    630   if (is_lexical != nullptr) *is_lexical = lexical;
    631   if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
    632   return Statement::Default();
    633 }
    634 
    635 
    636 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
    637   // ExpressionStatement | LabelledStatement ::
    638   //   Expression ';'
    639   //   Identifier ':' Statement
    640 
    641   switch (peek()) {
    642     case Token::FUNCTION:
    643     case Token::LBRACE:
    644       UNREACHABLE();  // Always handled by the callers.
    645     case Token::CLASS:
    646       ReportUnexpectedToken(Next());
    647       *ok = false;
    648       return Statement::Default();
    649 
    650     case Token::THIS:
    651       if (!FLAG_strong_this) break;
    652       // Fall through.
    653     case Token::SUPER:
    654       if (is_strong(language_mode()) &&
    655           IsClassConstructor(function_state_->kind())) {
    656         bool is_this = peek() == Token::THIS;
    657         Expression expr = Expression::Default();
    658         ExpressionClassifier classifier;
    659         if (is_this) {
    660           expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
    661         } else {
    662           expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
    663         }
    664         ValidateExpression(&classifier, CHECK_OK);
    665         switch (peek()) {
    666           case Token::SEMICOLON:
    667             Consume(Token::SEMICOLON);
    668             break;
    669           case Token::RBRACE:
    670           case Token::EOS:
    671             break;
    672           default:
    673             if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
    674               ReportMessageAt(function_state_->this_location(),
    675                               is_this
    676                                   ? MessageTemplate::kStrongConstructorThis
    677                                   : MessageTemplate::kStrongConstructorSuper);
    678               *ok = false;
    679               return Statement::Default();
    680             }
    681         }
    682         return Statement::ExpressionStatement(expr);
    683       }
    684       break;
    685 
    686     // TODO(arv): Handle `let [`
    687     // https://code.google.com/p/v8/issues/detail?id=3847
    688 
    689     default:
    690       break;
    691   }
    692 
    693   bool starts_with_identifier = peek_any_identifier();
    694   ExpressionClassifier classifier;
    695   Expression expr = ParseExpression(true, &classifier, CHECK_OK);
    696   ValidateExpression(&classifier, CHECK_OK);
    697 
    698   // Even if the expression starts with an identifier, it is not necessarily an
    699   // identifier. For example, "foo + bar" starts with an identifier but is not
    700   // an identifier.
    701   if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
    702     // Expression is a single identifier, and not, e.g., a parenthesized
    703     // identifier.
    704     DCHECK(!expr.AsIdentifier().IsFutureReserved());
    705     DCHECK(is_sloppy(language_mode()) ||
    706            !IsFutureStrictReserved(expr.AsIdentifier()));
    707     Consume(Token::COLON);
    708     Statement statement = ParseStatement(ok);
    709     return statement.IsJumpStatement() ? Statement::Default() : statement;
    710     // Preparsing is disabled for extensions (because the extension details
    711     // aren't passed to lazily compiled functions), so we don't
    712     // accept "native function" in the preparser.
    713   }
    714   // Parsed expression statement.
    715   // Detect attempts at 'let' declarations in sloppy mode.
    716   if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
    717       is_sloppy(language_mode()) && expr.IsIdentifier() &&
    718       expr.AsIdentifier().IsLet()) {
    719     ReportMessage(MessageTemplate::kSloppyLexical, NULL);
    720     *ok = false;
    721     return Statement::Default();
    722   }
    723   ExpectSemicolon(CHECK_OK);
    724   return Statement::ExpressionStatement(expr);
    725 }
    726 
    727 
    728 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
    729   // IfStatement ::
    730   //   'if' '(' Expression ')' Statement ('else' Statement)?
    731 
    732   Expect(Token::IF, CHECK_OK);
    733   Expect(Token::LPAREN, CHECK_OK);
    734   ParseExpression(true, CHECK_OK);
    735   Expect(Token::RPAREN, CHECK_OK);
    736   Statement stat = ParseSubStatement(CHECK_OK);
    737   if (peek() == Token::ELSE) {
    738     Next();
    739     Statement else_stat = ParseSubStatement(CHECK_OK);
    740     stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ?
    741         Statement::Jump() : Statement::Default();
    742   } else {
    743     stat = Statement::Default();
    744   }
    745   return stat;
    746 }
    747 
    748 
    749 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
    750   // ContinueStatement ::
    751   //   'continue' [no line terminator] Identifier? ';'
    752 
    753   Expect(Token::CONTINUE, CHECK_OK);
    754   Token::Value tok = peek();
    755   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    756       tok != Token::SEMICOLON &&
    757       tok != Token::RBRACE &&
    758       tok != Token::EOS) {
    759     // ECMA allows "eval" or "arguments" as labels even in strict mode.
    760     ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
    761   }
    762   ExpectSemicolon(CHECK_OK);
    763   return Statement::Jump();
    764 }
    765 
    766 
    767 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
    768   // BreakStatement ::
    769   //   'break' [no line terminator] Identifier? ';'
    770 
    771   Expect(Token::BREAK, CHECK_OK);
    772   Token::Value tok = peek();
    773   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    774       tok != Token::SEMICOLON &&
    775       tok != Token::RBRACE &&
    776       tok != Token::EOS) {
    777     // ECMA allows "eval" or "arguments" as labels even in strict mode.
    778     ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
    779   }
    780   ExpectSemicolon(CHECK_OK);
    781   return Statement::Jump();
    782 }
    783 
    784 
    785 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
    786   // ReturnStatement ::
    787   //   'return' [no line terminator] Expression? ';'
    788 
    789   // Consume the return token. It is necessary to do before
    790   // reporting any errors on it, because of the way errors are
    791   // reported (underlining).
    792   Expect(Token::RETURN, CHECK_OK);
    793   function_state_->set_return_location(scanner()->location());
    794 
    795   // An ECMAScript program is considered syntactically incorrect if it
    796   // contains a return statement that is not within the body of a
    797   // function. See ECMA-262, section 12.9, page 67.
    798   // This is not handled during preparsing.
    799 
    800   Token::Value tok = peek();
    801   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
    802       tok != Token::SEMICOLON &&
    803       tok != Token::RBRACE &&
    804       tok != Token::EOS) {
    805     if (is_strong(language_mode()) &&
    806         IsClassConstructor(function_state_->kind())) {
    807       int pos = peek_position();
    808       ReportMessageAt(Scanner::Location(pos, pos + 1),
    809                       MessageTemplate::kStrongConstructorReturnValue);
    810       *ok = false;
    811       return Statement::Default();
    812     }
    813     ParseExpression(true, CHECK_OK);
    814   }
    815   ExpectSemicolon(CHECK_OK);
    816   return Statement::Jump();
    817 }
    818 
    819 
    820 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
    821   // WithStatement ::
    822   //   'with' '(' Expression ')' Statement
    823   Expect(Token::WITH, CHECK_OK);
    824   if (is_strict(language_mode())) {
    825     ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
    826     *ok = false;
    827     return Statement::Default();
    828   }
    829   Expect(Token::LPAREN, CHECK_OK);
    830   ParseExpression(true, CHECK_OK);
    831   Expect(Token::RPAREN, CHECK_OK);
    832 
    833   Scope* with_scope = NewScope(scope_, WITH_SCOPE);
    834   BlockState block_state(&scope_, with_scope);
    835   ParseSubStatement(CHECK_OK);
    836   return Statement::Default();
    837 }
    838 
    839 
    840 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
    841   // SwitchStatement ::
    842   //   'switch' '(' Expression ')' '{' CaseClause* '}'
    843 
    844   Expect(Token::SWITCH, CHECK_OK);
    845   Expect(Token::LPAREN, CHECK_OK);
    846   ParseExpression(true, CHECK_OK);
    847   Expect(Token::RPAREN, CHECK_OK);
    848 
    849   Expect(Token::LBRACE, CHECK_OK);
    850   Token::Value token = peek();
    851   while (token != Token::RBRACE) {
    852     if (token == Token::CASE) {
    853       Expect(Token::CASE, CHECK_OK);
    854       ParseExpression(true, CHECK_OK);
    855     } else {
    856       Expect(Token::DEFAULT, CHECK_OK);
    857     }
    858     Expect(Token::COLON, CHECK_OK);
    859     token = peek();
    860     Statement statement = Statement::Jump();
    861     while (token != Token::CASE &&
    862            token != Token::DEFAULT &&
    863            token != Token::RBRACE) {
    864       statement = ParseStatementListItem(CHECK_OK);
    865       token = peek();
    866     }
    867     if (is_strong(language_mode()) && !statement.IsJumpStatement() &&
    868         token != Token::RBRACE) {
    869       ReportMessageAt(scanner()->location(),
    870                       MessageTemplate::kStrongSwitchFallthrough);
    871       *ok = false;
    872       return Statement::Default();
    873     }
    874   }
    875   Expect(Token::RBRACE, ok);
    876   return Statement::Default();
    877 }
    878 
    879 
    880 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
    881   // DoStatement ::
    882   //   'do' Statement 'while' '(' Expression ')' ';'
    883 
    884   Expect(Token::DO, CHECK_OK);
    885   ParseSubStatement(CHECK_OK);
    886   Expect(Token::WHILE, CHECK_OK);
    887   Expect(Token::LPAREN, CHECK_OK);
    888   ParseExpression(true, CHECK_OK);
    889   Expect(Token::RPAREN, ok);
    890   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
    891   return Statement::Default();
    892 }
    893 
    894 
    895 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
    896   // WhileStatement ::
    897   //   'while' '(' Expression ')' Statement
    898 
    899   Expect(Token::WHILE, CHECK_OK);
    900   Expect(Token::LPAREN, CHECK_OK);
    901   ParseExpression(true, CHECK_OK);
    902   Expect(Token::RPAREN, CHECK_OK);
    903   ParseSubStatement(ok);
    904   return Statement::Default();
    905 }
    906 
    907 
    908 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
    909   // ForStatement ::
    910   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
    911 
    912   Expect(Token::FOR, CHECK_OK);
    913   Expect(Token::LPAREN, CHECK_OK);
    914   bool is_let_identifier_expression = false;
    915   if (peek() != Token::SEMICOLON) {
    916     ForEachStatement::VisitMode mode;
    917     if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
    918         (peek() == Token::LET && IsNextLetKeyword())) {
    919       int decl_count;
    920       bool is_lexical;
    921       bool is_binding_pattern;
    922       Scanner::Location first_initializer_loc = Scanner::Location::invalid();
    923       Scanner::Location bindings_loc = Scanner::Location::invalid();
    924       ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
    925                                 &is_binding_pattern, &first_initializer_loc,
    926                                 &bindings_loc, CHECK_OK);
    927       bool accept_IN = decl_count >= 1;
    928       if (accept_IN && CheckInOrOf(&mode, ok)) {
    929         if (!*ok) return Statement::Default();
    930         if (decl_count != 1) {
    931           const char* loop_type =
    932               mode == ForEachStatement::ITERATE ? "for-of" : "for-in";
    933           PreParserTraits::ReportMessageAt(
    934               bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
    935               loop_type);
    936           *ok = false;
    937           return Statement::Default();
    938         }
    939         if (first_initializer_loc.IsValid() &&
    940             (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
    941              is_lexical || is_binding_pattern)) {
    942           if (mode == ForEachStatement::ITERATE) {
    943             ReportMessageAt(first_initializer_loc,
    944                             MessageTemplate::kForOfLoopInitializer);
    945           } else {
    946             // TODO(caitp): This should be an error in sloppy mode, too.
    947             ReportMessageAt(first_initializer_loc,
    948                             MessageTemplate::kForInLoopInitializer);
    949           }
    950           *ok = false;
    951           return Statement::Default();
    952         }
    953         ParseExpression(true, CHECK_OK);
    954         Expect(Token::RPAREN, CHECK_OK);
    955         ParseSubStatement(CHECK_OK);
    956         return Statement::Default();
    957       }
    958     } else {
    959       int lhs_beg_pos = peek_position();
    960       ExpressionClassifier classifier;
    961       Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
    962       int lhs_end_pos = scanner()->location().end_pos;
    963       is_let_identifier_expression =
    964           lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
    965       bool is_for_each = CheckInOrOf(&mode, ok);
    966       if (!*ok) return Statement::Default();
    967       bool is_destructuring = is_for_each &&
    968                               allow_harmony_destructuring_assignment() &&
    969                               (lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
    970 
    971       if (is_destructuring) {
    972         ValidateAssignmentPattern(&classifier, CHECK_OK);
    973       } else {
    974         ValidateExpression(&classifier, CHECK_OK);
    975       }
    976 
    977       if (is_for_each) {
    978         if (!is_destructuring) {
    979           lhs = CheckAndRewriteReferenceExpression(
    980               lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
    981               kSyntaxError, CHECK_OK);
    982         }
    983         ParseExpression(true, CHECK_OK);
    984         Expect(Token::RPAREN, CHECK_OK);
    985         ParseSubStatement(CHECK_OK);
    986         return Statement::Default();
    987       }
    988     }
    989   }
    990 
    991   // Parsed initializer at this point.
    992   // Detect attempts at 'let' declarations in sloppy mode.
    993   if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
    994       is_sloppy(language_mode()) && is_let_identifier_expression) {
    995     ReportMessage(MessageTemplate::kSloppyLexical, NULL);
    996     *ok = false;
    997     return Statement::Default();
    998   }
    999   Expect(Token::SEMICOLON, CHECK_OK);
   1000 
   1001   if (peek() != Token::SEMICOLON) {
   1002     ParseExpression(true, CHECK_OK);
   1003   }
   1004   Expect(Token::SEMICOLON, CHECK_OK);
   1005 
   1006   if (peek() != Token::RPAREN) {
   1007     ParseExpression(true, CHECK_OK);
   1008   }
   1009   Expect(Token::RPAREN, CHECK_OK);
   1010 
   1011   ParseSubStatement(ok);
   1012   return Statement::Default();
   1013 }
   1014 
   1015 
   1016 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
   1017   // ThrowStatement ::
   1018   //   'throw' [no line terminator] Expression ';'
   1019 
   1020   Expect(Token::THROW, CHECK_OK);
   1021   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
   1022     ReportMessageAt(scanner()->location(), MessageTemplate::kNewlineAfterThrow);
   1023     *ok = false;
   1024     return Statement::Default();
   1025   }
   1026   ParseExpression(true, CHECK_OK);
   1027   ExpectSemicolon(ok);
   1028   return Statement::Jump();
   1029 }
   1030 
   1031 
   1032 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
   1033   // TryStatement ::
   1034   //   'try' Block Catch
   1035   //   'try' Block Finally
   1036   //   'try' Block Catch Finally
   1037   //
   1038   // Catch ::
   1039   //   'catch' '(' Identifier ')' Block
   1040   //
   1041   // Finally ::
   1042   //   'finally' Block
   1043 
   1044   Expect(Token::TRY, CHECK_OK);
   1045 
   1046   ParseBlock(CHECK_OK);
   1047 
   1048   Token::Value tok = peek();
   1049   if (tok != Token::CATCH && tok != Token::FINALLY) {
   1050     ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
   1051     *ok = false;
   1052     return Statement::Default();
   1053   }
   1054   if (tok == Token::CATCH) {
   1055     Consume(Token::CATCH);
   1056     Expect(Token::LPAREN, CHECK_OK);
   1057     ExpressionClassifier pattern_classifier;
   1058     ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
   1059     ValidateBindingPattern(&pattern_classifier, CHECK_OK);
   1060     Expect(Token::RPAREN, CHECK_OK);
   1061     {
   1062       // TODO(adamk): Make this CATCH_SCOPE
   1063       Scope* with_scope = NewScope(scope_, WITH_SCOPE);
   1064       BlockState block_state(&scope_, with_scope);
   1065       ParseBlock(CHECK_OK);
   1066     }
   1067     tok = peek();
   1068   }
   1069   if (tok == Token::FINALLY) {
   1070     Consume(Token::FINALLY);
   1071     ParseBlock(CHECK_OK);
   1072   }
   1073   return Statement::Default();
   1074 }
   1075 
   1076 
   1077 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
   1078   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
   1079   // contexts this is used as a statement which invokes the debugger as if a
   1080   // break point is present.
   1081   // DebuggerStatement ::
   1082   //   'debugger' ';'
   1083 
   1084   Expect(Token::DEBUGGER, CHECK_OK);
   1085   ExpectSemicolon(ok);
   1086   return Statement::Default();
   1087 }
   1088 
   1089 
   1090 #undef CHECK_OK
   1091 #define CHECK_OK  ok);                     \
   1092   if (!*ok) return Expression::Default();  \
   1093   ((void)0
   1094 #define DUMMY )  // to make indentation work
   1095 #undef DUMMY
   1096 
   1097 
   1098 PreParser::Expression PreParser::ParseFunctionLiteral(
   1099     Identifier function_name, Scanner::Location function_name_location,
   1100     FunctionNameValidity function_name_validity, FunctionKind kind,
   1101     int function_token_pos, FunctionLiteral::FunctionType function_type,
   1102     FunctionLiteral::ArityRestriction arity_restriction,
   1103     LanguageMode language_mode, bool* ok) {
   1104   // Function ::
   1105   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
   1106 
   1107   // Parse function body.
   1108   bool outer_is_script_scope = scope_->is_script_scope();
   1109   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
   1110   function_scope->SetLanguageMode(language_mode);
   1111   PreParserFactory factory(NULL);
   1112   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
   1113                                &factory);
   1114   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
   1115   ExpressionClassifier formals_classifier(&duplicate_finder);
   1116 
   1117   Expect(Token::LPAREN, CHECK_OK);
   1118   int start_position = scanner()->location().beg_pos;
   1119   function_scope->set_start_position(start_position);
   1120   PreParserFormalParameters formals(function_scope);
   1121   ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
   1122   Expect(Token::RPAREN, CHECK_OK);
   1123   int formals_end_position = scanner()->location().end_pos;
   1124 
   1125   CheckArityRestrictions(formals.arity, arity_restriction,
   1126                          formals.has_rest, start_position,
   1127                          formals_end_position, CHECK_OK);
   1128 
   1129   // See Parser::ParseFunctionLiteral for more information about lazy parsing
   1130   // and lazy compilation.
   1131   bool is_lazily_parsed =
   1132       (outer_is_script_scope && allow_lazy() && !parenthesized_function_);
   1133   parenthesized_function_ = false;
   1134 
   1135   Expect(Token::LBRACE, CHECK_OK);
   1136   if (is_lazily_parsed) {
   1137     ParseLazyFunctionLiteralBody(CHECK_OK);
   1138   } else {
   1139     ParseStatementList(Token::RBRACE, CHECK_OK);
   1140   }
   1141   Expect(Token::RBRACE, CHECK_OK);
   1142 
   1143   // Parsing the body may change the language mode in our scope.
   1144   language_mode = function_scope->language_mode();
   1145 
   1146   // Validate name and parameter names. We can do this only after parsing the
   1147   // function, since the function can declare itself strict.
   1148   CheckFunctionName(language_mode, function_name, function_name_validity,
   1149                     function_name_location, CHECK_OK);
   1150   const bool allow_duplicate_parameters =
   1151       is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
   1152   ValidateFormalParameters(&formals_classifier, language_mode,
   1153                            allow_duplicate_parameters, CHECK_OK);
   1154 
   1155   if (is_strict(language_mode)) {
   1156     int end_position = scanner()->location().end_pos;
   1157     CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
   1158   }
   1159 
   1160   if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
   1161     if (!function_state.super_location().IsValid()) {
   1162       ReportMessageAt(function_name_location,
   1163                       MessageTemplate::kStrongSuperCallMissing,
   1164                       kReferenceError);
   1165       *ok = false;
   1166       return Expression::Default();
   1167     }
   1168   }
   1169 
   1170   return Expression::Default();
   1171 }
   1172 
   1173 
   1174 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
   1175                                              Scanner::BookmarkScope* bookmark) {
   1176   int body_start = position();
   1177   ParseStatementList(Token::RBRACE, ok, bookmark);
   1178   if (!*ok) return;
   1179   if (bookmark && bookmark->HasBeenReset()) return;
   1180 
   1181   // Position right after terminal '}'.
   1182   DCHECK_EQ(Token::RBRACE, scanner()->peek());
   1183   int body_end = scanner()->peek_location().end_pos;
   1184   log_->LogFunction(body_start, body_end,
   1185                     function_state_->materialized_literal_count(),
   1186                     function_state_->expected_property_count(), language_mode(),
   1187                     scope_->uses_super_property(), scope_->calls_eval());
   1188 }
   1189 
   1190 
   1191 PreParserExpression PreParser::ParseClassLiteral(
   1192     PreParserIdentifier name, Scanner::Location class_name_location,
   1193     bool name_is_strict_reserved, int pos, bool* ok) {
   1194   // All parts of a ClassDeclaration and ClassExpression are strict code.
   1195   if (name_is_strict_reserved) {
   1196     ReportMessageAt(class_name_location,
   1197                     MessageTemplate::kUnexpectedStrictReserved);
   1198     *ok = false;
   1199     return EmptyExpression();
   1200   }
   1201   if (IsEvalOrArguments(name)) {
   1202     ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
   1203     *ok = false;
   1204     return EmptyExpression();
   1205   }
   1206   LanguageMode class_language_mode = language_mode();
   1207   if (is_strong(class_language_mode) && IsUndefined(name)) {
   1208     ReportMessageAt(class_name_location, MessageTemplate::kStrongUndefined);
   1209     *ok = false;
   1210     return EmptyExpression();
   1211   }
   1212 
   1213   Scope* scope = NewScope(scope_, BLOCK_SCOPE);
   1214   BlockState block_state(&scope_, scope);
   1215   scope_->SetLanguageMode(
   1216       static_cast<LanguageMode>(class_language_mode | STRICT));
   1217   // TODO(marja): Make PreParser use scope names too.
   1218   // scope_->SetScopeName(name);
   1219 
   1220   bool has_extends = Check(Token::EXTENDS);
   1221   if (has_extends) {
   1222     ExpressionClassifier classifier;
   1223     ParseLeftHandSideExpression(&classifier, CHECK_OK);
   1224     ValidateExpression(&classifier, CHECK_OK);
   1225   }
   1226 
   1227   ClassLiteralChecker checker(this);
   1228   bool has_seen_constructor = false;
   1229 
   1230   Expect(Token::LBRACE, CHECK_OK);
   1231   while (peek() != Token::RBRACE) {
   1232     if (Check(Token::SEMICOLON)) continue;
   1233     const bool in_class = true;
   1234     const bool is_static = false;
   1235     bool is_computed_name = false;  // Classes do not care about computed
   1236                                     // property names here.
   1237     Identifier name;
   1238     ExpressionClassifier classifier;
   1239     ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
   1240                             &is_computed_name, &has_seen_constructor,
   1241                             &classifier, &name, CHECK_OK);
   1242     ValidateExpression(&classifier, CHECK_OK);
   1243   }
   1244 
   1245   Expect(Token::RBRACE, CHECK_OK);
   1246 
   1247   return Expression::Default();
   1248 }
   1249 
   1250 
   1251 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
   1252   // CallRuntime ::
   1253   //   '%' Identifier Arguments
   1254   Expect(Token::MOD, CHECK_OK);
   1255   if (!allow_natives()) {
   1256     *ok = false;
   1257     return Expression::Default();
   1258   }
   1259   // Allow "eval" or "arguments" for backward compatibility.
   1260   ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
   1261   Scanner::Location spread_pos;
   1262   ExpressionClassifier classifier;
   1263   ParseArguments(&spread_pos, &classifier, ok);
   1264   ValidateExpression(&classifier, CHECK_OK);
   1265 
   1266   DCHECK(!spread_pos.IsValid());
   1267 
   1268   return Expression::Default();
   1269 }
   1270 
   1271 
   1272 PreParserExpression PreParser::ParseDoExpression(bool* ok) {
   1273   // AssignmentExpression ::
   1274   //     do '{' StatementList '}'
   1275   Expect(Token::DO, CHECK_OK);
   1276   Expect(Token::LBRACE, CHECK_OK);
   1277   Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
   1278   {
   1279     BlockState block_state(&scope_, block_scope);
   1280     while (peek() != Token::RBRACE) {
   1281       ParseStatementListItem(CHECK_OK);
   1282     }
   1283     Expect(Token::RBRACE, CHECK_OK);
   1284     return PreParserExpression::Default();
   1285   }
   1286 }
   1287 
   1288 #undef CHECK_OK
   1289 
   1290 
   1291 }  // namespace internal
   1292 }  // namespace v8
   1293