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