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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } | 632 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
633 bool IsConstructor() const { return type_ == kConstructorIdentifier; } | 633 bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
634 bool IsEvalOrArguments() const { | 634 bool IsEvalOrArguments() const { |
635 return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier; | 635 return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier; |
636 } | 636 } |
637 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 637 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
638 bool IsFutureStrictReserved() const { | 638 bool IsFutureStrictReserved() const { |
639 return type_ == kFutureStrictReservedIdentifier; | 639 return type_ == kFutureStrictReservedIdentifier; |
640 } | 640 } |
641 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } | 641 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
642 V8_INLINE bool IsValidArrowParam() const { | |
643 // A valid identifier can be an arrow function parameter | |
644 // except for eval, arguments, yield, and reserved keywords. | |
645 return !(IsEval() || IsArguments() || IsYield() || | |
646 IsFutureStrictReserved()); | |
647 } | |
642 | 648 |
643 // Allow identifier->name()[->length()] to work. The preparser | 649 // Allow identifier->name()[->length()] to work. The preparser |
644 // does not need the actual positions/lengths of the identifiers. | 650 // does not need the actual positions/lengths of the identifiers. |
645 const PreParserIdentifier* operator->() const { return this; } | 651 const PreParserIdentifier* operator->() const { return this; } |
646 const PreParserIdentifier raw_name() const { return *this; } | 652 const PreParserIdentifier raw_name() const { return *this; } |
647 | 653 |
648 int position() const { return 0; } | 654 int position() const { return 0; } |
649 int length() const { return 0; } | 655 int length() const { return 0; } |
650 | 656 |
651 private: | 657 private: |
652 enum Type { | 658 enum Type { |
653 kUnknownIdentifier, | 659 kUnknownIdentifier, |
654 kFutureReservedIdentifier, | 660 kFutureReservedIdentifier, |
655 kFutureStrictReservedIdentifier, | 661 kFutureStrictReservedIdentifier, |
656 kLetIdentifier, | 662 kLetIdentifier, |
657 kYieldIdentifier, | 663 kYieldIdentifier, |
658 kEvalIdentifier, | 664 kEvalIdentifier, |
659 kArgumentsIdentifier, | 665 kArgumentsIdentifier, |
660 kPrototypeIdentifier, | 666 kPrototypeIdentifier, |
661 kConstructorIdentifier | 667 kConstructorIdentifier |
662 }; | 668 }; |
663 explicit PreParserIdentifier(Type type) : type_(type) {} | 669 explicit PreParserIdentifier(Type type) : type_(type) {} |
664 Type type_; | 670 Type type_; |
665 | 671 |
666 friend class PreParserExpression; | 672 friend class PreParserExpression; |
667 friend class PreParserScope; | 673 friend class PreParserScope; |
668 }; | 674 }; |
669 | 675 |
670 | 676 |
671 // Bits 0 and 1 are used to identify the type of expression: | |
672 // If bit 0 is set, it's an identifier. | |
673 // if bit 1 is set, it's a string literal. | |
674 // If neither is set, it's no particular type, and both set isn't | |
675 // use yet. | |
676 class PreParserExpression { | 677 class PreParserExpression { |
677 public: | 678 public: |
678 static PreParserExpression Default() { | 679 static PreParserExpression Default() { |
679 return PreParserExpression(kUnknownExpression); | 680 return PreParserExpression(TypeField::encode(kExpression)); |
680 } | 681 } |
681 | 682 |
682 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 683 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
683 return PreParserExpression(kTypeIdentifier | | 684 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
684 (id.type_ << kIdentifierShift)); | 685 IdentifierTypeField::encode(id.type_)); |
685 } | 686 } |
686 | 687 |
687 static PreParserExpression BinaryOperation(PreParserExpression left, | 688 static PreParserExpression BinaryOperation(PreParserExpression left, |
688 Token::Value op, | 689 Token::Value op, |
689 PreParserExpression right) { | 690 PreParserExpression right) { |
690 int code = ((op == Token::COMMA) && !left.is_parenthesized() && | 691 bool valid_arrow_param_list = |
691 !right.is_parenthesized()) | 692 op == Token::COMMA && !left.is_parenthesized() && |
692 ? left.ArrowParamListBit() & right.ArrowParamListBit() | 693 !right.is_parenthesized() && left.IsValidArrowParams() && |
693 : 0; | 694 right.IsValidArrowParams(); |
694 return PreParserExpression(kTypeBinaryOperation | code); | 695 return PreParserExpression( |
696 TypeField::encode(kBinaryOperationExpression) | | |
697 IsValidArrowParamListField::encode(valid_arrow_param_list)); | |
695 } | 698 } |
696 | 699 |
697 static PreParserExpression EmptyArrowParamList() { | 700 static PreParserExpression EmptyArrowParamList() { |
698 // Any expression for which IsValidArrowParamList() returns true | 701 // Any expression for which IsValidArrowParamList() returns true |
699 // will work here. | 702 // will work here. |
700 return FromIdentifier(PreParserIdentifier::Default()); | 703 return FromIdentifier(PreParserIdentifier::Default()); |
701 } | 704 } |
702 | 705 |
703 static PreParserExpression StringLiteral() { | 706 static PreParserExpression StringLiteral() { |
704 return PreParserExpression(kUnknownStringLiteral); | 707 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
708 IsUseStrictField::encode(false)); | |
705 } | 709 } |
706 | 710 |
707 static PreParserExpression UseStrictStringLiteral() { | 711 static PreParserExpression UseStrictStringLiteral() { |
708 return PreParserExpression(kUseStrictString); | 712 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
713 IsUseStrictField::encode(true)); | |
709 } | 714 } |
710 | 715 |
711 static PreParserExpression This() { | 716 static PreParserExpression This() { |
712 return PreParserExpression(kThisExpression); | 717 return PreParserExpression(TypeField::encode(kExpression) | |
718 ExpressionTypeField::encode(kThisExpression)); | |
713 } | 719 } |
714 | 720 |
715 static PreParserExpression Super() { | 721 static PreParserExpression Super() { |
716 return PreParserExpression(kSuperExpression); | 722 return PreParserExpression(TypeField::encode(kExpression) | |
723 ExpressionTypeField::encode(kSuperExpression)); | |
717 } | 724 } |
718 | 725 |
719 static PreParserExpression ThisProperty() { | 726 static PreParserExpression ThisProperty() { |
720 return PreParserExpression(kThisPropertyExpression); | 727 return PreParserExpression( |
728 TypeField::encode(kExpression) | | |
729 ExpressionTypeField::encode(kThisPropertyExpression)); | |
721 } | 730 } |
722 | 731 |
723 static PreParserExpression Property() { | 732 static PreParserExpression Property() { |
724 return PreParserExpression(kPropertyExpression); | 733 return PreParserExpression( |
734 TypeField::encode(kExpression) | | |
735 ExpressionTypeField::encode(kPropertyExpression)); | |
725 } | 736 } |
726 | 737 |
727 static PreParserExpression Call() { | 738 static PreParserExpression Call() { |
728 return PreParserExpression(kCallExpression); | 739 return PreParserExpression(TypeField::encode(kExpression) | |
740 ExpressionTypeField::encode(kCallExpression)); | |
729 } | 741 } |
730 | 742 |
731 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } | 743 bool IsIdentifier() const { |
744 return TypeField::decode(code_) == kIdentifierExpression; | |
745 } | |
732 | 746 |
733 PreParserIdentifier AsIdentifier() const { | 747 PreParserIdentifier AsIdentifier() const { |
734 DCHECK(IsIdentifier()); | 748 DCHECK(IsIdentifier()); |
735 return PreParserIdentifier( | 749 return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
736 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | |
737 } | 750 } |
738 | 751 |
739 bool IsStringLiteral() const { | 752 bool IsStringLiteral() const { |
740 return (code_ & kTypeMask) == kTypeStringLiteral; | 753 return TypeField::decode(code_) == kStringLiteralExpression; |
741 } | 754 } |
742 | 755 |
743 bool IsUseStrictLiteral() const { | 756 bool IsUseStrictLiteral() const { |
744 return (code_ & kUseStrictString) == kUseStrictString; | 757 return TypeField::decode(code_) == kStringLiteralExpression && |
758 IsUseStrictField::decode(code_); | |
745 } | 759 } |
746 | 760 |
747 bool IsThis() const { return (code_ & kThisExpression) == kThisExpression; } | 761 bool IsThis() const { |
762 return TypeField::decode(code_) == kExpression && | |
763 ExpressionTypeField::decode(code_) == kThisExpression; | |
764 } | |
748 | 765 |
749 bool IsThisProperty() const { | 766 bool IsThisProperty() const { |
750 return (code_ & kThisPropertyExpression) == kThisPropertyExpression; | 767 return TypeField::decode(code_) == kExpression && |
768 ExpressionTypeField::decode(code_) == kThisPropertyExpression; | |
751 } | 769 } |
752 | 770 |
753 bool IsProperty() const { | 771 bool IsProperty() const { |
754 return (code_ & kPropertyExpression) == kPropertyExpression || | 772 return TypeField::decode(code_) == kExpression && |
755 (code_ & kThisPropertyExpression) == kThisPropertyExpression; | 773 (ExpressionTypeField::decode(code_) == kPropertyExpression || |
774 ExpressionTypeField::decode(code_) == kThisPropertyExpression); | |
756 } | 775 } |
757 | 776 |
758 bool IsCall() const { return (code_ & kCallExpression) == kCallExpression; } | 777 bool IsCall() const { |
778 return TypeField::decode(code_) == kExpression && | |
779 ExpressionTypeField::decode(code_) == kCallExpression; | |
780 } | |
759 | 781 |
760 bool IsValidReferenceExpression() const { | 782 bool IsValidReferenceExpression() const { |
761 return IsIdentifier() || IsProperty(); | 783 return IsIdentifier() || IsProperty(); |
762 } | 784 } |
763 | 785 |
764 bool IsValidArrowParamList() const { | 786 bool IsValidArrowParamList() const { |
765 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && | 787 return IsValidArrowParams() && |
766 (code_ & kMultiParenthesizedExpression) == 0; | 788 ParenthesizationField::decode(code_) != |
789 kMultiParenthesizedExpression; | |
767 } | 790 } |
768 | 791 |
769 // At the moment PreParser doesn't track these expression types. | 792 // At the moment PreParser doesn't track these expression types. |
770 bool IsFunctionLiteral() const { return false; } | 793 bool IsFunctionLiteral() const { return false; } |
771 bool IsCallNew() const { return false; } | 794 bool IsCallNew() const { return false; } |
772 | 795 |
773 PreParserExpression AsFunctionLiteral() { return *this; } | 796 PreParserExpression AsFunctionLiteral() { return *this; } |
774 | 797 |
775 bool IsBinaryOperation() const { | 798 bool IsBinaryOperation() const { |
776 return (code_ & kTypeMask) == kTypeBinaryOperation; | 799 return TypeField::decode(code_) == kBinaryOperationExpression; |
777 } | 800 } |
778 | 801 |
779 bool is_parenthesized() const { | 802 bool is_parenthesized() const { |
780 return (code_ & kParenthesizedExpression) != 0; | 803 return ParenthesizationField::decode(code_) != kNotParenthesized; |
781 } | 804 } |
782 | 805 |
783 void increase_parenthesization_level() { | 806 void increase_parenthesization_level() { |
784 code_ |= is_parenthesized() ? kMultiParenthesizedExpression | 807 code_ = ParenthesizationField::update( |
785 : kParenthesizedExpression; | 808 code_, is_parenthesized() ? kMultiParenthesizedExpression |
809 : kParanthesizedExpression); | |
786 } | 810 } |
787 | 811 |
788 // Dummy implementation for making expression->somefunc() work in both Parser | 812 // Dummy implementation for making expression->somefunc() work in both Parser |
789 // and PreParser. | 813 // and PreParser. |
790 PreParserExpression* operator->() { return this; } | 814 PreParserExpression* operator->() { return this; } |
791 | 815 |
792 // More dummy implementations of things PreParser doesn't need to track: | 816 // More dummy implementations of things PreParser doesn't need to track: |
793 void set_index(int index) {} // For YieldExpressions | 817 void set_index(int index) {} // For YieldExpressions |
794 void set_parenthesized() {} | 818 void set_parenthesized() {} |
795 | 819 |
796 int position() const { return RelocInfo::kNoPosition; } | 820 int position() const { return RelocInfo::kNoPosition; } |
797 void set_function_token_position(int position) {} | 821 void set_function_token_position(int position) {} |
798 void set_ast_properties(int* ast_properties) {} | 822 void set_ast_properties(int* ast_properties) {} |
799 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | 823 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
800 | 824 |
801 bool operator==(const PreParserExpression& other) const { | 825 private: |
802 return code_ == other.code_; | 826 enum Type { |
marja
2015/03/10 08:45:40
Type and ExpressionType both??? What's up with tha
| |
803 } | 827 kExpression, |
804 bool operator!=(const PreParserExpression& other) const { | 828 kIdentifierExpression, |
805 return code_ != other.code_; | 829 kStringLiteralExpression, |
830 kBinaryOperationExpression | |
831 }; | |
832 | |
833 enum Parenthesization { | |
834 kNotParenthesized, | |
835 kParanthesizedExpression, | |
836 kMultiParenthesizedExpression | |
837 }; | |
838 | |
839 enum ExpressionType { | |
840 kThisExpression, | |
841 kThisPropertyExpression, | |
842 kPropertyExpression, | |
843 kCallExpression, | |
844 kSuperExpression | |
845 }; | |
846 | |
847 explicit PreParserExpression(uint32_t expression_code) | |
848 : code_(expression_code) {} | |
849 | |
850 V8_INLINE bool IsValidArrowParams() const { | |
851 return IsBinaryOperation() | |
852 ? IsValidArrowParamListField::decode(code_) | |
853 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | |
806 } | 854 } |
807 | 855 |
808 private: | 856 // The first four bits are for the Type and Parenthesization. |
809 // Least significant 2 bits are used as expression type. The third least | 857 typedef BitField<Type, 0, 2> TypeField; |
810 // significant bit tracks whether an expression is parenthesized. If the | 858 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
811 // expression is an identifier or a string literal, the other bits | |
812 // describe the type/ (see PreParserIdentifier::Type and string literal | |
813 // constants below). For binary operations, the other bits are flags | |
814 // which further describe the contents of the expression. | |
815 enum { | |
816 kUnknownExpression = 0, | |
817 kTypeMask = 1 | 2, | |
818 kParenthesizedExpression = (1 << 2), | |
819 kMultiParenthesizedExpression = (1 << 3), | |
820 | 859 |
821 // Identifiers | 860 // The rest of the bits are interpreted depending on the value |
822 kTypeIdentifier = 1, // Used to detect labels. | 861 // of the Type field, so they can share the storage. |
823 kIdentifierShift = 5, | 862 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
824 kTypeStringLiteral = 2, // Used to detect directive prologue. | 863 ExpressionTypeField; |
825 kUnknownStringLiteral = kTypeStringLiteral, | 864 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
826 kUseStrictString = kTypeStringLiteral | 32, | 865 typedef BitField<bool, ParenthesizationField::kNext, 1> |
827 kStringLiteralMask = kUseStrictString, | 866 IsValidArrowParamListField; |
867 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | |
868 IdentifierTypeField; | |
828 | 869 |
829 // Binary operations. Those are needed to detect certain keywords and | 870 uint32_t code_; |
830 // duplicated identifier in parameter lists for arrow functions, because | |
831 // they are initially parsed as comma-separated expressions. | |
832 kTypeBinaryOperation = 3, | |
833 kBinaryOperationArrowParamList = (1 << 4), | |
834 | |
835 // Below here applies if neither identifier nor string literal. Reserve the | |
836 // 2 least significant bits for flags. | |
837 kThisExpression = (1 << 4), | |
838 kThisPropertyExpression = (2 << 4), | |
839 kPropertyExpression = (3 << 4), | |
840 kCallExpression = (4 << 4), | |
841 kSuperExpression = (5 << 4) | |
842 }; | |
843 | |
844 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | |
845 | |
846 V8_INLINE int ArrowParamListBit() const { | |
847 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; | |
848 if (IsIdentifier()) { | |
849 const PreParserIdentifier ident = AsIdentifier(); | |
850 // A valid identifier can be an arrow function parameter list | |
851 // except for eval, arguments, yield, and reserved keywords. | |
852 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || | |
853 ident.IsFutureStrictReserved()) | |
854 return 0; | |
855 return kBinaryOperationArrowParamList; | |
856 } | |
857 return 0; | |
858 } | |
859 | |
860 int code_; | |
861 }; | 871 }; |
862 | 872 |
863 | 873 |
864 // PreParserExpressionList doesn't actually store the expressions because | 874 // PreParserExpressionList doesn't actually store the expressions because |
865 // PreParser doesn't need to. | 875 // PreParser doesn't need to. |
866 class PreParserExpressionList { | 876 class PreParserExpressionList { |
867 public: | 877 public: |
868 // These functions make list->Add(some_expression) work (and do nothing). | 878 // These functions make list->Add(some_expression) work (and do nothing). |
869 PreParserExpressionList() : length_(0) {} | 879 PreParserExpressionList() : length_(0) {} |
870 PreParserExpressionList* operator->() { return this; } | 880 PreParserExpressionList* operator->() { return this; } |
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2835 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2845 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2836 // Both accessors of the same type. | 2846 // Both accessors of the same type. |
2837 parser()->ReportMessage("accessor_get_set"); | 2847 parser()->ReportMessage("accessor_get_set"); |
2838 } | 2848 } |
2839 *ok = false; | 2849 *ok = false; |
2840 } | 2850 } |
2841 } | 2851 } |
2842 } } // v8::internal | 2852 } } // v8::internal |
2843 | 2853 |
2844 #endif // V8_PREPARSER_H | 2854 #endif // V8_PREPARSER_H |
OLD | NEW |