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

Side by Side Diff: src/jsregexp.h

Issue 10174017: Regexp: Remove nodes from the regexp that cannot match because (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 8 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 | src/jsregexp.cc » ('j') | src/jsregexp.cc » ('J')
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 // 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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | src/jsregexp.cc » ('j') | src/jsregexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698