| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 69 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 70 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 70 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
| 71 void set_allow_harmony_scoping(bool allow) { | 71 void set_allow_harmony_scoping(bool allow) { |
| 72 scanner()->SetHarmonyScoping(allow); | 72 scanner()->SetHarmonyScoping(allow); |
| 73 } | 73 } |
| 74 void set_allow_harmony_numeric_literals(bool allow) { | 74 void set_allow_harmony_numeric_literals(bool allow) { |
| 75 scanner()->SetHarmonyNumericLiterals(allow); | 75 scanner()->SetHarmonyNumericLiterals(allow); |
| 76 } | 76 } |
| 77 | 77 |
| 78 protected: | 78 protected: |
| 79 enum AllowEvalOrArgumentsAsIdentifier { |
| 80 kAllowEvalOrArguments, |
| 81 kDontAllowEvalOrArguments |
| 82 }; |
| 83 |
| 79 Scanner* scanner() const { return scanner_; } | 84 Scanner* scanner() const { return scanner_; } |
| 80 int position() { return scanner_->location().beg_pos; } | 85 int position() { return scanner_->location().beg_pos; } |
| 81 int peek_position() { return scanner_->peek_location().beg_pos; } | 86 int peek_position() { return scanner_->peek_location().beg_pos; } |
| 82 bool stack_overflow() const { return stack_overflow_; } | 87 bool stack_overflow() const { return stack_overflow_; } |
| 83 void set_stack_overflow() { stack_overflow_ = true; } | 88 void set_stack_overflow() { stack_overflow_ = true; } |
| 84 | 89 |
| 90 virtual bool is_classic_mode() = 0; |
| 91 |
| 85 INLINE(Token::Value peek()) { | 92 INLINE(Token::Value peek()) { |
| 86 if (stack_overflow_) return Token::ILLEGAL; | 93 if (stack_overflow_) return Token::ILLEGAL; |
| 87 return scanner()->peek(); | 94 return scanner()->peek(); |
| 88 } | 95 } |
| 89 | 96 |
| 90 INLINE(Token::Value Next()) { | 97 INLINE(Token::Value Next()) { |
| 91 if (stack_overflow_) return Token::ILLEGAL; | 98 if (stack_overflow_) return Token::ILLEGAL; |
| 92 { | 99 { |
| 93 int marker; | 100 int marker; |
| 94 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) { | 101 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 bool CheckContextualKeyword(Vector<const char> keyword); | 137 bool CheckContextualKeyword(Vector<const char> keyword); |
| 131 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); | 138 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); |
| 132 | 139 |
| 133 // Strict mode octal literal validation. | 140 // Strict mode octal literal validation. |
| 134 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); | 141 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); |
| 135 | 142 |
| 136 // Determine precedence of given token. | 143 // Determine precedence of given token. |
| 137 static int Precedence(Token::Value token, bool accept_IN); | 144 static int Precedence(Token::Value token, bool accept_IN); |
| 138 | 145 |
| 139 // Report syntax errors. | 146 // Report syntax errors. |
| 140 virtual void ReportUnexpectedToken(Token::Value token) = 0; | 147 void ReportUnexpectedToken(Token::Value token); |
| 141 virtual void ReportMessageAt(Scanner::Location loc, const char* type) = 0; | 148 void ReportMessageAt(Scanner::Location location, const char* type) { |
| 149 ReportMessageAt(location, type, Vector<const char*>::empty()); |
| 150 } |
| 151 virtual void ReportMessageAt(Scanner::Location source_location, |
| 152 const char* message, |
| 153 Vector<const char*> args) = 0; |
| 142 | 154 |
| 143 // Used to detect duplicates in object literals. Each of the values | 155 // Used to detect duplicates in object literals. Each of the values |
| 144 // kGetterProperty, kSetterProperty and kValueProperty represents | 156 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 145 // a type of object literal property. When parsing a property, its | 157 // a type of object literal property. When parsing a property, its |
| 146 // type value is stored in the DuplicateFinder for the property name. | 158 // type value is stored in the DuplicateFinder for the property name. |
| 147 // Values are chosen so that having intersection bits means the there is | 159 // Values are chosen so that having intersection bits means the there is |
| 148 // an incompatibility. | 160 // an incompatibility. |
| 149 // I.e., you can add a getter to a property that already has a setter, since | 161 // I.e., you can add a getter to a property that already has a setter, since |
| 150 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 162 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
| 151 // already has a getter or a value. Adding the getter to an existing | 163 // already has a getter or a value. Adding the getter to an existing |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 kPreParseStackOverflow, | 236 kPreParseStackOverflow, |
| 225 kPreParseSuccess | 237 kPreParseSuccess |
| 226 }; | 238 }; |
| 227 | 239 |
| 228 PreParser(Scanner* scanner, | 240 PreParser(Scanner* scanner, |
| 229 ParserRecorder* log, | 241 ParserRecorder* log, |
| 230 uintptr_t stack_limit) | 242 uintptr_t stack_limit) |
| 231 : ParserBase(scanner, stack_limit), | 243 : ParserBase(scanner, stack_limit), |
| 232 log_(log), | 244 log_(log), |
| 233 scope_(NULL), | 245 scope_(NULL), |
| 234 strict_mode_violation_location_(Scanner::Location::invalid()), | |
| 235 strict_mode_violation_type_(NULL), | |
| 236 parenthesized_function_(false) { } | 246 parenthesized_function_(false) { } |
| 237 | 247 |
| 238 ~PreParser() {} | 248 ~PreParser() {} |
| 239 | 249 |
| 240 // Pre-parse the program from the character stream; returns true on | 250 // Pre-parse the program from the character stream; returns true on |
| 241 // success (even if parsing failed, the pre-parse data successfully | 251 // success (even if parsing failed, the pre-parse data successfully |
| 242 // captured the syntax error), and false if a stack-overflow happened | 252 // captured the syntax error), and false if a stack-overflow happened |
| 243 // during parsing. | 253 // during parsing. |
| 244 PreParseResult PreParseProgram() { | 254 PreParseResult PreParseProgram() { |
| 245 Scope top_scope(&scope_, kTopLevelScope); | 255 Scope top_scope(&scope_, kTopLevelScope); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 Type type_; | 345 Type type_; |
| 336 | 346 |
| 337 friend class Expression; | 347 friend class Expression; |
| 338 }; | 348 }; |
| 339 | 349 |
| 340 // Bits 0 and 1 are used to identify the type of expression: | 350 // Bits 0 and 1 are used to identify the type of expression: |
| 341 // If bit 0 is set, it's an identifier. | 351 // If bit 0 is set, it's an identifier. |
| 342 // if bit 1 is set, it's a string literal. | 352 // if bit 1 is set, it's a string literal. |
| 343 // If neither is set, it's no particular type, and both set isn't | 353 // If neither is set, it's no particular type, and both set isn't |
| 344 // use yet. | 354 // use yet. |
| 345 // Bit 2 is used to mark the expression as being parenthesized, | |
| 346 // so "(foo)" isn't recognized as a pure identifier (and possible label). | |
| 347 class Expression { | 355 class Expression { |
| 348 public: | 356 public: |
| 349 static Expression Default() { | 357 static Expression Default() { |
| 350 return Expression(kUnknownExpression); | 358 return Expression(kUnknownExpression); |
| 351 } | 359 } |
| 352 | 360 |
| 353 static Expression FromIdentifier(Identifier id) { | 361 static Expression FromIdentifier(Identifier id) { |
| 354 return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift)); | 362 return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift)); |
| 355 } | 363 } |
| 356 | 364 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 377 bool IsIdentifier() { | 385 bool IsIdentifier() { |
| 378 return (code_ & kIdentifierFlag) != 0; | 386 return (code_ & kIdentifierFlag) != 0; |
| 379 } | 387 } |
| 380 | 388 |
| 381 // Only works corretly if it is actually an identifier expression. | 389 // Only works corretly if it is actually an identifier expression. |
| 382 PreParser::Identifier AsIdentifier() { | 390 PreParser::Identifier AsIdentifier() { |
| 383 return PreParser::Identifier( | 391 return PreParser::Identifier( |
| 384 static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift)); | 392 static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift)); |
| 385 } | 393 } |
| 386 | 394 |
| 387 bool IsParenthesized() { | |
| 388 // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized. | |
| 389 return (code_ & 7) > 4; | |
| 390 } | |
| 391 | |
| 392 bool IsRawIdentifier() { | |
| 393 return !IsParenthesized() && IsIdentifier(); | |
| 394 } | |
| 395 | |
| 396 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 395 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } |
| 397 | 396 |
| 398 bool IsRawStringLiteral() { | |
| 399 return !IsParenthesized() && IsStringLiteral(); | |
| 400 } | |
| 401 | |
| 402 bool IsUseStrictLiteral() { | 397 bool IsUseStrictLiteral() { |
| 403 return (code_ & kStringLiteralMask) == kUseStrictString; | 398 return (code_ & kStringLiteralMask) == kUseStrictString; |
| 404 } | 399 } |
| 405 | 400 |
| 406 bool IsThis() { | 401 bool IsThis() { |
| 407 return code_ == kThisExpression; | 402 return code_ == kThisExpression; |
| 408 } | 403 } |
| 409 | 404 |
| 410 bool IsThisProperty() { | 405 bool IsThisProperty() { |
| 411 return code_ == kThisPropertyExpression; | 406 return code_ == kThisPropertyExpression; |
| 412 } | 407 } |
| 413 | 408 |
| 414 bool IsStrictFunction() { | 409 bool IsStrictFunction() { |
| 415 return code_ == kStrictFunctionExpression; | 410 return code_ == kStrictFunctionExpression; |
| 416 } | 411 } |
| 417 | 412 |
| 418 Expression Parenthesize() { | |
| 419 int type = code_ & 3; | |
| 420 if (type != 0) { | |
| 421 // Identifiers and string literals can be parenthesized. | |
| 422 // They no longer work as labels or directive prologues, | |
| 423 // but are still recognized in other contexts. | |
| 424 return Expression(code_ | kParenthesizedExpressionFlag); | |
| 425 } | |
| 426 // For other types of expressions, it's not important to remember | |
| 427 // the parentheses. | |
| 428 return *this; | |
| 429 } | |
| 430 | |
| 431 private: | 413 private: |
| 432 // First two/three bits are used as flags. | 414 // First two/three bits are used as flags. |
| 433 // Bit 0 and 1 represent identifiers or strings literals, and are | 415 // Bit 0 and 1 represent identifiers or strings literals, and are |
| 434 // mutually exclusive, but can both be absent. | 416 // mutually exclusive, but can both be absent. |
| 435 // If bit 0 or 1 are set, bit 2 marks that the expression has | |
| 436 // been wrapped in parentheses (a string literal can no longer | |
| 437 // be a directive prologue, and an identifier can no longer be | |
| 438 // a label. | |
| 439 enum { | 417 enum { |
| 440 kUnknownExpression = 0, | 418 kUnknownExpression = 0, |
| 441 // Identifiers | 419 // Identifiers |
| 442 kIdentifierFlag = 1, // Used to detect labels. | 420 kIdentifierFlag = 1, // Used to detect labels. |
| 443 kIdentifierShift = 3, | 421 kIdentifierShift = 3, |
| 444 | 422 |
| 445 kStringLiteralFlag = 2, // Used to detect directive prologue. | 423 kStringLiteralFlag = 2, // Used to detect directive prologue. |
| 446 kUnknownStringLiteral = kStringLiteralFlag, | 424 kUnknownStringLiteral = kStringLiteralFlag, |
| 447 kUseStrictString = kStringLiteralFlag | 8, | 425 kUseStrictString = kStringLiteralFlag | 8, |
| 448 kStringLiteralMask = kUseStrictString, | 426 kStringLiteralMask = kUseStrictString, |
| 449 | 427 |
| 450 // Only if identifier or string literal. | |
| 451 kParenthesizedExpressionFlag = 4, | |
| 452 | |
| 453 // Below here applies if neither identifier nor string literal. | 428 // Below here applies if neither identifier nor string literal. |
| 454 kThisExpression = 4, | 429 kThisExpression = 4, |
| 455 kThisPropertyExpression = 8, | 430 kThisPropertyExpression = 8, |
| 456 kStrictFunctionExpression = 12 | 431 kStrictFunctionExpression = 12 |
| 457 }; | 432 }; |
| 458 | 433 |
| 459 explicit Expression(int expression_code) : code_(expression_code) { } | 434 explicit Expression(int expression_code) : code_(expression_code) { } |
| 460 | 435 |
| 461 int code_; | 436 int code_; |
| 462 }; | 437 }; |
| 463 | 438 |
| 464 class Statement { | 439 class Statement { |
| 465 public: | 440 public: |
| 466 static Statement Default() { | 441 static Statement Default() { |
| 467 return Statement(kUnknownStatement); | 442 return Statement(kUnknownStatement); |
| 468 } | 443 } |
| 469 | 444 |
| 470 static Statement FunctionDeclaration() { | 445 static Statement FunctionDeclaration() { |
| 471 return Statement(kFunctionDeclaration); | 446 return Statement(kFunctionDeclaration); |
| 472 } | 447 } |
| 473 | 448 |
| 474 // Creates expression statement from expression. | 449 // Creates expression statement from expression. |
| 475 // Preserves being an unparenthesized string literal, possibly | 450 // Preserves being an unparenthesized string literal, possibly |
| 476 // "use strict". | 451 // "use strict". |
| 477 static Statement ExpressionStatement(Expression expression) { | 452 static Statement ExpressionStatement(Expression expression) { |
| 478 if (!expression.IsParenthesized()) { | 453 if (expression.IsUseStrictLiteral()) { |
| 479 if (expression.IsUseStrictLiteral()) { | 454 return Statement(kUseStrictExpressionStatement); |
| 480 return Statement(kUseStrictExpressionStatement); | 455 } |
| 481 } | 456 if (expression.IsStringLiteral()) { |
| 482 if (expression.IsStringLiteral()) { | 457 return Statement(kStringLiteralExpressionStatement); |
| 483 return Statement(kStringLiteralExpressionStatement); | |
| 484 } | |
| 485 } | 458 } |
| 486 return Default(); | 459 return Default(); |
| 487 } | 460 } |
| 488 | 461 |
| 489 bool IsStringLiteral() { | 462 bool IsStringLiteral() { |
| 490 return code_ == kStringLiteralExpressionStatement; | 463 return code_ == kStringLiteralExpressionStatement; |
| 491 } | 464 } |
| 492 | 465 |
| 493 bool IsUseStrictLiteral() { | 466 bool IsUseStrictLiteral() { |
| 494 return code_ == kUseStrictExpressionStatement; | 467 return code_ == kUseStrictExpressionStatement; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 Scope* const prev_; | 540 Scope* const prev_; |
| 568 const ScopeType type_; | 541 const ScopeType type_; |
| 569 int materialized_literal_count_; | 542 int materialized_literal_count_; |
| 570 int expected_properties_; | 543 int expected_properties_; |
| 571 int with_nesting_count_; | 544 int with_nesting_count_; |
| 572 LanguageMode language_mode_; | 545 LanguageMode language_mode_; |
| 573 bool is_generator_; | 546 bool is_generator_; |
| 574 }; | 547 }; |
| 575 | 548 |
| 576 // Report syntax error | 549 // Report syntax error |
| 577 void ReportUnexpectedToken(Token::Value token); | 550 void ReportMessageAt(Scanner::Location location, |
| 578 void ReportMessageAt(Scanner::Location location, const char* type) { | 551 const char* message, |
| 579 ReportMessageAt(location, type, NULL); | 552 Vector<const char*> args) { |
| 553 ReportMessageAt(location.beg_pos, |
| 554 location.end_pos, |
| 555 message, |
| 556 args.length() > 0 ? args[0] : NULL); |
| 580 } | 557 } |
| 581 void ReportMessageAt(Scanner::Location location, | 558 void ReportMessageAt(Scanner::Location location, |
| 582 const char* type, | 559 const char* type, |
| 583 const char* name_opt) { | 560 const char* name_opt) { |
| 584 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); | 561 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); |
| 585 } | 562 } |
| 586 void ReportMessageAt(int start_pos, | 563 void ReportMessageAt(int start_pos, |
| 587 int end_pos, | 564 int end_pos, |
| 588 const char* type, | 565 const char* type, |
| 589 const char* name_opt) { | 566 const char* name_opt) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 Expression ParseNewExpression(bool* ok); | 607 Expression ParseNewExpression(bool* ok); |
| 631 Expression ParseMemberExpression(bool* ok); | 608 Expression ParseMemberExpression(bool* ok); |
| 632 Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); | 609 Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); |
| 633 Expression ParsePrimaryExpression(bool* ok); | 610 Expression ParsePrimaryExpression(bool* ok); |
| 634 Expression ParseArrayLiteral(bool* ok); | 611 Expression ParseArrayLiteral(bool* ok); |
| 635 Expression ParseObjectLiteral(bool* ok); | 612 Expression ParseObjectLiteral(bool* ok); |
| 636 Expression ParseRegExpLiteral(bool seen_equal, bool* ok); | 613 Expression ParseRegExpLiteral(bool seen_equal, bool* ok); |
| 637 Expression ParseV8Intrinsic(bool* ok); | 614 Expression ParseV8Intrinsic(bool* ok); |
| 638 | 615 |
| 639 Arguments ParseArguments(bool* ok); | 616 Arguments ParseArguments(bool* ok); |
| 640 Expression ParseFunctionLiteral(bool is_generator, bool* ok); | 617 Expression ParseFunctionLiteral( |
| 618 Identifier name, |
| 619 Scanner::Location function_name_location, |
| 620 bool name_is_strict_reserved, |
| 621 bool is_generator, |
| 622 bool* ok); |
| 641 void ParseLazyFunctionLiteralBody(bool* ok); | 623 void ParseLazyFunctionLiteralBody(bool* ok); |
| 642 | 624 |
| 643 Identifier ParseIdentifier(bool* ok); | 625 Identifier ParseIdentifier(AllowEvalOrArgumentsAsIdentifier, bool* ok); |
| 626 Identifier ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
| 627 bool* ok); |
| 644 Identifier ParseIdentifierName(bool* ok); | 628 Identifier ParseIdentifierName(bool* ok); |
| 645 Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, | 629 Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 646 bool* is_set, | 630 bool* is_set, |
| 647 bool* ok); | 631 bool* ok); |
| 648 | 632 |
| 649 // Logs the currently parsed literal as a symbol in the preparser data. | 633 // Logs the currently parsed literal as a symbol in the preparser data. |
| 650 void LogSymbol(); | 634 void LogSymbol(); |
| 651 // Log the currently parsed identifier. | 635 // Log the currently parsed identifier. |
| 652 Identifier GetIdentifierSymbol(); | 636 Identifier GetIdentifierSymbol(); |
| 653 // Log the currently parsed string literal. | 637 // Log the currently parsed string literal. |
| 654 Expression GetStringSymbol(); | 638 Expression GetStringSymbol(); |
| 655 | 639 |
| 656 void set_language_mode(LanguageMode language_mode) { | 640 void set_language_mode(LanguageMode language_mode) { |
| 657 scope_->set_language_mode(language_mode); | 641 scope_->set_language_mode(language_mode); |
| 658 } | 642 } |
| 659 | 643 |
| 660 bool is_classic_mode() { | 644 virtual bool is_classic_mode() { |
| 661 return scope_->language_mode() == CLASSIC_MODE; | 645 return scope_->language_mode() == CLASSIC_MODE; |
| 662 } | 646 } |
| 663 | 647 |
| 664 bool is_extended_mode() { | 648 bool is_extended_mode() { |
| 665 return scope_->language_mode() == EXTENDED_MODE; | 649 return scope_->language_mode() == EXTENDED_MODE; |
| 666 } | 650 } |
| 667 | 651 |
| 668 LanguageMode language_mode() { return scope_->language_mode(); } | 652 LanguageMode language_mode() { return scope_->language_mode(); } |
| 669 | 653 |
| 670 bool CheckInOrOf(bool accept_OF); | 654 bool CheckInOrOf(bool accept_OF); |
| 671 | 655 |
| 672 void SetStrictModeViolation(Scanner::Location, | |
| 673 const char* type, | |
| 674 bool* ok); | |
| 675 | |
| 676 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); | |
| 677 | |
| 678 void StrictModeIdentifierViolation(Scanner::Location, | |
| 679 const char* eval_args_type, | |
| 680 Identifier identifier, | |
| 681 bool* ok); | |
| 682 | |
| 683 ParserRecorder* log_; | 656 ParserRecorder* log_; |
| 684 Scope* scope_; | 657 Scope* scope_; |
| 685 Scanner::Location strict_mode_violation_location_; | |
| 686 const char* strict_mode_violation_type_; | |
| 687 bool parenthesized_function_; | 658 bool parenthesized_function_; |
| 688 }; | 659 }; |
| 689 | 660 |
| 690 } } // v8::internal | 661 } } // v8::internal |
| 691 | 662 |
| 692 #endif // V8_PREPARSER_H | 663 #endif // V8_PREPARSER_H |
| OLD | NEW |