Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
| 6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 kArgumentsIdentifier | 601 kArgumentsIdentifier |
| 602 }; | 602 }; |
| 603 explicit PreParserIdentifier(Type type) : type_(type) {} | 603 explicit PreParserIdentifier(Type type) : type_(type) {} |
| 604 Type type_; | 604 Type type_; |
| 605 | 605 |
| 606 friend class PreParserExpression; | 606 friend class PreParserExpression; |
| 607 friend class PreParserScope; | 607 friend class PreParserScope; |
| 608 }; | 608 }; |
| 609 | 609 |
| 610 | 610 |
| 611 // Bits 0 and 1 are used to identify the type of expression: | |
| 612 // If bit 0 is set, it's an identifier. | |
| 613 // if bit 1 is set, it's a string literal. | |
| 614 // If neither is set, it's no particular type, and both set isn't | |
| 615 // use yet. | |
| 616 class PreParserExpression { | 611 class PreParserExpression { |
| 617 public: | 612 public: |
| 618 static PreParserExpression Default() { | 613 static PreParserExpression Default() { |
| 619 return PreParserExpression(kUnknownExpression); | 614 return PreParserExpression(kExpression); |
| 620 } | 615 } |
| 621 | 616 |
| 622 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 617 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 623 return PreParserExpression(kTypeIdentifier | | 618 PreParserExpression expr(kIdentifierExpression); |
| 624 (id.type_ << kIdentifierShift)); | 619 expr.detail_.identifier_type = id.type_; |
| 620 return expr; | |
| 625 } | 621 } |
| 626 | 622 |
| 627 static PreParserExpression BinaryOperation(PreParserExpression left, | 623 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 628 Token::Value op, | 624 Token::Value op, |
| 629 PreParserExpression right) { | 625 PreParserExpression right) { |
| 630 int code = ((op == Token::COMMA) && !left.is_parenthesized() && | 626 PreParserExpression expr(kBinaryOperationExpression); |
| 631 !right.is_parenthesized()) | 627 expr.detail_.valid_arrow_param_list = |
| 632 ? left.ArrowParamListBit() & right.ArrowParamListBit() | 628 op == Token::COMMA && !left.is_parenthesized() && |
| 633 : 0; | 629 !right.is_parenthesized() && left.IsValidArrowParams() && |
| 634 return PreParserExpression(kTypeBinaryOperation | code); | 630 right.IsValidArrowParams(); |
| 631 return expr; | |
| 635 } | 632 } |
| 636 | 633 |
| 637 static PreParserExpression EmptyArrowParamList() { | 634 static PreParserExpression EmptyArrowParamList() { |
| 638 // Any expression for which IsValidArrowParamList() returns true | 635 // Any expression for which IsValidArrowParamList() returns true |
| 639 // will work here. | 636 // will work here. |
| 640 return FromIdentifier(PreParserIdentifier::Default()); | 637 return FromIdentifier(PreParserIdentifier::Default()); |
| 641 } | 638 } |
| 642 | 639 |
| 643 static PreParserExpression StringLiteral() { | 640 static PreParserExpression StringLiteral() { |
| 644 return PreParserExpression(kUnknownStringLiteral); | 641 return PreParserExpression(kStringLiteralExpression); |
| 645 } | 642 } |
| 646 | 643 |
| 647 static PreParserExpression UseStrictStringLiteral() { | 644 static PreParserExpression UseStrictStringLiteral() { |
| 648 return PreParserExpression(kUseStrictString); | 645 PreParserExpression expr(kStringLiteralExpression); |
| 646 expr.detail_.string_literal_is_use_strict = true; | |
| 647 return expr; | |
| 649 } | 648 } |
| 650 | 649 |
| 651 static PreParserExpression This() { | 650 static PreParserExpression This() { |
| 652 return PreParserExpression(kThisExpression); | 651 PreParserExpression expr(kExpression); |
| 652 expr.detail_.expression_type = kThisExpression; | |
| 653 return expr; | |
| 653 } | 654 } |
| 654 | 655 |
| 655 static PreParserExpression ThisProperty() { | 656 static PreParserExpression ThisProperty() { |
| 656 return PreParserExpression(kThisPropertyExpression); | 657 PreParserExpression expr(kExpression); |
| 658 expr.detail_.expression_type = kThisPropertyExpression; | |
| 659 return expr; | |
| 657 } | 660 } |
| 658 | 661 |
| 659 static PreParserExpression Property() { | 662 static PreParserExpression Property() { |
| 660 return PreParserExpression(kPropertyExpression); | 663 PreParserExpression expr(kExpression); |
| 664 expr.detail_.expression_type = kPropertyExpression; | |
| 665 return expr; | |
| 661 } | 666 } |
| 662 | 667 |
| 663 static PreParserExpression Call() { | 668 static PreParserExpression Call() { |
| 664 return PreParserExpression(kCallExpression); | 669 PreParserExpression expr(kExpression); |
| 670 expr.detail_.expression_type = kCallExpression; | |
| 671 return expr; | |
| 665 } | 672 } |
| 666 | 673 |
| 667 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } | 674 bool IsIdentifier() const { return type_ == kIdentifierExpression; } |
| 668 | 675 |
| 669 PreParserIdentifier AsIdentifier() const { | 676 PreParserIdentifier AsIdentifier() const { |
| 670 ASSERT(IsIdentifier()); | 677 ASSERT(IsIdentifier()); |
| 671 return PreParserIdentifier( | 678 return PreParserIdentifier(detail_.identifier_type); |
| 672 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | |
| 673 } | 679 } |
| 674 | 680 |
| 675 bool IsStringLiteral() const { | 681 bool IsStringLiteral() const { return type_ == kStringLiteralExpression; } |
| 676 return (code_ & kTypeMask) == kTypeStringLiteral; | 682 |
| 683 bool IsUseStrictLiteral() const { | |
| 684 return type_ == kStringLiteralExpression && | |
| 685 detail_.string_literal_is_use_strict; | |
| 677 } | 686 } |
| 678 | 687 |
| 679 bool IsUseStrictLiteral() const { | 688 bool IsThis() const { |
| 680 return (code_ & kUseStrictString) == kUseStrictString; | 689 return type_ == kExpression && detail_.expression_type == kThisExpression; |
| 681 } | 690 } |
| 682 | 691 |
| 683 bool IsThis() const { return (code_ & kThisExpression) == kThisExpression; } | |
| 684 | |
| 685 bool IsThisProperty() const { | 692 bool IsThisProperty() const { |
| 686 return (code_ & kThisPropertyExpression) == kThisPropertyExpression; | 693 return type_ == kExpression && |
| 694 detail_.expression_type == kThisPropertyExpression; | |
| 687 } | 695 } |
| 688 | 696 |
| 689 bool IsProperty() const { | 697 bool IsProperty() const { |
| 690 return (code_ & kPropertyExpression) == kPropertyExpression || | 698 return type_ == kExpression && |
| 691 (code_ & kThisPropertyExpression) == kThisPropertyExpression; | 699 (detail_.expression_type == kPropertyExpression || |
| 700 detail_.expression_type == kThisPropertyExpression); | |
| 692 } | 701 } |
| 693 | 702 |
| 694 bool IsCall() const { return (code_ & kCallExpression) == kCallExpression; } | 703 bool IsCall() const { |
| 704 return type_ == kExpression && detail_.expression_type == kCallExpression; | |
| 705 } | |
| 695 | 706 |
| 696 bool IsValidReferenceExpression() const { | 707 bool IsValidReferenceExpression() const { |
| 697 return IsIdentifier() || IsProperty(); | 708 return IsIdentifier() || IsProperty(); |
| 698 } | 709 } |
| 699 | 710 |
| 700 bool IsValidArrowParamList() const { | 711 bool IsValidArrowParamList() const { |
| 701 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && | 712 return IsValidArrowParams() && |
| 702 (code_ & kMultiParenthesizedExpression) == 0; | 713 parenthesization_ != kMultiParenthesizedExpression; |
| 703 } | 714 } |
| 704 | 715 |
| 705 // At the moment PreParser doesn't track these expression types. | 716 // At the moment PreParser doesn't track these expression types. |
| 706 bool IsFunctionLiteral() const { return false; } | 717 bool IsFunctionLiteral() const { return false; } |
| 707 bool IsCallNew() const { return false; } | 718 bool IsCallNew() const { return false; } |
| 708 | 719 |
| 709 PreParserExpression AsFunctionLiteral() { return *this; } | 720 PreParserExpression AsFunctionLiteral() { return *this; } |
| 710 | 721 |
| 711 bool IsBinaryOperation() const { | 722 bool IsBinaryOperation() const { return type_ == kBinaryOperationExpression; } |
| 712 return (code_ & kTypeMask) == kTypeBinaryOperation; | |
| 713 } | |
| 714 | 723 |
| 715 bool is_parenthesized() const { | 724 bool is_parenthesized() const { |
| 716 return (code_ & kParenthesizedExpression) != 0; | 725 return parenthesization_ != kNotParenthesized; |
| 717 } | 726 } |
| 718 | 727 |
| 719 void increase_parenthesization_level() { | 728 void increase_parenthesization_level() { |
| 720 code_ |= is_parenthesized() ? kMultiParenthesizedExpression | 729 parenthesization_ = is_parenthesized() ? kMultiParenthesizedExpression |
| 721 : kParenthesizedExpression; | 730 : kParenthesizedExpression; |
| 722 } | 731 } |
| 723 | 732 |
| 724 // Dummy implementation for making expression->somefunc() work in both Parser | 733 // Dummy implementation for making expression->somefunc() work in both Parser |
| 725 // and PreParser. | 734 // and PreParser. |
| 726 PreParserExpression* operator->() { return this; } | 735 PreParserExpression* operator->() { return this; } |
| 727 | 736 |
| 728 // More dummy implementations of things PreParser doesn't need to track: | 737 // More dummy implementations of things PreParser doesn't need to track: |
| 729 void set_index(int index) {} // For YieldExpressions | 738 void set_index(int index) {} // For YieldExpressions |
| 730 void set_parenthesized() {} | 739 void set_parenthesized() {} |
| 731 | 740 |
| 732 int position() const { return RelocInfo::kNoPosition; } | 741 int position() const { return RelocInfo::kNoPosition; } |
| 733 void set_function_token_position(int position) {} | 742 void set_function_token_position(int position) {} |
| 734 void set_ast_properties(int* ast_properties) {} | 743 void set_ast_properties(int* ast_properties) {} |
| 735 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | 744 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
| 736 | 745 |
| 737 bool operator==(const PreParserExpression& other) const { | |
| 738 return code_ == other.code_; | |
| 739 } | |
| 740 bool operator!=(const PreParserExpression& other) const { | |
| 741 return code_ != other.code_; | |
| 742 } | |
| 743 | |
| 744 private: | 746 private: |
| 745 // Least significant 2 bits are used as expression type. The third least | 747 enum Type { |
| 746 // significant bit tracks whether an expression is parenthesized. If the | 748 kExpression, |
| 747 // expression is an identifier or a string literal, the other bits | 749 kIdentifierExpression, |
| 748 // describe the type/ (see PreParserIdentifier::Type and string literal | 750 kStringLiteralExpression, |
| 749 // constants below). For binary operations, the other bits are flags | 751 kBinaryOperationExpression |
| 750 // which further describe the contents of the expression. | |
| 751 enum { | |
| 752 kUnknownExpression = 0, | |
| 753 kTypeMask = 1 | 2, | |
| 754 kParenthesizedExpression = (1 << 2), | |
| 755 kMultiParenthesizedExpression = (1 << 3), | |
| 756 | |
| 757 // Identifiers | |
| 758 kTypeIdentifier = 1, // Used to detect labels. | |
| 759 kIdentifierShift = 5, | |
| 760 kTypeStringLiteral = 2, // Used to detect directive prologue. | |
| 761 kUnknownStringLiteral = kTypeStringLiteral, | |
| 762 kUseStrictString = kTypeStringLiteral | 32, | |
| 763 kStringLiteralMask = kUseStrictString, | |
| 764 | |
| 765 // Binary operations. Those are needed to detect certain keywords and | |
| 766 // duplicated identifier in parameter lists for arrow functions, because | |
| 767 // they are initially parsed as comma-separated expressions. | |
| 768 kTypeBinaryOperation = 3, | |
| 769 kBinaryOperationArrowParamList = (1 << 4), | |
| 770 | |
| 771 // Below here applies if neither identifier nor string literal. Reserve the | |
| 772 // 2 least significant bits for flags. | |
| 773 kThisExpression = (1 << 4), | |
| 774 kThisPropertyExpression = (2 << 4), | |
| 775 kPropertyExpression = (3 << 4), | |
| 776 kCallExpression = (4 << 4) | |
| 777 }; | 752 }; |
| 778 | 753 |
| 779 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 754 enum Parenthesization { |
| 755 kNotParenthesized, | |
| 756 kParenthesizedExpression, | |
| 757 kMultiParenthesizedExpression | |
| 758 }; | |
| 780 | 759 |
| 781 V8_INLINE int ArrowParamListBit() const { | 760 enum ExpressionType { |
| 782 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; | 761 kThisExpression, |
| 762 kThisPropertyExpression, | |
| 763 kPropertyExpression, | |
| 764 kCallExpression | |
| 765 }; | |
| 766 | |
| 767 explicit PreParserExpression(Type type) : type_(type) {} | |
| 768 | |
| 769 V8_INLINE bool IsValidArrowParams() const { | |
| 770 if (IsBinaryOperation()) return detail_.valid_arrow_param_list; | |
| 783 if (IsIdentifier()) { | 771 if (IsIdentifier()) { |
| 784 const PreParserIdentifier ident = AsIdentifier(); | 772 const PreParserIdentifier ident = AsIdentifier(); |
| 785 // A valid identifier can be an arrow function parameter list | 773 // A valid identifier can be an arrow function parameter list |
| 786 // except for eval, arguments, yield, and reserved keywords. | 774 // except for eval, arguments, yield, and reserved keywords. |
| 787 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || | 775 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || |
| 788 ident.IsFutureStrictReserved()) | 776 ident.IsFutureStrictReserved()) |
| 789 return 0; | 777 return false; |
| 790 return kBinaryOperationArrowParamList; | 778 return true; |
| 791 } | 779 } |
| 792 return 0; | 780 return false; |
| 793 } | 781 } |
| 794 | 782 |
| 795 int code_; | 783 Type type_ : 2; |
|
Sven Panne
2014/08/04 06:55:57
This actually blows up memory usage instead of red
| |
| 784 Parenthesization parenthesization_ : 2; | |
| 785 union { | |
| 786 // Used for kExpression | |
| 787 ExpressionType expression_type : 2; | |
| 788 | |
| 789 // Used for kStringLiteralExpression | |
| 790 bool string_literal_is_use_strict : 1; | |
| 791 | |
| 792 // Used for kBinaryOperationExpression | |
| 793 bool valid_arrow_param_list : 1; | |
| 794 | |
| 795 // Used for kIdentifierExpression | |
| 796 PreParserIdentifier::Type identifier_type : 10; | |
| 797 } detail_; | |
| 796 }; | 798 }; |
| 797 | 799 |
| 798 | 800 |
| 799 // PreParserExpressionList doesn't actually store the expressions because | 801 // PreParserExpressionList doesn't actually store the expressions because |
| 800 // PreParser doesn't need to. | 802 // PreParser doesn't need to. |
| 801 class PreParserExpressionList { | 803 class PreParserExpressionList { |
| 802 public: | 804 public: |
| 803 // These functions make list->Add(some_expression) work (and do nothing). | 805 // These functions make list->Add(some_expression) work (and do nothing). |
| 804 PreParserExpressionList() : length_(0) {} | 806 PreParserExpressionList() : length_(0) {} |
| 805 PreParserExpressionList* operator->() { return this; } | 807 PreParserExpressionList* operator->() { return this; } |
| (...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2619 parser()->ReportMessage("accessor_get_set"); | 2621 parser()->ReportMessage("accessor_get_set"); |
| 2620 } | 2622 } |
| 2621 *ok = false; | 2623 *ok = false; |
| 2622 } | 2624 } |
| 2623 } | 2625 } |
| 2624 | 2626 |
| 2625 | 2627 |
| 2626 } } // v8::internal | 2628 } } // v8::internal |
| 2627 | 2629 |
| 2628 #endif // V8_PREPARSER_H | 2630 #endif // V8_PREPARSER_H |
| OLD | NEW |