| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   137       } |   137       } | 
|   138     } |   138     } | 
|   139   } |   139   } | 
|   140   if (index < 0) { |   140   if (index < 0) { | 
|   141     return -1; |   141     return -1; | 
|   142   } |   142   } | 
|   143   return %StringLastIndexOf(sub, pat, index); |   143   return %StringLastIndexOf(sub, pat, index); | 
|   144 } |   144 } | 
|   145  |   145  | 
|   146  |   146  | 
|   147 function CloneDenseArray(array) { |  | 
|   148   if (array === null) return null; |  | 
|   149   var clone = new $Array(array.length); |  | 
|   150   for (var i = 0; i < array.length; i++) { |  | 
|   151     clone[i] = array[i]; |  | 
|   152   } |  | 
|   153   return clone; |  | 
|   154 } |  | 
|   155  |  | 
|   156  |  | 
|   157 // ECMA-262 section 15.5.4.9 |   147 // ECMA-262 section 15.5.4.9 | 
|   158 // |   148 // | 
|   159 // This function is implementation specific.  For now, we do not |   149 // This function is implementation specific.  For now, we do not | 
|   160 // do anything locale specific. |   150 // do anything locale specific. | 
|   161 function StringLocaleCompare(other) { |   151 function StringLocaleCompare(other) { | 
|   162   if (%_ArgumentsLength() === 0) return 0; |   152   if (%_ArgumentsLength() === 0) return 0; | 
|   163  |   153  | 
|   164   var this_str = TO_STRING_INLINE(this); |   154   var this_str = TO_STRING_INLINE(this); | 
|   165   var other_str = TO_STRING_INLINE(other); |   155   var other_str = TO_STRING_INLINE(other); | 
|   166   return %StringLocaleCompare(this_str, other_str); |   156   return %StringLocaleCompare(this_str, other_str); | 
|   167 } |   157 } | 
|   168  |   158  | 
|   169  |   159  | 
|   170 // ECMA-262 section 15.5.4.10 |   160 // ECMA-262 section 15.5.4.10 | 
|   171 function StringMatch(regexp) { |   161 function StringMatch(regexp) { | 
|   172   var subject = TO_STRING_INLINE(this); |   162   var subject = TO_STRING_INLINE(this); | 
|   173   if (IS_REGEXP(regexp)) { |   163   if (IS_REGEXP(regexp)) { | 
|   174     if (!regexp.global) return regexp.exec(subject); |   164     if (!regexp.global) return regexp.exec(subject); | 
|   175  |   165  | 
|   176     var cache = regExpCache; |  | 
|   177     var saveAnswer = false; |   166     var saveAnswer = false; | 
|   178  |   167  | 
|   179     if (%_ObjectEquals(cache.type, 'match') && |  | 
|   180         %_IsRegExpEquivalent(cache.regExp, regexp) && |  | 
|   181         %_ObjectEquals(cache.subject, subject)) { |  | 
|   182       if (cache.answerSaved) { |  | 
|   183         return CloneDenseArray(cache.answer); |  | 
|   184       } else { |  | 
|   185         saveAnswer = true; |  | 
|   186       } |  | 
|   187     } |  | 
|   188     %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); |   168     %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); | 
|   189     // lastMatchInfo is defined in regexp.js. |   169     // lastMatchInfo is defined in regexp.js. | 
|   190     var result = %StringMatch(subject, regexp, lastMatchInfo); |   170     return %StringMatch(subject, regexp, lastMatchInfo); | 
|   191     cache.type = 'match'; |  | 
|   192     cache.regExp = regexp; |  | 
|   193     cache.subject = subject; |  | 
|   194     if (saveAnswer) cache.answer = CloneDenseArray(result); |  | 
|   195     cache.answerSaved = saveAnswer; |  | 
|   196     return result; |  | 
|   197   } |   171   } | 
|   198   // Non-regexp argument. |   172   // Non-regexp argument. | 
|   199   regexp = new $RegExp(regexp); |   173   regexp = new $RegExp(regexp); | 
|   200   // Don't check regexp exec cache, since the regexp is new. |  | 
|   201   // TODO(lrn): Change this if we start caching regexps here. |  | 
|   202   return RegExpExecNoTests(regexp, subject, 0); |   174   return RegExpExecNoTests(regexp, subject, 0); | 
|   203 } |   175 } | 
|   204  |   176  | 
|   205  |   177  | 
|   206 // SubString is an internal function that returns the sub string of 'string'. |   178 // SubString is an internal function that returns the sub string of 'string'. | 
|   207 // If resulting string is of length 1, we use the one character cache |   179 // If resulting string is of length 1, we use the one character cache | 
|   208 // otherwise we call the runtime system. |   180 // otherwise we call the runtime system. | 
|   209 function SubString(string, start, end) { |   181 function SubString(string, start, end) { | 
|   210   // Use the one character string cache. |   182   // Use the one character string cache. | 
|   211   if (start + 1 == end) { |   183   if (start + 1 == end) { | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|   224  |   196  | 
|   225  |   197  | 
|   226 // ECMA-262, section 15.5.4.11 |   198 // ECMA-262, section 15.5.4.11 | 
|   227 function StringReplace(search, replace) { |   199 function StringReplace(search, replace) { | 
|   228   var subject = TO_STRING_INLINE(this); |   200   var subject = TO_STRING_INLINE(this); | 
|   229  |   201  | 
|   230   // Delegate to one of the regular expression variants if necessary. |   202   // Delegate to one of the regular expression variants if necessary. | 
|   231   if (IS_REGEXP(search)) { |   203   if (IS_REGEXP(search)) { | 
|   232     %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); |   204     %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); | 
|   233     if (IS_FUNCTION(replace)) { |   205     if (IS_FUNCTION(replace)) { | 
|   234       regExpCache.type = 'none'; |  | 
|   235       if (search.global) { |   206       if (search.global) { | 
|   236         return StringReplaceGlobalRegExpWithFunction(subject, search, replace); |   207         return StringReplaceGlobalRegExpWithFunction(subject, search, replace); | 
|   237       } else { |   208       } else { | 
|   238         return StringReplaceNonGlobalRegExpWithFunction(subject, |   209         return StringReplaceNonGlobalRegExpWithFunction(subject, | 
|   239                                                         search, |   210                                                         search, | 
|   240                                                         replace); |   211                                                         replace); | 
|   241       } |   212       } | 
|   242     } else { |   213     } else { | 
|   243       return StringReplaceRegExp(subject, search, replace); |   214       return StringReplaceRegExp(subject, search, replace); | 
|   244     } |   215     } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   266  |   237  | 
|   267   // suffix |   238   // suffix | 
|   268   builder.addSpecialSlice(end, subject.length); |   239   builder.addSpecialSlice(end, subject.length); | 
|   269  |   240  | 
|   270   return builder.generate(); |   241   return builder.generate(); | 
|   271 } |   242 } | 
|   272  |   243  | 
|   273  |   244  | 
|   274 // Helper function for regular expressions in String.prototype.replace. |   245 // Helper function for regular expressions in String.prototype.replace. | 
|   275 function StringReplaceRegExp(subject, regexp, replace) { |   246 function StringReplaceRegExp(subject, regexp, replace) { | 
|   276   var cache = regExpCache; |   247   return %StringReplaceRegExpWithString(subject, | 
|   277   if (%_ObjectEquals(cache.type, 'replace') && |   248                                         regexp, | 
|   278       %_IsRegExpEquivalent(cache.regExp, regexp) && |   249                                         TO_STRING_INLINE(replace), | 
|   279       %_ObjectEquals(cache.replaceString, replace) && |   250                                         lastMatchInfo); | 
|   280       %_ObjectEquals(cache.subject, subject)) { |  | 
|   281     return cache.answer; |  | 
|   282   } |  | 
|   283   replace = TO_STRING_INLINE(replace); |  | 
|   284   var answer = %StringReplaceRegExpWithString(subject, |  | 
|   285                                               regexp, |  | 
|   286                                               replace, |  | 
|   287                                               lastMatchInfo); |  | 
|   288   cache.subject = subject; |  | 
|   289   cache.regExp = regexp; |  | 
|   290   cache.replaceString = replace; |  | 
|   291   cache.answer = answer; |  | 
|   292   cache.type = 'replace'; |  | 
|   293   return answer; |  | 
|   294 } |   251 } | 
|   295  |   252  | 
|   296  |   253  | 
|   297 // Expand the $-expressions in the string and return a new string with |   254 // Expand the $-expressions in the string and return a new string with | 
|   298 // the result. |   255 // the result. | 
|   299 function ExpandReplacement(string, subject, matchInfo, builder) { |   256 function ExpandReplacement(string, subject, matchInfo, builder) { | 
|   300   var next = %StringIndexOf(string, '$', 0); |   257   var next = %StringIndexOf(string, '$', 0); | 
|   301   if (next < 0) { |   258   if (next < 0) { | 
|   302     builder.add(string); |   259     builder.add(string); | 
|   303     return; |   260     return; | 
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   598     var separator_length = separator.length; |   555     var separator_length = separator.length; | 
|   599  |   556  | 
|   600     // If the separator string is empty then return the elements in the subject. |   557     // If the separator string is empty then return the elements in the subject. | 
|   601     if (separator_length === 0) return %StringToArray(subject); |   558     if (separator_length === 0) return %StringToArray(subject); | 
|   602  |   559  | 
|   603     var result = %StringSplit(subject, separator, limit); |   560     var result = %StringSplit(subject, separator, limit); | 
|   604  |   561  | 
|   605     return result; |   562     return result; | 
|   606   } |   563   } | 
|   607  |   564  | 
|   608   var cache = regExpCache; |  | 
|   609   var saveAnswer = false; |   565   var saveAnswer = false; | 
|   610  |   566  | 
|   611   if (%_ObjectEquals(cache.type, 'split') && |  | 
|   612       %_IsRegExpEquivalent(cache.regExp, separator) && |  | 
|   613       %_ObjectEquals(cache.subject, subject) && |  | 
|   614       %_ObjectEquals(cache.splitLimit, limit)) { |  | 
|   615     if (cache.answerSaved) { |  | 
|   616       return CloneDenseArray(cache.answer); |  | 
|   617     } else { |  | 
|   618       saveAnswer = true; |  | 
|   619     } |  | 
|   620   } |  | 
|   621  |  | 
|   622   cache.type = 'split'; |  | 
|   623   cache.regExp = separator; |  | 
|   624   cache.subject = subject; |  | 
|   625   cache.splitLimit = limit; |  | 
|   626  |  | 
|   627   %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); |   567   %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); | 
|   628  |   568  | 
|   629   if (length === 0) { |   569   if (length === 0) { | 
|   630     cache.answerSaved = true; |  | 
|   631     if (splitMatch(separator, subject, 0, 0) != null) { |   570     if (splitMatch(separator, subject, 0, 0) != null) { | 
|   632       cache.answer = []; |  | 
|   633       return []; |   571       return []; | 
|   634     } |   572     } | 
|   635     cache.answer = [subject]; |  | 
|   636     return [subject]; |   573     return [subject]; | 
|   637   } |   574   } | 
|   638  |   575  | 
|   639   var currentIndex = 0; |   576   var currentIndex = 0; | 
|   640   var startIndex = 0; |   577   var startIndex = 0; | 
|   641   var result = []; |   578   var result = []; | 
|   642  |   579  | 
|   643   outer_loop: |   580   outer_loop: | 
|   644   while (true) { |   581   while (true) { | 
|   645  |   582  | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   673       if (start != -1 && end != -1) { |   610       if (start != -1 && end != -1) { | 
|   674         result[result.length] = SubString(subject, start, end); |   611         result[result.length] = SubString(subject, start, end); | 
|   675       } else { |   612       } else { | 
|   676         result[result.length] = void 0; |   613         result[result.length] = void 0; | 
|   677       } |   614       } | 
|   678       if (result.length === limit) break outer_loop; |   615       if (result.length === limit) break outer_loop; | 
|   679     } |   616     } | 
|   680  |   617  | 
|   681     startIndex = currentIndex = endIndex; |   618     startIndex = currentIndex = endIndex; | 
|   682   } |   619   } | 
|   683   if (saveAnswer) cache.answer = CloneDenseArray(result); |  | 
|   684   cache.answerSaved = saveAnswer; |  | 
|   685   return result; |   620   return result; | 
|   686 } |   621 } | 
|   687  |   622  | 
|   688  |   623  | 
|   689 // ECMA-262 section 15.5.4.14 |   624 // ECMA-262 section 15.5.4.14 | 
|   690 // Helper function used by split.  This version returns the matchInfo |   625 // Helper function used by split.  This version returns the matchInfo | 
|   691 // instead of allocating a new array with basically the same information. |   626 // instead of allocating a new array with basically the same information. | 
|   692 function splitMatch(separator, subject, current_index, start_index) { |   627 function splitMatch(separator, subject, current_index, start_index) { | 
|   693   var matchInfo = DoRegExpExec(separator, subject, start_index); |   628   var matchInfo = DoRegExpExec(separator, subject, start_index); | 
|   694   if (matchInfo == null) return null; |   629   if (matchInfo == null) return null; | 
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   999     "small", StringSmall, |   934     "small", StringSmall, | 
|  1000     "strike", StringStrike, |   935     "strike", StringStrike, | 
|  1001     "sub", StringSub, |   936     "sub", StringSub, | 
|  1002     "sup", StringSup, |   937     "sup", StringSup, | 
|  1003     "toJSON", StringToJSON |   938     "toJSON", StringToJSON | 
|  1004   )); |   939   )); | 
|  1005 } |   940 } | 
|  1006  |   941  | 
|  1007  |   942  | 
|  1008 SetupString(); |   943 SetupString(); | 
| OLD | NEW |