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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 |
OLD | NEW |