Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: src/preparser.h

Issue 422363002: Clean up manual bit field usage in PreParserExpression (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased against latest changes Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698