OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 // Represents the location of one element relative to the intersection of | 218 // Represents the location of one element relative to the intersection of |
219 // two sets. Corresponds to the four areas of a Venn diagram. | 219 // two sets. Corresponds to the four areas of a Venn diagram. |
220 enum ElementInSetsRelation { | 220 enum ElementInSetsRelation { |
221 kInsideNone = 0, | 221 kInsideNone = 0, |
222 kInsideFirst = 1, | 222 kInsideFirst = 1, |
223 kInsideSecond = 2, | 223 kInsideSecond = 2, |
224 kInsideBoth = 3 | 224 kInsideBoth = 3 |
225 }; | 225 }; |
226 | 226 |
227 | 227 |
228 // Represents code units in the range from from_ to to_, both ends are | |
229 // inclusive. | |
228 class CharacterRange { | 230 class CharacterRange { |
229 public: | 231 public: |
230 CharacterRange() : from_(0), to_(0) { } | 232 CharacterRange() : from_(0), to_(0) { } |
231 // For compatibility with the CHECK_OK macro | 233 // For compatibility with the CHECK_OK macro |
232 CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT | 234 CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT |
233 CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { } | 235 CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { } |
234 static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges); | 236 static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges); |
235 static Vector<const int> GetWordBounds(); | 237 static Vector<const int> GetWordBounds(); |
236 static inline CharacterRange Singleton(uc16 value) { | 238 static inline CharacterRange Singleton(uc16 value) { |
237 return CharacterRange(value, value); | 239 return CharacterRange(value, value); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
512 Position positions_[4]; | 514 Position positions_[4]; |
513 // These values are the condensate of the above array after Rationalize(). | 515 // These values are the condensate of the above array after Rationalize(). |
514 uint32_t mask_; | 516 uint32_t mask_; |
515 uint32_t value_; | 517 uint32_t value_; |
516 // If set to true, there is no way this quick check can match at all. | 518 // If set to true, there is no way this quick check can match at all. |
517 // E.g., if it requires to be at the start of the input, and isn't. | 519 // E.g., if it requires to be at the start of the input, and isn't. |
518 bool cannot_match_; | 520 bool cannot_match_; |
519 }; | 521 }; |
520 | 522 |
521 | 523 |
524 extern int kUninitializedRegExpNodePlaceHolder; | |
525 | |
526 | |
522 class RegExpNode: public ZoneObject { | 527 class RegExpNode: public ZoneObject { |
523 public: | 528 public: |
524 RegExpNode() : trace_count_(0) { | 529 RegExpNode() : replacement_(Uninitialized()), trace_count_(0) { |
525 bm_info_[0] = bm_info_[1] = NULL; | 530 bm_info_[0] = bm_info_[1] = NULL; |
526 } | 531 } |
527 virtual ~RegExpNode(); | 532 virtual ~RegExpNode(); |
528 virtual void Accept(NodeVisitor* visitor) = 0; | 533 virtual void Accept(NodeVisitor* visitor) = 0; |
529 // Generates a goto to this node or actually generates the code at this point. | 534 // Generates a goto to this node or actually generates the code at this point. |
530 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; | 535 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; |
531 // How many characters must this node consume at a minimum in order to | 536 // How many characters must this node consume at a minimum in order to |
532 // succeed. If we have found at least 'still_to_find' characters that | 537 // succeed. If we have found at least 'still_to_find' characters that |
533 // must be consumed there is no need to ask any following nodes whether | 538 // must be consumed there is no need to ask any following nodes whether |
534 // they are sure to eat any more characters. The not_at_start argument is | 539 // they are sure to eat any more characters. The not_at_start argument is |
(...skipping 30 matching lines...) Expand all Loading... | |
565 } | 570 } |
566 | 571 |
567 // Collects information on the possible code units (mod 128) that can match if | 572 // Collects information on the possible code units (mod 128) that can match if |
568 // we look forward. This is used for a Boyer-Moore-like string searching | 573 // we look forward. This is used for a Boyer-Moore-like string searching |
569 // implementation. TODO(erikcorry): This should share more code with | 574 // implementation. TODO(erikcorry): This should share more code with |
570 // EatsAtLeast, GetQuickCheckDetails. | 575 // EatsAtLeast, GetQuickCheckDetails. |
571 virtual void FillInBMInfo( | 576 virtual void FillInBMInfo( |
572 int offset, BoyerMooreLookahead* bm, bool not_at_start) { | 577 int offset, BoyerMooreLookahead* bm, bool not_at_start) { |
573 UNREACHABLE(); | 578 UNREACHABLE(); |
574 } | 579 } |
580 | |
581 // If we know that the input is ASCII then there are some nodes that can | |
582 // never match. This method returns returns a node that can be substituted | |
ulan
2012/04/25 12:55:28
double "returns"
Erik Corry
2012/04/26 08:23:11
done done
| |
583 // for itself, or NULL if the node can never match. | |
584 virtual RegExpNode* FilterASCII(int depth) { return this; } | |
585 // Helper for FilterASCII. | |
586 RegExpNode* Uninitialized() { | |
ulan
2012/04/25 12:55:28
If it doesn't make big difference in speed/space t
Erik Corry
2012/04/26 08:23:11
Done.
| |
587 return reinterpret_cast<RegExpNode*>(&kUninitializedRegExpNodePlaceHolder); | |
588 } | |
589 | |
575 // We want to avoid recalculating the lookahead info, so we store it on the | 590 // We want to avoid recalculating the lookahead info, so we store it on the |
576 // node. Only info that is for this node is stored. We can tell that the | 591 // node. Only info that is for this node is stored. We can tell that the |
577 // info is for this node when offset == 0, so the information is calculated | 592 // info is for this node when offset == 0, so the information is calculated |
578 // relative to this node. | 593 // relative to this node. |
579 void SaveBMInfo(BoyerMooreLookahead* bm, bool not_at_start, int offset) { | 594 void SaveBMInfo(BoyerMooreLookahead* bm, bool not_at_start, int offset) { |
580 if (offset == 0) set_bm_info(not_at_start, bm); | 595 if (offset == 0) set_bm_info(not_at_start, bm); |
581 } | 596 } |
582 | 597 |
583 Label* label() { return &label_; } | 598 Label* label() { return &label_; } |
584 // If non-generic code is generated for a node (i.e. the node is not at the | 599 // If non-generic code is generated for a node (i.e. the node is not at the |
585 // start of the trace) then it cannot be reused. This variable sets a limit | 600 // start of the trace) then it cannot be reused. This variable sets a limit |
586 // on how often we allow that to happen before we insist on starting a new | 601 // on how often we allow that to happen before we insist on starting a new |
587 // trace and generating generic code for a node that can be reused by flushing | 602 // trace and generating generic code for a node that can be reused by flushing |
588 // the deferred actions in the current trace and generating a goto. | 603 // the deferred actions in the current trace and generating a goto. |
589 static const int kMaxCopiesCodeGenerated = 10; | 604 static const int kMaxCopiesCodeGenerated = 10; |
590 | 605 |
591 NodeInfo* info() { return &info_; } | 606 NodeInfo* info() { return &info_; } |
592 | 607 |
593 BoyerMooreLookahead* bm_info(bool not_at_start) { | 608 BoyerMooreLookahead* bm_info(bool not_at_start) { |
594 return bm_info_[not_at_start ? 1 : 0]; | 609 return bm_info_[not_at_start ? 1 : 0]; |
595 } | 610 } |
596 | 611 |
597 protected: | 612 protected: |
598 enum LimitResult { DONE, CONTINUE }; | 613 enum LimitResult { DONE, CONTINUE }; |
614 RegExpNode* replacement_; | |
599 | 615 |
600 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); | 616 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); |
601 | 617 |
602 // Returns a clone of this node initialized using the copy constructor | |
603 // of its concrete class. Note that the node may have to be pre- | |
604 // processed before it is on a usable state. | |
605 virtual RegExpNode* Clone() = 0; | |
606 | |
607 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { | 618 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { |
608 bm_info_[not_at_start ? 1 : 0] = bm; | 619 bm_info_[not_at_start ? 1 : 0] = bm; |
609 } | 620 } |
610 | 621 |
611 private: | 622 private: |
612 static const int kFirstCharBudget = 10; | 623 static const int kFirstCharBudget = 10; |
613 Label label_; | 624 Label label_; |
614 NodeInfo info_; | 625 NodeInfo info_; |
615 // This variable keeps track of how many times code has been generated for | 626 // This variable keeps track of how many times code has been generated for |
616 // this node (in different traces). We don't keep track of where the | 627 // this node (in different traces). We don't keep track of where the |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 int to_; | 659 int to_; |
649 }; | 660 }; |
650 | 661 |
651 | 662 |
652 class SeqRegExpNode: public RegExpNode { | 663 class SeqRegExpNode: public RegExpNode { |
653 public: | 664 public: |
654 explicit SeqRegExpNode(RegExpNode* on_success) | 665 explicit SeqRegExpNode(RegExpNode* on_success) |
655 : on_success_(on_success) { } | 666 : on_success_(on_success) { } |
656 RegExpNode* on_success() { return on_success_; } | 667 RegExpNode* on_success() { return on_success_; } |
657 void set_on_success(RegExpNode* node) { on_success_ = node; } | 668 void set_on_success(RegExpNode* node) { on_success_ = node; } |
669 virtual RegExpNode* FilterASCII(int depth); | |
658 virtual void FillInBMInfo( | 670 virtual void FillInBMInfo( |
659 int offset, BoyerMooreLookahead* bm, bool not_at_start) { | 671 int offset, BoyerMooreLookahead* bm, bool not_at_start) { |
660 on_success_->FillInBMInfo(offset, bm, not_at_start); | 672 on_success_->FillInBMInfo(offset, bm, not_at_start); |
661 if (offset == 0) set_bm_info(not_at_start, bm); | 673 if (offset == 0) set_bm_info(not_at_start, bm); |
662 } | 674 } |
675 | |
676 protected: | |
677 RegExpNode* FilterSuccessor(int depth); | |
678 | |
663 private: | 679 private: |
664 RegExpNode* on_success_; | 680 RegExpNode* on_success_; |
665 }; | 681 }; |
666 | 682 |
667 | 683 |
668 class ActionNode: public SeqRegExpNode { | 684 class ActionNode: public SeqRegExpNode { |
669 public: | 685 public: |
670 enum Type { | 686 enum Type { |
671 SET_REGISTER, | 687 SET_REGISTER, |
672 INCREMENT_REGISTER, | 688 INCREMENT_REGISTER, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
704 int filled_in, | 720 int filled_in, |
705 bool not_at_start) { | 721 bool not_at_start) { |
706 return on_success()->GetQuickCheckDetails( | 722 return on_success()->GetQuickCheckDetails( |
707 details, compiler, filled_in, not_at_start); | 723 details, compiler, filled_in, not_at_start); |
708 } | 724 } |
709 virtual void FillInBMInfo( | 725 virtual void FillInBMInfo( |
710 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 726 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
711 Type type() { return type_; } | 727 Type type() { return type_; } |
712 // TODO(erikcorry): We should allow some action nodes in greedy loops. | 728 // TODO(erikcorry): We should allow some action nodes in greedy loops. |
713 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } | 729 virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } |
714 virtual ActionNode* Clone() { return new ActionNode(*this); } | |
715 | 730 |
716 private: | 731 private: |
717 union { | 732 union { |
718 struct { | 733 struct { |
719 int reg; | 734 int reg; |
720 int value; | 735 int value; |
721 } u_store_register; | 736 } u_store_register; |
722 struct { | 737 struct { |
723 int reg; | 738 int reg; |
724 } u_increment_register; | 739 } u_increment_register; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 RegExpCompiler* compiler, | 786 RegExpCompiler* compiler, |
772 int characters_filled_in, | 787 int characters_filled_in, |
773 bool not_at_start); | 788 bool not_at_start); |
774 ZoneList<TextElement>* elements() { return elms_; } | 789 ZoneList<TextElement>* elements() { return elms_; } |
775 void MakeCaseIndependent(bool is_ascii); | 790 void MakeCaseIndependent(bool is_ascii); |
776 virtual int GreedyLoopTextLength(); | 791 virtual int GreedyLoopTextLength(); |
777 virtual RegExpNode* GetSuccessorOfOmnivorousTextNode( | 792 virtual RegExpNode* GetSuccessorOfOmnivorousTextNode( |
778 RegExpCompiler* compiler); | 793 RegExpCompiler* compiler); |
779 virtual void FillInBMInfo( | 794 virtual void FillInBMInfo( |
780 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 795 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
781 virtual TextNode* Clone() { | |
782 TextNode* result = new TextNode(*this); | |
783 result->CalculateOffsets(); | |
784 return result; | |
785 } | |
786 void CalculateOffsets(); | 796 void CalculateOffsets(); |
797 virtual RegExpNode* FilterASCII(int depth); | |
787 | 798 |
788 private: | 799 private: |
789 enum TextEmitPassType { | 800 enum TextEmitPassType { |
790 NON_ASCII_MATCH, // Check for characters that can't match. | 801 NON_ASCII_MATCH, // Check for characters that can't match. |
791 SIMPLE_CHARACTER_MATCH, // Case-dependent single character check. | 802 SIMPLE_CHARACTER_MATCH, // Case-dependent single character check. |
792 NON_LETTER_CHARACTER_MATCH, // Check characters that have no case equivs. | 803 NON_LETTER_CHARACTER_MATCH, // Check characters that have no case equivs. |
793 CASE_CHARACTER_MATCH, // Case-independent single character check. | 804 CASE_CHARACTER_MATCH, // Case-independent single character check. |
794 CHARACTER_CLASS_MATCH // Character class. | 805 CHARACTER_CLASS_MATCH // Character class. |
795 }; | 806 }; |
796 static bool SkipPass(int pass, bool ignore_case); | 807 static bool SkipPass(int pass, bool ignore_case); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
835 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 846 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
836 virtual int EatsAtLeast(int still_to_find, | 847 virtual int EatsAtLeast(int still_to_find, |
837 int recursion_depth, | 848 int recursion_depth, |
838 bool not_at_start); | 849 bool not_at_start); |
839 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 850 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
840 RegExpCompiler* compiler, | 851 RegExpCompiler* compiler, |
841 int filled_in, | 852 int filled_in, |
842 bool not_at_start); | 853 bool not_at_start); |
843 virtual void FillInBMInfo( | 854 virtual void FillInBMInfo( |
844 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 855 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
845 virtual AssertionNode* Clone() { return new AssertionNode(*this); } | |
846 AssertionNodeType type() { return type_; } | 856 AssertionNodeType type() { return type_; } |
847 void set_type(AssertionNodeType type) { type_ = type; } | 857 void set_type(AssertionNodeType type) { type_ = type; } |
848 | 858 |
849 private: | 859 private: |
850 void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace); | 860 void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace); |
851 enum IfPrevious { kIsNonWord, kIsWord }; | 861 enum IfPrevious { kIsNonWord, kIsWord }; |
852 void BacktrackIfPrevious(RegExpCompiler* compiler, | 862 void BacktrackIfPrevious(RegExpCompiler* compiler, |
853 Trace* trace, | 863 Trace* trace, |
854 IfPrevious backtrack_if_previous); | 864 IfPrevious backtrack_if_previous); |
855 AssertionNode(AssertionNodeType t, RegExpNode* on_success) | 865 AssertionNode(AssertionNodeType t, RegExpNode* on_success) |
(...skipping 18 matching lines...) Expand all Loading... | |
874 int recursion_depth, | 884 int recursion_depth, |
875 bool not_at_start); | 885 bool not_at_start); |
876 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 886 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
877 RegExpCompiler* compiler, | 887 RegExpCompiler* compiler, |
878 int characters_filled_in, | 888 int characters_filled_in, |
879 bool not_at_start) { | 889 bool not_at_start) { |
880 return; | 890 return; |
881 } | 891 } |
882 virtual void FillInBMInfo( | 892 virtual void FillInBMInfo( |
883 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 893 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
884 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } | |
885 | 894 |
886 private: | 895 private: |
887 int start_reg_; | 896 int start_reg_; |
888 int end_reg_; | 897 int end_reg_; |
889 }; | 898 }; |
890 | 899 |
891 | 900 |
892 class EndNode: public RegExpNode { | 901 class EndNode: public RegExpNode { |
893 public: | 902 public: |
894 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; | 903 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; |
895 explicit EndNode(Action action) : action_(action) { } | 904 explicit EndNode(Action action) : action_(action) { } |
896 virtual void Accept(NodeVisitor* visitor); | 905 virtual void Accept(NodeVisitor* visitor); |
897 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 906 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
898 virtual int EatsAtLeast(int still_to_find, | 907 virtual int EatsAtLeast(int still_to_find, |
899 int recursion_depth, | 908 int recursion_depth, |
900 bool not_at_start) { return 0; } | 909 bool not_at_start) { return 0; } |
901 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 910 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
902 RegExpCompiler* compiler, | 911 RegExpCompiler* compiler, |
903 int characters_filled_in, | 912 int characters_filled_in, |
904 bool not_at_start) { | 913 bool not_at_start) { |
905 // Returning 0 from EatsAtLeast should ensure we never get here. | 914 // Returning 0 from EatsAtLeast should ensure we never get here. |
906 UNREACHABLE(); | 915 UNREACHABLE(); |
907 } | 916 } |
908 virtual void FillInBMInfo( | 917 virtual void FillInBMInfo( |
909 int offset, BoyerMooreLookahead* bm, bool not_at_start) { | 918 int offset, BoyerMooreLookahead* bm, bool not_at_start) { |
910 // Returning 0 from EatsAtLeast should ensure we never get here. | 919 // Returning 0 from EatsAtLeast should ensure we never get here. |
911 UNREACHABLE(); | 920 UNREACHABLE(); |
912 } | 921 } |
913 virtual EndNode* Clone() { return new EndNode(*this); } | 922 |
914 private: | 923 private: |
915 Action action_; | 924 Action action_; |
916 }; | 925 }; |
917 | 926 |
918 | 927 |
919 class NegativeSubmatchSuccess: public EndNode { | 928 class NegativeSubmatchSuccess: public EndNode { |
920 public: | 929 public: |
921 NegativeSubmatchSuccess(int stack_pointer_reg, | 930 NegativeSubmatchSuccess(int stack_pointer_reg, |
922 int position_reg, | 931 int position_reg, |
923 int clear_capture_count, | 932 int clear_capture_count, |
(...skipping 27 matching lines...) Expand all Loading... | |
951 private: | 960 private: |
952 int reg_; | 961 int reg_; |
953 Relation op_; | 962 Relation op_; |
954 int value_; | 963 int value_; |
955 }; | 964 }; |
956 | 965 |
957 | 966 |
958 class GuardedAlternative { | 967 class GuardedAlternative { |
959 public: | 968 public: |
960 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } | 969 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } |
970 GuardedAlternative(RegExpNode* node, ZoneList<Guard*>* guards) | |
ulan
2012/04/25 12:55:28
This seems to be unused.
Erik Corry
2012/04/26 08:23:11
Done.
| |
971 : node_(node), guards_(guards) { } | |
961 void AddGuard(Guard* guard); | 972 void AddGuard(Guard* guard); |
962 RegExpNode* node() { return node_; } | 973 RegExpNode* node() { return node_; } |
963 void set_node(RegExpNode* node) { node_ = node; } | 974 void set_node(RegExpNode* node) { node_ = node; } |
964 ZoneList<Guard*>* guards() { return guards_; } | 975 ZoneList<Guard*>* guards() { return guards_; } |
965 | 976 |
966 private: | 977 private: |
967 RegExpNode* node_; | 978 RegExpNode* node_; |
968 ZoneList<Guard*>* guards_; | 979 ZoneList<Guard*>* guards_; |
969 }; | 980 }; |
970 | 981 |
(...skipping 19 matching lines...) Expand all Loading... | |
990 int EatsAtLeastHelper(int still_to_find, | 1001 int EatsAtLeastHelper(int still_to_find, |
991 int recursion_depth, | 1002 int recursion_depth, |
992 RegExpNode* ignore_this_node, | 1003 RegExpNode* ignore_this_node, |
993 bool not_at_start); | 1004 bool not_at_start); |
994 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1005 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
995 RegExpCompiler* compiler, | 1006 RegExpCompiler* compiler, |
996 int characters_filled_in, | 1007 int characters_filled_in, |
997 bool not_at_start); | 1008 bool not_at_start); |
998 virtual void FillInBMInfo( | 1009 virtual void FillInBMInfo( |
999 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 1010 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
1000 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); } | |
1001 | 1011 |
1002 bool being_calculated() { return being_calculated_; } | 1012 bool being_calculated() { return being_calculated_; } |
1003 bool not_at_start() { return not_at_start_; } | 1013 bool not_at_start() { return not_at_start_; } |
1004 void set_not_at_start() { not_at_start_ = true; } | 1014 void set_not_at_start() { not_at_start_ = true; } |
1005 void set_being_calculated(bool b) { being_calculated_ = b; } | 1015 void set_being_calculated(bool b) { being_calculated_ = b; } |
1006 virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; } | 1016 virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; } |
1017 virtual RegExpNode* FilterASCII(int depth); | |
1007 | 1018 |
1008 protected: | 1019 protected: |
1009 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); | 1020 int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); |
1010 ZoneList<GuardedAlternative>* alternatives_; | 1021 ZoneList<GuardedAlternative>* alternatives_; |
1011 | 1022 |
1012 private: | 1023 private: |
1013 friend class DispatchTableConstructor; | 1024 friend class DispatchTableConstructor; |
1014 friend class Analysis; | 1025 friend class Analysis; |
1015 void GenerateGuard(RegExpMacroAssembler* macro_assembler, | 1026 void GenerateGuard(RegExpMacroAssembler* macro_assembler, |
1016 Guard* guard, | 1027 Guard* guard, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 int offset, BoyerMooreLookahead* bm, bool not_at_start) { | 1060 int offset, BoyerMooreLookahead* bm, bool not_at_start) { |
1050 alternatives_->at(1).node()->FillInBMInfo(offset, bm, not_at_start); | 1061 alternatives_->at(1).node()->FillInBMInfo(offset, bm, not_at_start); |
1051 if (offset == 0) set_bm_info(not_at_start, bm); | 1062 if (offset == 0) set_bm_info(not_at_start, bm); |
1052 } | 1063 } |
1053 // For a negative lookahead we don't emit the quick check for the | 1064 // For a negative lookahead we don't emit the quick check for the |
1054 // alternative that is expected to fail. This is because quick check code | 1065 // alternative that is expected to fail. This is because quick check code |
1055 // starts by loading enough characters for the alternative that takes fewest | 1066 // starts by loading enough characters for the alternative that takes fewest |
1056 // characters, but on a negative lookahead the negative branch did not take | 1067 // characters, but on a negative lookahead the negative branch did not take |
1057 // part in that calculation (EatsAtLeast) so the assumptions don't hold. | 1068 // part in that calculation (EatsAtLeast) so the assumptions don't hold. |
1058 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } | 1069 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } |
1070 virtual RegExpNode* FilterASCII(int depth); | |
1059 }; | 1071 }; |
1060 | 1072 |
1061 | 1073 |
1062 class LoopChoiceNode: public ChoiceNode { | 1074 class LoopChoiceNode: public ChoiceNode { |
1063 public: | 1075 public: |
1064 explicit LoopChoiceNode(bool body_can_be_zero_length) | 1076 explicit LoopChoiceNode(bool body_can_be_zero_length) |
1065 : ChoiceNode(2), | 1077 : ChoiceNode(2), |
1066 loop_node_(NULL), | 1078 loop_node_(NULL), |
1067 continue_node_(NULL), | 1079 continue_node_(NULL), |
1068 body_can_be_zero_length_(body_can_be_zero_length) { } | 1080 body_can_be_zero_length_(body_can_be_zero_length) { } |
1069 void AddLoopAlternative(GuardedAlternative alt); | 1081 void AddLoopAlternative(GuardedAlternative alt); |
1070 void AddContinueAlternative(GuardedAlternative alt); | 1082 void AddContinueAlternative(GuardedAlternative alt); |
1071 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1083 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
1072 virtual int EatsAtLeast(int still_to_find, | 1084 virtual int EatsAtLeast(int still_to_find, |
1073 int recursion_depth, | 1085 int recursion_depth, |
1074 bool not_at_start); | 1086 bool not_at_start); |
1075 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1087 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
1076 RegExpCompiler* compiler, | 1088 RegExpCompiler* compiler, |
1077 int characters_filled_in, | 1089 int characters_filled_in, |
1078 bool not_at_start); | 1090 bool not_at_start); |
1079 virtual void FillInBMInfo( | 1091 virtual void FillInBMInfo( |
1080 int offset, BoyerMooreLookahead* bm, bool not_at_start); | 1092 int offset, BoyerMooreLookahead* bm, bool not_at_start); |
1081 virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); } | |
1082 RegExpNode* loop_node() { return loop_node_; } | 1093 RegExpNode* loop_node() { return loop_node_; } |
1083 RegExpNode* continue_node() { return continue_node_; } | 1094 RegExpNode* continue_node() { return continue_node_; } |
1084 bool body_can_be_zero_length() { return body_can_be_zero_length_; } | 1095 bool body_can_be_zero_length() { return body_can_be_zero_length_; } |
1085 virtual void Accept(NodeVisitor* visitor); | 1096 virtual void Accept(NodeVisitor* visitor); |
1097 virtual RegExpNode* FilterASCII(int depth); | |
1086 | 1098 |
1087 private: | 1099 private: |
1088 // AddAlternative is made private for loop nodes because alternatives | 1100 // AddAlternative is made private for loop nodes because alternatives |
1089 // should not be added freely, we need to keep track of which node | 1101 // should not be added freely, we need to keep track of which node |
1090 // goes back to the node itself. | 1102 // goes back to the node itself. |
1091 void AddAlternative(GuardedAlternative node) { | 1103 void AddAlternative(GuardedAlternative node) { |
1092 ChoiceNode::AddAlternative(node); | 1104 ChoiceNode::AddAlternative(node); |
1093 } | 1105 } |
1094 | 1106 |
1095 RegExpNode* loop_node_; | 1107 RegExpNode* loop_node_; |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1565 int* vector_; | 1577 int* vector_; |
1566 int offsets_vector_length_; | 1578 int offsets_vector_length_; |
1567 | 1579 |
1568 friend class ExternalReference; | 1580 friend class ExternalReference; |
1569 }; | 1581 }; |
1570 | 1582 |
1571 | 1583 |
1572 } } // namespace v8::internal | 1584 } } // namespace v8::internal |
1573 | 1585 |
1574 #endif // V8_JSREGEXP_H_ | 1586 #endif // V8_JSREGEXP_H_ |
OLD | NEW |