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