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