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