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 60 matching lines...) Loading... |
71 // Returns false if compilation fails. | 71 // Returns false if compilation fails. |
72 static Handle<Object> Compile(Handle<JSRegExp> re, | 72 static Handle<Object> Compile(Handle<JSRegExp> re, |
73 Handle<String> pattern, | 73 Handle<String> pattern, |
74 Handle<String> flags); | 74 Handle<String> flags); |
75 | 75 |
76 // See ECMA-262 section 15.10.6.2. | 76 // See ECMA-262 section 15.10.6.2. |
77 // This function calls the garbage collector if necessary. | 77 // This function calls the garbage collector if necessary. |
78 static Handle<Object> Exec(Handle<JSRegExp> regexp, | 78 static Handle<Object> Exec(Handle<JSRegExp> regexp, |
79 Handle<String> subject, | 79 Handle<String> subject, |
80 int index, | 80 int index, |
81 Handle<JSArray> lastMatchInfo); | 81 Handle<JSArray> lastMatchInfo, |
| 82 Zone* zone); |
82 | 83 |
83 // Prepares a JSRegExp object with Irregexp-specific data. | 84 // Prepares a JSRegExp object with Irregexp-specific data. |
84 static void IrregexpInitialize(Handle<JSRegExp> re, | 85 static void IrregexpInitialize(Handle<JSRegExp> re, |
85 Handle<String> pattern, | 86 Handle<String> pattern, |
86 JSRegExp::Flags flags, | 87 JSRegExp::Flags flags, |
87 int capture_register_count); | 88 int capture_register_count); |
88 | 89 |
89 | 90 |
90 static void AtomCompile(Handle<JSRegExp> re, | 91 static void AtomCompile(Handle<JSRegExp> re, |
91 Handle<String> pattern, | 92 Handle<String> pattern, |
92 JSRegExp::Flags flags, | 93 JSRegExp::Flags flags, |
93 Handle<String> match_pattern); | 94 Handle<String> match_pattern); |
94 | 95 |
95 static Handle<Object> AtomExec(Handle<JSRegExp> regexp, | 96 static Handle<Object> AtomExec(Handle<JSRegExp> regexp, |
96 Handle<String> subject, | 97 Handle<String> subject, |
97 int index, | 98 int index, |
98 Handle<JSArray> lastMatchInfo); | 99 Handle<JSArray> lastMatchInfo); |
99 | 100 |
100 enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }; | 101 enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }; |
101 | 102 |
102 // Prepare a RegExp for being executed one or more times (using | 103 // Prepare a RegExp for being executed one or more times (using |
103 // IrregexpExecOnce) on the subject. | 104 // IrregexpExecOnce) on the subject. |
104 // This ensures that the regexp is compiled for the subject, and that | 105 // This ensures that the regexp is compiled for the subject, and that |
105 // the subject is flat. | 106 // the subject is flat. |
106 // Returns the number of integer spaces required by IrregexpExecOnce | 107 // Returns the number of integer spaces required by IrregexpExecOnce |
107 // as its "registers" argument. If the regexp cannot be compiled, | 108 // as its "registers" argument. If the regexp cannot be compiled, |
108 // an exception is set as pending, and this function returns negative. | 109 // an exception is set as pending, and this function returns negative. |
109 static int IrregexpPrepare(Handle<JSRegExp> regexp, | 110 static int IrregexpPrepare(Handle<JSRegExp> regexp, |
110 Handle<String> subject); | 111 Handle<String> subject, |
| 112 Zone* zone); |
111 | 113 |
112 // Calculate the size of offsets vector for the case of global regexp | 114 // Calculate the size of offsets vector for the case of global regexp |
113 // and the number of matches this vector is able to store. | 115 // and the number of matches this vector is able to store. |
114 static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, | 116 static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, |
115 int registers_per_match, | 117 int registers_per_match, |
116 int* max_matches); | 118 int* max_matches); |
117 | 119 |
118 // Execute a regular expression on the subject, starting from index. | 120 // Execute a regular expression on the subject, starting from index. |
119 // If matching succeeds, return the number of matches. This can be larger | 121 // If matching succeeds, return the number of matches. This can be larger |
120 // than one in the case of global regular expressions. | 122 // than one in the case of global regular expressions. |
121 // The captures and subcaptures are stored into the registers vector. | 123 // The captures and subcaptures are stored into the registers vector. |
122 // If matching fails, returns RE_FAILURE. | 124 // If matching fails, returns RE_FAILURE. |
123 // If execution fails, sets a pending exception and returns RE_EXCEPTION. | 125 // If execution fails, sets a pending exception and returns RE_EXCEPTION. |
124 static int IrregexpExecRaw(Handle<JSRegExp> regexp, | 126 static int IrregexpExecRaw(Handle<JSRegExp> regexp, |
125 Handle<String> subject, | 127 Handle<String> subject, |
126 int index, | 128 int index, |
127 Vector<int> registers); | 129 Vector<int> registers, |
| 130 Zone* zone); |
128 | 131 |
129 // Execute an Irregexp bytecode pattern. | 132 // Execute an Irregexp bytecode pattern. |
130 // On a successful match, the result is a JSArray containing | 133 // On a successful match, the result is a JSArray containing |
131 // captured positions. On a failure, the result is the null value. | 134 // captured positions. On a failure, the result is the null value. |
132 // Returns an empty handle in case of an exception. | 135 // Returns an empty handle in case of an exception. |
133 static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp, | 136 static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp, |
134 Handle<String> subject, | 137 Handle<String> subject, |
135 int index, | 138 int index, |
136 Handle<JSArray> lastMatchInfo); | 139 Handle<JSArray> lastMatchInfo, |
| 140 Zone* zone); |
137 | 141 |
138 // Array index in the lastMatchInfo array. | 142 // Array index in the lastMatchInfo array. |
139 static const int kLastCaptureCount = 0; | 143 static const int kLastCaptureCount = 0; |
140 static const int kLastSubject = 1; | 144 static const int kLastSubject = 1; |
141 static const int kLastInput = 2; | 145 static const int kLastInput = 2; |
142 static const int kFirstCapture = 3; | 146 static const int kFirstCapture = 3; |
143 static const int kLastMatchOverhead = 3; | 147 static const int kLastMatchOverhead = 3; |
144 | 148 |
145 // Direct offset into the lastMatchInfo array. | 149 // Direct offset into the lastMatchInfo array. |
146 static const int kLastCaptureCountOffset = | 150 static const int kLastCaptureCountOffset = |
(...skipping 44 matching lines...) Loading... |
191 // total regexp code compiled including code that has subsequently been freed | 195 // total regexp code compiled including code that has subsequently been freed |
192 // and the total executable memory at any point. | 196 // and the total executable memory at any point. |
193 static const int kRegExpExecutableMemoryLimit = 16 * MB; | 197 static const int kRegExpExecutableMemoryLimit = 16 * MB; |
194 static const int kRegWxpCompiledLimit = 1 * MB; | 198 static const int kRegWxpCompiledLimit = 1 * MB; |
195 | 199 |
196 private: | 200 private: |
197 static String* last_ascii_string_; | 201 static String* last_ascii_string_; |
198 static String* two_byte_cached_string_; | 202 static String* two_byte_cached_string_; |
199 | 203 |
200 static bool CompileIrregexp( | 204 static bool CompileIrregexp( |
201 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); | 205 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii, |
| 206 Zone* zone); |
202 static inline bool EnsureCompiledIrregexp( | 207 static inline bool EnsureCompiledIrregexp( |
203 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); | 208 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii, |
| 209 Zone* zone); |
204 | 210 |
205 | 211 |
206 // Set the subject cache. The previous string buffer is not deleted, so the | 212 // Set the subject cache. The previous string buffer is not deleted, so the |
207 // caller should ensure that it doesn't leak. | 213 // caller should ensure that it doesn't leak. |
208 static void SetSubjectCache(String* subject, | 214 static void SetSubjectCache(String* subject, |
209 char* utf8_subject, | 215 char* utf8_subject, |
210 int uft8_length, | 216 int uft8_length, |
211 int character_position, | 217 int character_position, |
212 int utf8_position); | 218 int utf8_position); |
213 | 219 |
(...skipping 313 matching lines...) Loading... |
527 // E.g., if it requires to be at the start of the input, and isn't. | 533 // E.g., if it requires to be at the start of the input, and isn't. |
528 bool cannot_match_; | 534 bool cannot_match_; |
529 }; | 535 }; |
530 | 536 |
531 | 537 |
532 extern int kUninitializedRegExpNodePlaceHolder; | 538 extern int kUninitializedRegExpNodePlaceHolder; |
533 | 539 |
534 | 540 |
535 class RegExpNode: public ZoneObject { | 541 class RegExpNode: public ZoneObject { |
536 public: | 542 public: |
537 RegExpNode() : replacement_(NULL), trace_count_(0) { | 543 explicit RegExpNode(Zone* zone) |
| 544 : replacement_(NULL), trace_count_(0), zone_(zone) { |
538 bm_info_[0] = bm_info_[1] = NULL; | 545 bm_info_[0] = bm_info_[1] = NULL; |
539 } | 546 } |
540 virtual ~RegExpNode(); | 547 virtual ~RegExpNode(); |
541 virtual void Accept(NodeVisitor* visitor) = 0; | 548 virtual void Accept(NodeVisitor* visitor) = 0; |
542 // Generates a goto to this node or actually generates the code at this point. | 549 // Generates a goto to this node or actually generates the code at this point. |
543 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; | 550 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; |
544 // How many characters must this node consume at a minimum in order to | 551 // How many characters must this node consume at a minimum in order to |
545 // succeed. If we have found at least 'still_to_find' characters that | 552 // succeed. If we have found at least 'still_to_find' characters that |
546 // must be consumed there is no need to ask any following nodes whether | 553 // must be consumed there is no need to ask any following nodes whether |
547 // they are sure to eat any more characters. The not_at_start argument is | 554 // they are sure to eat any more characters. The not_at_start argument is |
(...skipping 73 matching lines...) Loading... |
621 // trace and generating generic code for a node that can be reused by flushing | 628 // trace and generating generic code for a node that can be reused by flushing |
622 // the deferred actions in the current trace and generating a goto. | 629 // the deferred actions in the current trace and generating a goto. |
623 static const int kMaxCopiesCodeGenerated = 10; | 630 static const int kMaxCopiesCodeGenerated = 10; |
624 | 631 |
625 NodeInfo* info() { return &info_; } | 632 NodeInfo* info() { return &info_; } |
626 | 633 |
627 BoyerMooreLookahead* bm_info(bool not_at_start) { | 634 BoyerMooreLookahead* bm_info(bool not_at_start) { |
628 return bm_info_[not_at_start ? 1 : 0]; | 635 return bm_info_[not_at_start ? 1 : 0]; |
629 } | 636 } |
630 | 637 |
| 638 Zone* zone() { return zone_; } |
| 639 |
631 protected: | 640 protected: |
632 enum LimitResult { DONE, CONTINUE }; | 641 enum LimitResult { DONE, CONTINUE }; |
633 RegExpNode* replacement_; | 642 RegExpNode* replacement_; |
634 | 643 |
635 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); | 644 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); |
636 | 645 |
637 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { | 646 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { |
638 bm_info_[not_at_start ? 1 : 0] = bm; | 647 bm_info_[not_at_start ? 1 : 0] = bm; |
639 } | 648 } |
640 | 649 |
641 private: | 650 private: |
642 static const int kFirstCharBudget = 10; | 651 static const int kFirstCharBudget = 10; |
643 Label label_; | 652 Label label_; |
644 NodeInfo info_; | 653 NodeInfo info_; |
645 // This variable keeps track of how many times code has been generated for | 654 // This variable keeps track of how many times code has been generated for |
646 // this node (in different traces). We don't keep track of where the | 655 // this node (in different traces). We don't keep track of where the |
647 // generated code is located unless the code is generated at the start of | 656 // generated code is located unless the code is generated at the start of |
648 // a trace, in which case it is generic and can be reused by flushing the | 657 // a trace, in which case it is generic and can be reused by flushing the |
649 // deferred operations in the current trace and generating a goto. | 658 // deferred operations in the current trace and generating a goto. |
650 int trace_count_; | 659 int trace_count_; |
651 BoyerMooreLookahead* bm_info_[2]; | 660 BoyerMooreLookahead* bm_info_[2]; |
| 661 |
| 662 Zone* zone_; |
652 }; | 663 }; |
653 | 664 |
654 | 665 |
655 // A simple closed interval. | 666 // A simple closed interval. |
656 class Interval { | 667 class Interval { |
657 public: | 668 public: |
658 Interval() : from_(kNone), to_(kNone) { } | 669 Interval() : from_(kNone), to_(kNone) { } |
659 Interval(int from, int to) : from_(from), to_(to) { } | 670 Interval(int from, int to) : from_(from), to_(to) { } |
660 Interval Union(Interval that) { | 671 Interval Union(Interval that) { |
661 if (that.from_ == kNone) | 672 if (that.from_ == kNone) |
(...skipping 13 matching lines...) Loading... |
675 static const int kNone = -1; | 686 static const int kNone = -1; |
676 private: | 687 private: |
677 int from_; | 688 int from_; |
678 int to_; | 689 int to_; |
679 }; | 690 }; |
680 | 691 |
681 | 692 |
682 class SeqRegExpNode: public RegExpNode { | 693 class SeqRegExpNode: public RegExpNode { |
683 public: | 694 public: |
684 explicit SeqRegExpNode(RegExpNode* on_success) | 695 explicit SeqRegExpNode(RegExpNode* on_success) |
685 : on_success_(on_success) { } | 696 : RegExpNode(on_success->zone()), on_success_(on_success) { } |
686 RegExpNode* on_success() { return on_success_; } | 697 RegExpNode* on_success() { return on_success_; } |
687 void set_on_success(RegExpNode* node) { on_success_ = node; } | 698 void set_on_success(RegExpNode* node) { on_success_ = node; } |
688 virtual RegExpNode* FilterASCII(int depth); | 699 virtual RegExpNode* FilterASCII(int depth); |
689 virtual void FillInBMInfo(int offset, | 700 virtual void FillInBMInfo(int offset, |
690 int recursion_depth, | 701 int recursion_depth, |
691 int budget, | 702 int budget, |
692 BoyerMooreLookahead* bm, | 703 BoyerMooreLookahead* bm, |
693 bool not_at_start) { | 704 bool not_at_start) { |
694 on_success_->FillInBMInfo( | 705 on_success_->FillInBMInfo( |
695 offset, recursion_depth + 1, budget - 1, bm, not_at_start); | 706 offset, recursion_depth + 1, budget - 1, bm, not_at_start); |
(...skipping 97 matching lines...) Loading... |
793 | 804 |
794 class TextNode: public SeqRegExpNode { | 805 class TextNode: public SeqRegExpNode { |
795 public: | 806 public: |
796 TextNode(ZoneList<TextElement>* elms, | 807 TextNode(ZoneList<TextElement>* elms, |
797 RegExpNode* on_success) | 808 RegExpNode* on_success) |
798 : SeqRegExpNode(on_success), | 809 : SeqRegExpNode(on_success), |
799 elms_(elms) { } | 810 elms_(elms) { } |
800 TextNode(RegExpCharacterClass* that, | 811 TextNode(RegExpCharacterClass* that, |
801 RegExpNode* on_success) | 812 RegExpNode* on_success) |
802 : SeqRegExpNode(on_success), | 813 : SeqRegExpNode(on_success), |
803 elms_(new ZoneList<TextElement>(1)) { | 814 elms_(new ZoneList<TextElement>(1, zone())) { |
804 elms_->Add(TextElement::CharClass(that)); | 815 elms_->Add(TextElement::CharClass(that), zone()); |
805 } | 816 } |
806 virtual void Accept(NodeVisitor* visitor); | 817 virtual void Accept(NodeVisitor* visitor); |
807 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 818 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
808 virtual int EatsAtLeast(int still_to_find, | 819 virtual int EatsAtLeast(int still_to_find, |
809 int recursion_depth, | 820 int recursion_depth, |
810 bool not_at_start); | 821 bool not_at_start); |
811 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 822 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
812 RegExpCompiler* compiler, | 823 RegExpCompiler* compiler, |
813 int characters_filled_in, | 824 int characters_filled_in, |
814 bool not_at_start); | 825 bool not_at_start); |
(...skipping 114 matching lines...) Loading... |
929 | 940 |
930 private: | 941 private: |
931 int start_reg_; | 942 int start_reg_; |
932 int end_reg_; | 943 int end_reg_; |
933 }; | 944 }; |
934 | 945 |
935 | 946 |
936 class EndNode: public RegExpNode { | 947 class EndNode: public RegExpNode { |
937 public: | 948 public: |
938 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; | 949 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; |
939 explicit EndNode(Action action) : action_(action) { } | 950 explicit EndNode(Action action, Zone* zone) |
| 951 : RegExpNode(zone), action_(action) { } |
940 virtual void Accept(NodeVisitor* visitor); | 952 virtual void Accept(NodeVisitor* visitor); |
941 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 953 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
942 virtual int EatsAtLeast(int still_to_find, | 954 virtual int EatsAtLeast(int still_to_find, |
943 int recursion_depth, | 955 int recursion_depth, |
944 bool not_at_start) { return 0; } | 956 bool not_at_start) { return 0; } |
945 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 957 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
946 RegExpCompiler* compiler, | 958 RegExpCompiler* compiler, |
947 int characters_filled_in, | 959 int characters_filled_in, |
948 bool not_at_start) { | 960 bool not_at_start) { |
949 // Returning 0 from EatsAtLeast should ensure we never get here. | 961 // Returning 0 from EatsAtLeast should ensure we never get here. |
(...skipping 11 matching lines...) Loading... |
961 private: | 973 private: |
962 Action action_; | 974 Action action_; |
963 }; | 975 }; |
964 | 976 |
965 | 977 |
966 class NegativeSubmatchSuccess: public EndNode { | 978 class NegativeSubmatchSuccess: public EndNode { |
967 public: | 979 public: |
968 NegativeSubmatchSuccess(int stack_pointer_reg, | 980 NegativeSubmatchSuccess(int stack_pointer_reg, |
969 int position_reg, | 981 int position_reg, |
970 int clear_capture_count, | 982 int clear_capture_count, |
971 int clear_capture_start) | 983 int clear_capture_start, |
972 : EndNode(NEGATIVE_SUBMATCH_SUCCESS), | 984 Zone* zone) |
| 985 : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone), |
973 stack_pointer_register_(stack_pointer_reg), | 986 stack_pointer_register_(stack_pointer_reg), |
974 current_position_register_(position_reg), | 987 current_position_register_(position_reg), |
975 clear_capture_count_(clear_capture_count), | 988 clear_capture_count_(clear_capture_count), |
976 clear_capture_start_(clear_capture_start) { } | 989 clear_capture_start_(clear_capture_start) { } |
977 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 990 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
978 | 991 |
979 private: | 992 private: |
980 int stack_pointer_register_; | 993 int stack_pointer_register_; |
981 int current_position_register_; | 994 int current_position_register_; |
982 int clear_capture_count_; | 995 int clear_capture_count_; |
(...skipping 31 matching lines...) Loading... |
1014 RegExpNode* node_; | 1027 RegExpNode* node_; |
1015 ZoneList<Guard*>* guards_; | 1028 ZoneList<Guard*>* guards_; |
1016 }; | 1029 }; |
1017 | 1030 |
1018 | 1031 |
1019 class AlternativeGeneration; | 1032 class AlternativeGeneration; |
1020 | 1033 |
1021 | 1034 |
1022 class ChoiceNode: public RegExpNode { | 1035 class ChoiceNode: public RegExpNode { |
1023 public: | 1036 public: |
1024 explicit ChoiceNode(int expected_size) | 1037 explicit ChoiceNode(int expected_size, Zone* zone) |
1025 : alternatives_(new ZoneList<GuardedAlternative>(expected_size)), | 1038 : RegExpNode(zone), |
| 1039 alternatives_(new ZoneList<GuardedAlternative>(expected_size, zone)), |
1026 table_(NULL), | 1040 table_(NULL), |
1027 not_at_start_(false), | 1041 not_at_start_(false), |
1028 being_calculated_(false) { } | 1042 being_calculated_(false) { } |
1029 virtual void Accept(NodeVisitor* visitor); | 1043 virtual void Accept(NodeVisitor* visitor); |
1030 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } | 1044 void AddAlternative(GuardedAlternative node) { |
| 1045 alternatives()->Add(node, zone()); |
| 1046 } |
1031 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } | 1047 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } |
1032 DispatchTable* GetTable(bool ignore_case); | 1048 DispatchTable* GetTable(bool ignore_case); |
1033 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1049 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
1034 virtual int EatsAtLeast(int still_to_find, | 1050 virtual int EatsAtLeast(int still_to_find, |
1035 int recursion_depth, | 1051 int recursion_depth, |
1036 bool not_at_start); | 1052 bool not_at_start); |
1037 int EatsAtLeastHelper(int still_to_find, | 1053 int EatsAtLeastHelper(int still_to_find, |
1038 int recursion_depth, | 1054 int recursion_depth, |
1039 RegExpNode* ignore_this_node, | 1055 RegExpNode* ignore_this_node, |
1040 bool not_at_start); | 1056 bool not_at_start); |
(...skipping 35 matching lines...) Loading... |
1076 // If true, this node is never checked at the start of the input. | 1092 // If true, this node is never checked at the start of the input. |
1077 // Allows a new trace to start with at_start() set to false. | 1093 // Allows a new trace to start with at_start() set to false. |
1078 bool not_at_start_; | 1094 bool not_at_start_; |
1079 bool being_calculated_; | 1095 bool being_calculated_; |
1080 }; | 1096 }; |
1081 | 1097 |
1082 | 1098 |
1083 class NegativeLookaheadChoiceNode: public ChoiceNode { | 1099 class NegativeLookaheadChoiceNode: public ChoiceNode { |
1084 public: | 1100 public: |
1085 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, | 1101 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, |
1086 GuardedAlternative then_do_this) | 1102 GuardedAlternative then_do_this, |
1087 : ChoiceNode(2) { | 1103 Zone* zone) |
| 1104 : ChoiceNode(2, zone) { |
1088 AddAlternative(this_must_fail); | 1105 AddAlternative(this_must_fail); |
1089 AddAlternative(then_do_this); | 1106 AddAlternative(then_do_this); |
1090 } | 1107 } |
1091 virtual int EatsAtLeast(int still_to_find, | 1108 virtual int EatsAtLeast(int still_to_find, |
1092 int recursion_depth, | 1109 int recursion_depth, |
1093 bool not_at_start); | 1110 bool not_at_start); |
1094 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1111 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
1095 RegExpCompiler* compiler, | 1112 RegExpCompiler* compiler, |
1096 int characters_filled_in, | 1113 int characters_filled_in, |
1097 bool not_at_start); | 1114 bool not_at_start); |
(...skipping 11 matching lines...) Loading... |
1109 // starts by loading enough characters for the alternative that takes fewest | 1126 // starts by loading enough characters for the alternative that takes fewest |
1110 // characters, but on a negative lookahead the negative branch did not take | 1127 // characters, but on a negative lookahead the negative branch did not take |
1111 // part in that calculation (EatsAtLeast) so the assumptions don't hold. | 1128 // part in that calculation (EatsAtLeast) so the assumptions don't hold. |
1112 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } | 1129 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } |
1113 virtual RegExpNode* FilterASCII(int depth); | 1130 virtual RegExpNode* FilterASCII(int depth); |
1114 }; | 1131 }; |
1115 | 1132 |
1116 | 1133 |
1117 class LoopChoiceNode: public ChoiceNode { | 1134 class LoopChoiceNode: public ChoiceNode { |
1118 public: | 1135 public: |
1119 explicit LoopChoiceNode(bool body_can_be_zero_length) | 1136 explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) |
1120 : ChoiceNode(2), | 1137 : ChoiceNode(2, zone), |
1121 loop_node_(NULL), | 1138 loop_node_(NULL), |
1122 continue_node_(NULL), | 1139 continue_node_(NULL), |
1123 body_can_be_zero_length_(body_can_be_zero_length) { } | 1140 body_can_be_zero_length_(body_can_be_zero_length) { } |
1124 void AddLoopAlternative(GuardedAlternative alt); | 1141 void AddLoopAlternative(GuardedAlternative alt); |
1125 void AddContinueAlternative(GuardedAlternative alt); | 1142 void AddContinueAlternative(GuardedAlternative alt); |
1126 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1143 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
1127 virtual int EatsAtLeast(int still_to_find, | 1144 virtual int EatsAtLeast(int still_to_find, |
1128 int recursion_depth, | 1145 int recursion_depth, |
1129 bool not_at_start); | 1146 bool not_at_start); |
1130 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1147 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
(...skipping 64 matching lines...) Loading... |
1195 | 1212 |
1196 | 1213 |
1197 ContainedInLattice AddRange(ContainedInLattice a, | 1214 ContainedInLattice AddRange(ContainedInLattice a, |
1198 const int* ranges, | 1215 const int* ranges, |
1199 int ranges_size, | 1216 int ranges_size, |
1200 Interval new_range); | 1217 Interval new_range); |
1201 | 1218 |
1202 | 1219 |
1203 class BoyerMoorePositionInfo : public ZoneObject { | 1220 class BoyerMoorePositionInfo : public ZoneObject { |
1204 public: | 1221 public: |
1205 BoyerMoorePositionInfo() | 1222 explicit BoyerMoorePositionInfo(Zone* zone) |
1206 : map_(new ZoneList<bool>(kMapSize)), | 1223 : map_(new ZoneList<bool>(kMapSize, zone)), |
1207 map_count_(0), | 1224 map_count_(0), |
1208 w_(kNotYet), | 1225 w_(kNotYet), |
1209 s_(kNotYet), | 1226 s_(kNotYet), |
1210 d_(kNotYet), | 1227 d_(kNotYet), |
1211 surrogate_(kNotYet) { | 1228 surrogate_(kNotYet) { |
1212 for (int i = 0; i < kMapSize; i++) { | 1229 for (int i = 0; i < kMapSize; i++) { |
1213 map_->Add(false); | 1230 map_->Add(false, zone); |
1214 } | 1231 } |
1215 } | 1232 } |
1216 | 1233 |
1217 bool& at(int i) { return map_->at(i); } | 1234 bool& at(int i) { return map_->at(i); } |
1218 | 1235 |
1219 static const int kMapSize = 128; | 1236 static const int kMapSize = 128; |
1220 static const int kMask = kMapSize - 1; | 1237 static const int kMask = kMapSize - 1; |
1221 | 1238 |
1222 int map_count() const { return map_count_; } | 1239 int map_count() const { return map_count_; } |
1223 | 1240 |
1224 void Set(int character); | 1241 void Set(int character); |
1225 void SetInterval(const Interval& interval); | 1242 void SetInterval(const Interval& interval); |
1226 void SetAll(); | 1243 void SetAll(); |
1227 bool is_non_word() { return w_ == kLatticeOut; } | 1244 bool is_non_word() { return w_ == kLatticeOut; } |
1228 bool is_word() { return w_ == kLatticeIn; } | 1245 bool is_word() { return w_ == kLatticeIn; } |
1229 | 1246 |
1230 private: | 1247 private: |
1231 ZoneList<bool>* map_; | 1248 ZoneList<bool>* map_; |
1232 int map_count_; // Number of set bits in the map. | 1249 int map_count_; // Number of set bits in the map. |
1233 ContainedInLattice w_; // The \w character class. | 1250 ContainedInLattice w_; // The \w character class. |
1234 ContainedInLattice s_; // The \s character class. | 1251 ContainedInLattice s_; // The \s character class. |
1235 ContainedInLattice d_; // The \d character class. | 1252 ContainedInLattice d_; // The \d character class. |
1236 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. | 1253 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. |
1237 }; | 1254 }; |
1238 | 1255 |
1239 | 1256 |
1240 class BoyerMooreLookahead : public ZoneObject { | 1257 class BoyerMooreLookahead : public ZoneObject { |
1241 public: | 1258 public: |
1242 BoyerMooreLookahead(int length, RegExpCompiler* compiler); | 1259 BoyerMooreLookahead(int length, RegExpCompiler* compiler, Zone* zone); |
1243 | 1260 |
1244 int length() { return length_; } | 1261 int length() { return length_; } |
1245 int max_char() { return max_char_; } | 1262 int max_char() { return max_char_; } |
1246 RegExpCompiler* compiler() { return compiler_; } | 1263 RegExpCompiler* compiler() { return compiler_; } |
1247 | 1264 |
1248 int Count(int map_number) { | 1265 int Count(int map_number) { |
1249 return bitmaps_->at(map_number)->map_count(); | 1266 return bitmaps_->at(map_number)->map_count(); |
1250 } | 1267 } |
1251 | 1268 |
1252 BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); } | 1269 BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); } |
(...skipping 329 matching lines...) Loading... |
1582 Object* code; | 1599 Object* code; |
1583 int num_registers; | 1600 int num_registers; |
1584 }; | 1601 }; |
1585 | 1602 |
1586 static CompilationResult Compile(RegExpCompileData* input, | 1603 static CompilationResult Compile(RegExpCompileData* input, |
1587 bool ignore_case, | 1604 bool ignore_case, |
1588 bool global, | 1605 bool global, |
1589 bool multiline, | 1606 bool multiline, |
1590 Handle<String> pattern, | 1607 Handle<String> pattern, |
1591 Handle<String> sample_subject, | 1608 Handle<String> sample_subject, |
1592 bool is_ascii); | 1609 bool is_ascii, Zone* zone); |
1593 | 1610 |
1594 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); | 1611 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); |
1595 }; | 1612 }; |
1596 | 1613 |
1597 | 1614 |
1598 class OffsetsVector { | 1615 class OffsetsVector { |
1599 public: | 1616 public: |
1600 inline OffsetsVector(int num_registers, Isolate* isolate) | 1617 inline OffsetsVector(int num_registers, Isolate* isolate) |
1601 : offsets_vector_length_(num_registers) { | 1618 : offsets_vector_length_(num_registers) { |
1602 if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) { | 1619 if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) { |
(...skipping 22 matching lines...) Loading... |
1625 int* vector_; | 1642 int* vector_; |
1626 int offsets_vector_length_; | 1643 int offsets_vector_length_; |
1627 | 1644 |
1628 friend class ExternalReference; | 1645 friend class ExternalReference; |
1629 }; | 1646 }; |
1630 | 1647 |
1631 | 1648 |
1632 } } // namespace v8::internal | 1649 } } // namespace v8::internal |
1633 | 1650 |
1634 #endif // V8_JSREGEXP_H_ | 1651 #endif // V8_JSREGEXP_H_ |
OLD | NEW |