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 "include/v8stdint.h" 8 9 #include "src/allocation.h" 10 #include "src/base/logging.h" 11 #include "src/conversions-inl.h" 12 #include "src/conversions.h" 13 #include "src/globals.h" 14 #include "src/hashmap.h" 15 #include "src/list.h" 16 #include "src/preparse-data.h" 17 #include "src/preparse-data-format.h" 18 #include "src/preparser.h" 19 #include "src/unicode.h" 20 #include "src/utils.h" 21 22 #if V8_LIBC_MSVCRT && (_MSC_VER < 1800) 23 namespace std { 24 25 // Usually defined in math.h, but not in MSVC until VS2013+. 26 // Abstracted to work 27 int isfinite(double value); 28 29 } // namespace std 30 #endif 31 32 namespace v8 { 33 namespace internal { 34 35 class PreParserTraits::Checkpoint 36 : public ParserBase<PreParserTraits>::CheckpointBase { 37 public: 38 explicit Checkpoint(ParserBase<PreParserTraits>* parser) 39 : ParserBase<PreParserTraits>::CheckpointBase(parser) {} 40 }; 41 42 void PreParserTraits::ReportMessageAt(Scanner::Location location, 43 const char* message, 44 const char* arg, 45 bool is_reference_error) { 46 ReportMessageAt(location.beg_pos, 47 location.end_pos, 48 message, 49 arg, 50 is_reference_error); 51 } 52 53 54 void PreParserTraits::ReportMessageAt(int start_pos, 55 int end_pos, 56 const char* message, 57 const char* arg, 58 bool is_reference_error) { 59 pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, 60 is_reference_error); 61 } 62 63 64 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) { 65 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) { 66 return PreParserIdentifier::FutureReserved(); 67 } else if (scanner->current_token() == 68 Token::FUTURE_STRICT_RESERVED_WORD) { 69 return PreParserIdentifier::FutureStrictReserved(); 70 } else if (scanner->current_token() == Token::LET) { 71 return PreParserIdentifier::Let(); 72 } else if (scanner->current_token() == Token::YIELD) { 73 return PreParserIdentifier::Yield(); 74 } 75 if (scanner->UnescapedLiteralMatches("eval", 4)) { 76 return PreParserIdentifier::Eval(); 77 } 78 if (scanner->UnescapedLiteralMatches("arguments", 9)) { 79 return PreParserIdentifier::Arguments(); 80 } 81 if (scanner->UnescapedLiteralMatches("prototype", 9)) { 82 return PreParserIdentifier::Prototype(); 83 } 84 if (scanner->UnescapedLiteralMatches("constructor", 11)) { 85 return PreParserIdentifier::Constructor(); 86 } 87 return PreParserIdentifier::Default(); 88 } 89 90 91 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) { 92 return PreParserIdentifier::Default(); 93 } 94 95 96 PreParserExpression PreParserTraits::ExpressionFromString( 97 int pos, Scanner* scanner, PreParserFactory* factory) { 98 if (scanner->UnescapedLiteralMatches("use strict", 10)) { 99 return PreParserExpression::UseStrictStringLiteral(); 100 } 101 return PreParserExpression::StringLiteral(); 102 } 103 104 105 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) { 106 return pre_parser_->ParseV8Intrinsic(ok); 107 } 108 109 110 PreParserExpression PreParserTraits::ParseFunctionLiteral( 111 PreParserIdentifier name, Scanner::Location function_name_location, 112 bool name_is_strict_reserved, FunctionKind kind, 113 int function_token_position, FunctionLiteral::FunctionType type, 114 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 115 return pre_parser_->ParseFunctionLiteral( 116 name, function_name_location, name_is_strict_reserved, kind, 117 function_token_position, type, arity_restriction, ok); 118 } 119 120 121 PreParser::PreParseResult PreParser::PreParseLazyFunction( 122 StrictMode strict_mode, bool is_generator, ParserRecorder* log) { 123 log_ = log; 124 // Lazy functions always have trivial outer scopes (no with/catch scopes). 125 PreParserScope top_scope(scope_, GLOBAL_SCOPE); 126 FunctionState top_state(&function_state_, &scope_, &top_scope, NULL, 127 this->ast_value_factory()); 128 scope_->SetStrictMode(strict_mode); 129 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 130 FunctionState function_state(&function_state_, &scope_, &function_scope, NULL, 131 this->ast_value_factory()); 132 function_state.set_is_generator(is_generator); 133 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 134 bool ok = true; 135 int start_position = peek_position(); 136 ParseLazyFunctionLiteralBody(&ok); 137 if (stack_overflow()) return kPreParseStackOverflow; 138 if (!ok) { 139 ReportUnexpectedToken(scanner()->current_token()); 140 } else { 141 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 142 if (scope_->strict_mode() == STRICT) { 143 int end_pos = scanner()->location().end_pos; 144 CheckOctalLiteral(start_position, end_pos, &ok); 145 } 146 } 147 return kPreParseSuccess; 148 } 149 150 151 // Preparsing checks a JavaScript program and emits preparse-data that helps 152 // a later parsing to be faster. 153 // See preparser-data.h for the data. 154 155 // The PreParser checks that the syntax follows the grammar for JavaScript, 156 // and collects some information about the program along the way. 157 // The grammar check is only performed in order to understand the program 158 // sufficiently to deduce some information about it, that can be used 159 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 160 // rather it is to speed up properly written and correct programs. 161 // That means that contextual checks (like a label being declared where 162 // it is used) are generally omitted. 163 164 165 #define CHECK_OK ok); \ 166 if (!*ok) return kUnknownSourceElements; \ 167 ((void)0 168 #define DUMMY ) // to make indentation work 169 #undef DUMMY 170 171 172 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 173 // (Ecma 262 5th Edition, clause 14): 174 // SourceElement: 175 // Statement 176 // FunctionDeclaration 177 // 178 // In harmony mode we allow additionally the following productions 179 // SourceElement: 180 // LetDeclaration 181 // ConstDeclaration 182 // GeneratorDeclaration 183 184 switch (peek()) { 185 case Token::FUNCTION: 186 return ParseFunctionDeclaration(ok); 187 case Token::CLASS: 188 return ParseClassDeclaration(ok); 189 case Token::CONST: 190 return ParseVariableStatement(kSourceElement, ok); 191 case Token::LET: 192 DCHECK(allow_harmony_scoping()); 193 if (strict_mode() == STRICT) { 194 return ParseVariableStatement(kSourceElement, ok); 195 } 196 // Fall through. 197 default: 198 return ParseStatement(ok); 199 } 200 } 201 202 203 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 204 bool* ok) { 205 // SourceElements :: 206 // (Statement)* <end_token> 207 208 bool directive_prologue = true; 209 while (peek() != end_token) { 210 if (directive_prologue && peek() != Token::STRING) { 211 directive_prologue = false; 212 } 213 Statement statement = ParseSourceElement(CHECK_OK); 214 if (directive_prologue) { 215 if (statement.IsUseStrictLiteral()) { 216 scope_->SetStrictMode(STRICT); 217 } else if (!statement.IsStringLiteral()) { 218 directive_prologue = false; 219 } 220 } 221 } 222 return kUnknownSourceElements; 223 } 224 225 226 #undef CHECK_OK 227 #define CHECK_OK ok); \ 228 if (!*ok) return Statement::Default(); \ 229 ((void)0 230 #define DUMMY ) // to make indentation work 231 #undef DUMMY 232 233 234 PreParser::Statement PreParser::ParseStatement(bool* ok) { 235 // Statement :: 236 // Block 237 // VariableStatement 238 // EmptyStatement 239 // ExpressionStatement 240 // IfStatement 241 // IterationStatement 242 // ContinueStatement 243 // BreakStatement 244 // ReturnStatement 245 // WithStatement 246 // LabelledStatement 247 // SwitchStatement 248 // ThrowStatement 249 // TryStatement 250 // DebuggerStatement 251 252 // Note: Since labels can only be used by 'break' and 'continue' 253 // statements, which themselves are only valid within blocks, 254 // iterations or 'switch' statements (i.e., BreakableStatements), 255 // labels can be simply ignored in all other cases; except for 256 // trivial labeled break statements 'label: break label' which is 257 // parsed into an empty statement. 258 259 // Keep the source position of the statement 260 switch (peek()) { 261 case Token::LBRACE: 262 return ParseBlock(ok); 263 264 case Token::SEMICOLON: 265 Next(); 266 return Statement::Default(); 267 268 case Token::IF: 269 return ParseIfStatement(ok); 270 271 case Token::DO: 272 return ParseDoWhileStatement(ok); 273 274 case Token::WHILE: 275 return ParseWhileStatement(ok); 276 277 case Token::FOR: 278 return ParseForStatement(ok); 279 280 case Token::CONTINUE: 281 return ParseContinueStatement(ok); 282 283 case Token::BREAK: 284 return ParseBreakStatement(ok); 285 286 case Token::RETURN: 287 return ParseReturnStatement(ok); 288 289 case Token::WITH: 290 return ParseWithStatement(ok); 291 292 case Token::SWITCH: 293 return ParseSwitchStatement(ok); 294 295 case Token::THROW: 296 return ParseThrowStatement(ok); 297 298 case Token::TRY: 299 return ParseTryStatement(ok); 300 301 case Token::FUNCTION: { 302 Scanner::Location start_location = scanner()->peek_location(); 303 Statement statement = ParseFunctionDeclaration(CHECK_OK); 304 Scanner::Location end_location = scanner()->location(); 305 if (strict_mode() == STRICT) { 306 PreParserTraits::ReportMessageAt(start_location.beg_pos, 307 end_location.end_pos, 308 "strict_function"); 309 *ok = false; 310 return Statement::Default(); 311 } else { 312 return statement; 313 } 314 } 315 316 case Token::CLASS: 317 return ParseClassDeclaration(CHECK_OK); 318 319 case Token::DEBUGGER: 320 return ParseDebuggerStatement(ok); 321 322 case Token::VAR: 323 case Token::CONST: 324 return ParseVariableStatement(kStatement, ok); 325 326 case Token::LET: 327 DCHECK(allow_harmony_scoping()); 328 if (strict_mode() == STRICT) { 329 return ParseVariableStatement(kStatement, ok); 330 } 331 // Fall through. 332 default: 333 return ParseExpressionOrLabelledStatement(ok); 334 } 335 } 336 337 338 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 339 // FunctionDeclaration :: 340 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 341 // GeneratorDeclaration :: 342 // 'function' '*' Identifier '(' FormalParameterListopt ')' 343 // '{' FunctionBody '}' 344 Expect(Token::FUNCTION, CHECK_OK); 345 int pos = position(); 346 bool is_generator = Check(Token::MUL); 347 bool is_strict_reserved = false; 348 Identifier name = ParseIdentifierOrStrictReservedWord( 349 &is_strict_reserved, CHECK_OK); 350 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, 351 is_generator ? FunctionKind::kGeneratorFunction 352 : FunctionKind::kNormalFunction, 353 pos, FunctionLiteral::DECLARATION, 354 FunctionLiteral::NORMAL_ARITY, CHECK_OK); 355 return Statement::FunctionDeclaration(); 356 } 357 358 359 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 360 Expect(Token::CLASS, CHECK_OK); 361 int pos = position(); 362 bool is_strict_reserved = false; 363 Identifier name = 364 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 365 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, 366 CHECK_OK); 367 return Statement::Default(); 368 } 369 370 371 PreParser::Statement PreParser::ParseBlock(bool* ok) { 372 // Block :: 373 // '{' Statement* '}' 374 375 // Note that a Block does not introduce a new execution scope! 376 // (ECMA-262, 3rd, 12.2) 377 // 378 Expect(Token::LBRACE, CHECK_OK); 379 while (peek() != Token::RBRACE) { 380 if (allow_harmony_scoping() && strict_mode() == STRICT) { 381 ParseSourceElement(CHECK_OK); 382 } else { 383 ParseStatement(CHECK_OK); 384 } 385 } 386 Expect(Token::RBRACE, ok); 387 return Statement::Default(); 388 } 389 390 391 PreParser::Statement PreParser::ParseVariableStatement( 392 VariableDeclarationContext var_context, 393 bool* ok) { 394 // VariableStatement :: 395 // VariableDeclarations ';' 396 397 Statement result = ParseVariableDeclarations(var_context, 398 NULL, 399 NULL, 400 CHECK_OK); 401 ExpectSemicolon(CHECK_OK); 402 return result; 403 } 404 405 406 // If the variable declaration declares exactly one non-const 407 // variable, then *var is set to that variable. In all other cases, 408 // *var is untouched; in particular, it is the caller's responsibility 409 // to initialize it properly. This mechanism is also used for the parsing 410 // of 'for-in' loops. 411 PreParser::Statement PreParser::ParseVariableDeclarations( 412 VariableDeclarationContext var_context, 413 VariableDeclarationProperties* decl_props, 414 int* num_decl, 415 bool* ok) { 416 // VariableDeclarations :: 417 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 418 // 419 // The ES6 Draft Rev3 specifies the following grammar for const declarations 420 // 421 // ConstDeclaration :: 422 // const ConstBinding (',' ConstBinding)* ';' 423 // ConstBinding :: 424 // Identifier '=' AssignmentExpression 425 // 426 // TODO(ES6): 427 // ConstBinding :: 428 // BindingPattern '=' AssignmentExpression 429 bool require_initializer = false; 430 if (peek() == Token::VAR) { 431 Consume(Token::VAR); 432 } else if (peek() == Token::CONST) { 433 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 434 // 435 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 436 // 437 // * It is a Syntax Error if the code that matches this production is not 438 // contained in extended code. 439 // 440 // However disallowing const in sloppy mode will break compatibility with 441 // existing pages. Therefore we keep allowing const with the old 442 // non-harmony semantics in sloppy mode. 443 Consume(Token::CONST); 444 if (strict_mode() == STRICT) { 445 if (allow_harmony_scoping()) { 446 if (var_context != kSourceElement && var_context != kForStatement) { 447 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); 448 *ok = false; 449 return Statement::Default(); 450 } 451 require_initializer = true; 452 } else { 453 Scanner::Location location = scanner()->peek_location(); 454 ReportMessageAt(location, "strict_const"); 455 *ok = false; 456 return Statement::Default(); 457 } 458 } 459 } else if (peek() == Token::LET && strict_mode() == STRICT) { 460 Consume(Token::LET); 461 if (var_context != kSourceElement && var_context != kForStatement) { 462 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 463 *ok = false; 464 return Statement::Default(); 465 } 466 } else { 467 *ok = false; 468 return Statement::Default(); 469 } 470 471 // The scope of a var/const declared variable anywhere inside a function 472 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 473 // of a let declared variable is the scope of the immediately enclosing 474 // block. 475 int nvars = 0; // the number of variables declared 476 do { 477 // Parse variable name. 478 if (nvars > 0) Consume(Token::COMMA); 479 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 480 nvars++; 481 if (peek() == Token::ASSIGN || require_initializer) { 482 Expect(Token::ASSIGN, CHECK_OK); 483 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 484 if (decl_props != NULL) *decl_props = kHasInitializers; 485 } 486 } while (peek() == Token::COMMA); 487 488 if (num_decl != NULL) *num_decl = nvars; 489 return Statement::Default(); 490 } 491 492 493 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 494 // ExpressionStatement | LabelledStatement :: 495 // Expression ';' 496 // Identifier ':' Statement 497 498 bool starts_with_identifier = peek_any_identifier(); 499 Expression expr = ParseExpression(true, CHECK_OK); 500 // Even if the expression starts with an identifier, it is not necessarily an 501 // identifier. For example, "foo + bar" starts with an identifier but is not 502 // an identifier. 503 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 504 // Expression is a single identifier, and not, e.g., a parenthesized 505 // identifier. 506 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 507 DCHECK(strict_mode() == SLOPPY || 508 (!expr.AsIdentifier().IsFutureStrictReserved() && 509 !expr.AsIdentifier().IsYield())); 510 Consume(Token::COLON); 511 return ParseStatement(ok); 512 // Preparsing is disabled for extensions (because the extension details 513 // aren't passed to lazily compiled functions), so we don't 514 // accept "native function" in the preparser. 515 } 516 // Parsed expression statement. 517 ExpectSemicolon(CHECK_OK); 518 return Statement::ExpressionStatement(expr); 519 } 520 521 522 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 523 // IfStatement :: 524 // 'if' '(' Expression ')' Statement ('else' Statement)? 525 526 Expect(Token::IF, CHECK_OK); 527 Expect(Token::LPAREN, CHECK_OK); 528 ParseExpression(true, CHECK_OK); 529 Expect(Token::RPAREN, CHECK_OK); 530 ParseStatement(CHECK_OK); 531 if (peek() == Token::ELSE) { 532 Next(); 533 ParseStatement(CHECK_OK); 534 } 535 return Statement::Default(); 536 } 537 538 539 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 540 // ContinueStatement :: 541 // 'continue' [no line terminator] Identifier? ';' 542 543 Expect(Token::CONTINUE, CHECK_OK); 544 Token::Value tok = peek(); 545 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 546 tok != Token::SEMICOLON && 547 tok != Token::RBRACE && 548 tok != Token::EOS) { 549 // ECMA allows "eval" or "arguments" as labels even in strict mode. 550 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 551 } 552 ExpectSemicolon(CHECK_OK); 553 return Statement::Default(); 554 } 555 556 557 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 558 // BreakStatement :: 559 // 'break' [no line terminator] Identifier? ';' 560 561 Expect(Token::BREAK, CHECK_OK); 562 Token::Value tok = peek(); 563 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 564 tok != Token::SEMICOLON && 565 tok != Token::RBRACE && 566 tok != Token::EOS) { 567 // ECMA allows "eval" or "arguments" as labels even in strict mode. 568 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 569 } 570 ExpectSemicolon(CHECK_OK); 571 return Statement::Default(); 572 } 573 574 575 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 576 // ReturnStatement :: 577 // 'return' [no line terminator] Expression? ';' 578 579 // Consume the return token. It is necessary to do before 580 // reporting any errors on it, because of the way errors are 581 // reported (underlining). 582 Expect(Token::RETURN, CHECK_OK); 583 584 // An ECMAScript program is considered syntactically incorrect if it 585 // contains a return statement that is not within the body of a 586 // function. See ECMA-262, section 12.9, page 67. 587 // This is not handled during preparsing. 588 589 Token::Value tok = peek(); 590 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 591 tok != Token::SEMICOLON && 592 tok != Token::RBRACE && 593 tok != Token::EOS) { 594 ParseExpression(true, CHECK_OK); 595 } 596 ExpectSemicolon(CHECK_OK); 597 return Statement::Default(); 598 } 599 600 601 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 602 // WithStatement :: 603 // 'with' '(' Expression ')' Statement 604 Expect(Token::WITH, CHECK_OK); 605 if (strict_mode() == STRICT) { 606 ReportMessageAt(scanner()->location(), "strict_mode_with"); 607 *ok = false; 608 return Statement::Default(); 609 } 610 Expect(Token::LPAREN, CHECK_OK); 611 ParseExpression(true, CHECK_OK); 612 Expect(Token::RPAREN, CHECK_OK); 613 614 PreParserScope with_scope(scope_, WITH_SCOPE); 615 BlockState block_state(&scope_, &with_scope); 616 ParseStatement(CHECK_OK); 617 return Statement::Default(); 618 } 619 620 621 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 622 // SwitchStatement :: 623 // 'switch' '(' Expression ')' '{' CaseClause* '}' 624 625 Expect(Token::SWITCH, CHECK_OK); 626 Expect(Token::LPAREN, CHECK_OK); 627 ParseExpression(true, CHECK_OK); 628 Expect(Token::RPAREN, CHECK_OK); 629 630 Expect(Token::LBRACE, CHECK_OK); 631 Token::Value token = peek(); 632 while (token != Token::RBRACE) { 633 if (token == Token::CASE) { 634 Expect(Token::CASE, CHECK_OK); 635 ParseExpression(true, CHECK_OK); 636 } else { 637 Expect(Token::DEFAULT, CHECK_OK); 638 } 639 Expect(Token::COLON, CHECK_OK); 640 token = peek(); 641 while (token != Token::CASE && 642 token != Token::DEFAULT && 643 token != Token::RBRACE) { 644 ParseStatement(CHECK_OK); 645 token = peek(); 646 } 647 } 648 Expect(Token::RBRACE, ok); 649 return Statement::Default(); 650 } 651 652 653 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 654 // DoStatement :: 655 // 'do' Statement 'while' '(' Expression ')' ';' 656 657 Expect(Token::DO, CHECK_OK); 658 ParseStatement(CHECK_OK); 659 Expect(Token::WHILE, CHECK_OK); 660 Expect(Token::LPAREN, CHECK_OK); 661 ParseExpression(true, CHECK_OK); 662 Expect(Token::RPAREN, ok); 663 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 664 return Statement::Default(); 665 } 666 667 668 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { 669 // WhileStatement :: 670 // 'while' '(' Expression ')' Statement 671 672 Expect(Token::WHILE, CHECK_OK); 673 Expect(Token::LPAREN, CHECK_OK); 674 ParseExpression(true, CHECK_OK); 675 Expect(Token::RPAREN, CHECK_OK); 676 ParseStatement(ok); 677 return Statement::Default(); 678 } 679 680 681 bool PreParser::CheckInOrOf(bool accept_OF) { 682 if (Check(Token::IN) || 683 (accept_OF && CheckContextualKeyword(CStrVector("of")))) { 684 return true; 685 } 686 return false; 687 } 688 689 690 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 691 // ForStatement :: 692 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 693 694 Expect(Token::FOR, CHECK_OK); 695 Expect(Token::LPAREN, CHECK_OK); 696 if (peek() != Token::SEMICOLON) { 697 if (peek() == Token::VAR || peek() == Token::CONST || 698 (peek() == Token::LET && strict_mode() == STRICT)) { 699 bool is_let = peek() == Token::LET; 700 int decl_count; 701 VariableDeclarationProperties decl_props = kHasNoInitializers; 702 ParseVariableDeclarations( 703 kForStatement, &decl_props, &decl_count, CHECK_OK); 704 bool has_initializers = decl_props == kHasInitializers; 705 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 706 bool accept_OF = !has_initializers; 707 if (accept_IN && CheckInOrOf(accept_OF)) { 708 ParseExpression(true, CHECK_OK); 709 Expect(Token::RPAREN, CHECK_OK); 710 711 ParseStatement(CHECK_OK); 712 return Statement::Default(); 713 } 714 } else { 715 Expression lhs = ParseExpression(false, CHECK_OK); 716 if (CheckInOrOf(lhs.IsIdentifier())) { 717 ParseExpression(true, CHECK_OK); 718 Expect(Token::RPAREN, CHECK_OK); 719 720 ParseStatement(CHECK_OK); 721 return Statement::Default(); 722 } 723 } 724 } 725 726 // Parsed initializer at this point. 727 Expect(Token::SEMICOLON, CHECK_OK); 728 729 if (peek() != Token::SEMICOLON) { 730 ParseExpression(true, CHECK_OK); 731 } 732 Expect(Token::SEMICOLON, CHECK_OK); 733 734 if (peek() != Token::RPAREN) { 735 ParseExpression(true, CHECK_OK); 736 } 737 Expect(Token::RPAREN, CHECK_OK); 738 739 ParseStatement(ok); 740 return Statement::Default(); 741 } 742 743 744 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 745 // ThrowStatement :: 746 // 'throw' [no line terminator] Expression ';' 747 748 Expect(Token::THROW, CHECK_OK); 749 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 750 ReportMessageAt(scanner()->location(), "newline_after_throw"); 751 *ok = false; 752 return Statement::Default(); 753 } 754 ParseExpression(true, CHECK_OK); 755 ExpectSemicolon(ok); 756 return Statement::Default(); 757 } 758 759 760 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { 761 // TryStatement :: 762 // 'try' Block Catch 763 // 'try' Block Finally 764 // 'try' Block Catch Finally 765 // 766 // Catch :: 767 // 'catch' '(' Identifier ')' Block 768 // 769 // Finally :: 770 // 'finally' Block 771 772 Expect(Token::TRY, CHECK_OK); 773 774 ParseBlock(CHECK_OK); 775 776 Token::Value tok = peek(); 777 if (tok != Token::CATCH && tok != Token::FINALLY) { 778 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); 779 *ok = false; 780 return Statement::Default(); 781 } 782 if (tok == Token::CATCH) { 783 Consume(Token::CATCH); 784 Expect(Token::LPAREN, CHECK_OK); 785 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 786 Expect(Token::RPAREN, CHECK_OK); 787 { 788 PreParserScope with_scope(scope_, WITH_SCOPE); 789 BlockState block_state(&scope_, &with_scope); 790 ParseBlock(CHECK_OK); 791 } 792 tok = peek(); 793 } 794 if (tok == Token::FINALLY) { 795 Consume(Token::FINALLY); 796 ParseBlock(CHECK_OK); 797 } 798 return Statement::Default(); 799 } 800 801 802 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 803 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 804 // contexts this is used as a statement which invokes the debugger as if a 805 // break point is present. 806 // DebuggerStatement :: 807 // 'debugger' ';' 808 809 Expect(Token::DEBUGGER, CHECK_OK); 810 ExpectSemicolon(ok); 811 return Statement::Default(); 812 } 813 814 815 #undef CHECK_OK 816 #define CHECK_OK ok); \ 817 if (!*ok) return Expression::Default(); \ 818 ((void)0 819 #define DUMMY ) // to make indentation work 820 #undef DUMMY 821 822 823 PreParser::Expression PreParser::ParseFunctionLiteral( 824 Identifier function_name, Scanner::Location function_name_location, 825 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, 826 FunctionLiteral::FunctionType function_type, 827 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 828 // Function :: 829 // '(' FormalParameterList? ')' '{' FunctionBody '}' 830 831 // Parse function body. 832 ScopeType outer_scope_type = scope_->type(); 833 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 834 FunctionState function_state(&function_state_, &scope_, &function_scope, NULL, 835 this->ast_value_factory()); 836 function_state.set_is_generator(IsGeneratorFunction(kind)); 837 // FormalParameterList :: 838 // '(' (Identifier)*[','] ')' 839 Expect(Token::LPAREN, CHECK_OK); 840 int start_position = position(); 841 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 842 // We don't yet know if the function will be strict, so we cannot yet produce 843 // errors for parameter names or duplicates. However, we remember the 844 // locations of these errors if they occur and produce the errors later. 845 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 846 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); 847 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); 848 849 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || 850 (peek() == Token::RPAREN && 851 arity_restriction != FunctionLiteral::SETTER_ARITY); 852 while (!done) { 853 bool is_strict_reserved = false; 854 Identifier param_name = 855 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 856 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { 857 eval_args_error_loc = scanner()->location(); 858 } 859 if (!reserved_error_loc.IsValid() && is_strict_reserved) { 860 reserved_error_loc = scanner()->location(); 861 } 862 863 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); 864 865 if (!dupe_error_loc.IsValid() && prev_value != 0) { 866 dupe_error_loc = scanner()->location(); 867 } 868 869 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; 870 done = (peek() == Token::RPAREN); 871 if (!done) Expect(Token::COMMA, CHECK_OK); 872 } 873 Expect(Token::RPAREN, CHECK_OK); 874 875 // See Parser::ParseFunctionLiteral for more information about lazy parsing 876 // and lazy compilation. 877 bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && allow_lazy() && 878 !parenthesized_function_); 879 parenthesized_function_ = false; 880 881 Expect(Token::LBRACE, CHECK_OK); 882 if (is_lazily_parsed) { 883 ParseLazyFunctionLiteralBody(CHECK_OK); 884 } else { 885 ParseSourceElements(Token::RBRACE, ok); 886 } 887 Expect(Token::RBRACE, CHECK_OK); 888 889 // Validate strict mode. We can do this only after parsing the function, 890 // since the function can declare itself strict. 891 // Concise methods use StrictFormalParameters. 892 if (strict_mode() == STRICT || IsConciseMethod(kind)) { 893 if (function_name.IsEvalOrArguments()) { 894 ReportMessageAt(function_name_location, "strict_eval_arguments"); 895 *ok = false; 896 return Expression::Default(); 897 } 898 if (name_is_strict_reserved) { 899 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); 900 *ok = false; 901 return Expression::Default(); 902 } 903 if (eval_args_error_loc.IsValid()) { 904 ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); 905 *ok = false; 906 return Expression::Default(); 907 } 908 if (dupe_error_loc.IsValid()) { 909 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); 910 *ok = false; 911 return Expression::Default(); 912 } 913 if (reserved_error_loc.IsValid()) { 914 ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved"); 915 *ok = false; 916 return Expression::Default(); 917 } 918 919 int end_position = scanner()->location().end_pos; 920 CheckOctalLiteral(start_position, end_position, CHECK_OK); 921 } 922 923 return Expression::Default(); 924 } 925 926 927 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 928 int body_start = position(); 929 ParseSourceElements(Token::RBRACE, ok); 930 if (!*ok) return; 931 932 // Position right after terminal '}'. 933 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 934 int body_end = scanner()->peek_location().end_pos; 935 log_->LogFunction(body_start, body_end, 936 function_state_->materialized_literal_count(), 937 function_state_->expected_property_count(), 938 strict_mode()); 939 } 940 941 942 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 943 // CallRuntime :: 944 // '%' Identifier Arguments 945 Expect(Token::MOD, CHECK_OK); 946 if (!allow_natives_syntax()) { 947 *ok = false; 948 return Expression::Default(); 949 } 950 // Allow "eval" or "arguments" for backward compatibility. 951 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 952 ParseArguments(ok); 953 954 return Expression::Default(); 955 } 956 957 #undef CHECK_OK 958 959 960 } } // v8::internal 961