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

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: Alternative version using BitField Created 6 years, 3 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/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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