OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 142 } |
143 } | 143 } |
144 } | 144 } |
145 if (index < 0) { | 145 if (index < 0) { |
146 return -1; | 146 return -1; |
147 } | 147 } |
148 return %StringLastIndexOf(sub, pat, index); | 148 return %StringLastIndexOf(sub, pat, index); |
149 } | 149 } |
150 | 150 |
151 | 151 |
| 152 function CloneDenseArray(array) { |
| 153 if (array === null) return null; |
| 154 var clone = new $Array(array.length); |
| 155 for (var i = 0; i < array.length; i++) { |
| 156 clone[i] = array[i]; |
| 157 } |
| 158 return clone; |
| 159 } |
| 160 |
| 161 |
152 // ECMA-262 section 15.5.4.9 | 162 // ECMA-262 section 15.5.4.9 |
153 // | 163 // |
154 // This function is implementation specific. For now, we do not | 164 // This function is implementation specific. For now, we do not |
155 // do anything locale specific. | 165 // do anything locale specific. |
156 function StringLocaleCompare(other) { | 166 function StringLocaleCompare(other) { |
157 if (%_ArgumentsLength() === 0) return 0; | 167 if (%_ArgumentsLength() === 0) return 0; |
158 | 168 |
159 var this_str = TO_STRING_INLINE(this); | 169 var this_str = TO_STRING_INLINE(this); |
160 var other_str = TO_STRING_INLINE(other); | 170 var other_str = TO_STRING_INLINE(other); |
161 return %StringLocaleCompare(this_str, other_str); | 171 return %StringLocaleCompare(this_str, other_str); |
162 } | 172 } |
163 | 173 |
164 | 174 |
165 // ECMA-262 section 15.5.4.10 | 175 // ECMA-262 section 15.5.4.10 |
166 function StringMatch(regexp) { | 176 function StringMatch(regexp) { |
167 if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp); | |
168 var subject = TO_STRING_INLINE(this); | 177 var subject = TO_STRING_INLINE(this); |
| 178 if (IS_REGEXP(regexp)) { |
| 179 if (!regexp.global) return regexp.exec(subject); |
| 180 |
| 181 var cache = regExpCache; |
| 182 var saveAnswer = false; |
169 | 183 |
170 if (!regexp.global) return regexp.exec(subject); | 184 if (%_ObjectEquals(cache.type, 'match') && |
171 | 185 %_ObjectEquals(cache.regExp, regexp) && |
172 var cache = regExpCache; | 186 %_ObjectEquals(cache.subject, subject)) { |
173 var saveAnswer = false; | 187 if (cache.answerSaved) { |
174 | 188 return CloneDenseArray(cache.answer); |
175 if (%_ObjectEquals(cache.type, 'match') && | 189 } else { |
176 %_ObjectEquals(cache.regExp, regexp) && | 190 saveAnswer = true; |
177 %_ObjectEquals(cache.subject, subject)) { | 191 } |
178 if (cache.answerSaved) { | |
179 return CloneRegexpAnswer(cache.answer); | |
180 } else { | |
181 saveAnswer = true; | |
182 } | 192 } |
| 193 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); |
| 194 // lastMatchInfo is defined in regexp.js. |
| 195 var result = %StringMatch(subject, regexp, lastMatchInfo); |
| 196 cache.type = 'match'; |
| 197 cache.regExp = regexp; |
| 198 cache.subject = subject; |
| 199 if (saveAnswer) cache.answer = CloneDenseArray(result); |
| 200 cache.answerSaved = saveAnswer; |
| 201 return result; |
183 } | 202 } |
184 | 203 // Non-regexp argument. |
185 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); | 204 regexp = new $RegExp(regexp); |
186 // lastMatchInfo is defined in regexp.js. | 205 // Don't check regexp exec cache, since the regexp is new. |
187 var result = %StringMatch(subject, regexp, lastMatchInfo); | 206 // TODO(lrn): Change this if we start caching regexps here. |
188 cache.type = 'match'; | 207 return RegExpExecNoTests(regexp, subject, 0); |
189 cache.regExp = regexp; | |
190 cache.subject = subject; | |
191 if (saveAnswer) cache.answer = CloneRegexpAnswer(result); | |
192 cache.answerSaved = saveAnswer; | |
193 return result; | |
194 } | 208 } |
195 | 209 |
196 | 210 |
197 // SubString is an internal function that returns the sub string of 'string'. | 211 // SubString is an internal function that returns the sub string of 'string'. |
198 // If resulting string is of length 1, we use the one character cache | 212 // If resulting string is of length 1, we use the one character cache |
199 // otherwise we call the runtime system. | 213 // otherwise we call the runtime system. |
200 function SubString(string, start, end) { | 214 function SubString(string, start, end) { |
201 // Use the one character string cache. | 215 // Use the one character string cache. |
202 if (start + 1 == end) { | 216 if (start + 1 == end) { |
203 var char_code = %_FastCharCodeAt(string, start); | 217 var char_code = %_FastCharCodeAt(string, start); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 return result; | 606 return result; |
593 } | 607 } |
594 | 608 |
595 var cache = regExpCache; | 609 var cache = regExpCache; |
596 var saveAnswer = false; | 610 var saveAnswer = false; |
597 | 611 |
598 if (%_ObjectEquals(cache.type, 'split') && | 612 if (%_ObjectEquals(cache.type, 'split') && |
599 %_ObjectEquals(cache.regExp, separator) && | 613 %_ObjectEquals(cache.regExp, separator) && |
600 %_ObjectEquals(cache.subject, subject)) { | 614 %_ObjectEquals(cache.subject, subject)) { |
601 if (cache.answerSaved) { | 615 if (cache.answerSaved) { |
602 return CloneRegexpAnswer(cache.answer); | 616 return CloneDenseArray(cache.answer); |
603 } else { | 617 } else { |
604 saveAnswer = true; | 618 saveAnswer = true; |
605 } | 619 } |
606 } | 620 } |
607 | 621 |
608 cache.type = 'split'; | 622 cache.type = 'split'; |
609 cache.regExp = separator; | 623 cache.regExp = separator; |
610 cache.subject = subject; | 624 cache.subject = subject; |
611 | 625 |
612 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); | 626 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 if (start != -1 && end != -1) { | 672 if (start != -1 && end != -1) { |
659 result[result.length] = SubString(subject, start, end); | 673 result[result.length] = SubString(subject, start, end); |
660 } else { | 674 } else { |
661 result[result.length] = void 0; | 675 result[result.length] = void 0; |
662 } | 676 } |
663 if (result.length === limit) break outer_loop; | 677 if (result.length === limit) break outer_loop; |
664 } | 678 } |
665 | 679 |
666 startIndex = currentIndex = endIndex; | 680 startIndex = currentIndex = endIndex; |
667 } | 681 } |
668 if (saveAnswer) cache.answer = CloneRegexpAnswer(result); | 682 if (saveAnswer) cache.answer = CloneDenseArray(result); |
669 cache.answerSaved = saveAnswer; | 683 cache.answerSaved = saveAnswer; |
670 return result; | 684 return result; |
671 | |
672 } | 685 } |
673 | 686 |
674 | 687 |
675 // ECMA-262 section 15.5.4.14 | 688 // ECMA-262 section 15.5.4.14 |
676 // Helper function used by split. This version returns the matchInfo | 689 // Helper function used by split. This version returns the matchInfo |
677 // instead of allocating a new array with basically the same information. | 690 // instead of allocating a new array with basically the same information. |
678 function splitMatch(separator, subject, current_index, start_index) { | 691 function splitMatch(separator, subject, current_index, start_index) { |
679 var matchInfo = DoRegExpExec(separator, subject, start_index); | 692 var matchInfo = DoRegExpExec(separator, subject, start_index); |
680 if (matchInfo == null) return null; | 693 if (matchInfo == null) return null; |
681 // Section 15.5.4.14 paragraph two says that we do not allow zero length | 694 // Section 15.5.4.14 paragraph two says that we do not allow zero length |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 "small", StringSmall, | 998 "small", StringSmall, |
986 "strike", StringStrike, | 999 "strike", StringStrike, |
987 "sub", StringSub, | 1000 "sub", StringSub, |
988 "sup", StringSup, | 1001 "sup", StringSup, |
989 "toJSON", StringToJSON | 1002 "toJSON", StringToJSON |
990 )); | 1003 )); |
991 } | 1004 } |
992 | 1005 |
993 | 1006 |
994 SetupString(); | 1007 SetupString(); |
OLD | NEW |