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

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 Created 6 years, 4 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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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