| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 (function(global, utils) { | 5 (function(global, utils) { | 
| 6 | 6 | 
| 7 %CheckIsBootstrapping(); | 7 %CheckIsBootstrapping(); | 
| 8 | 8 | 
| 9 // ------------------------------------------------------------------- | 9 // ------------------------------------------------------------------- | 
| 10 // Imports | 10 // Imports | 
| 11 | 11 | 
| 12 var GlobalRegExp = global.RegExp; | 12 var GlobalRegExp = global.RegExp; | 
| 13 var GlobalString = global.String; | 13 var GlobalString = global.String; | 
| 14 var InternalArray = utils.InternalArray; | 14 var InternalArray = utils.InternalArray; | 
| 15 var InternalPackedArray = utils.InternalPackedArray; | 15 var InternalPackedArray = utils.InternalPackedArray; | 
| 16 | 16 | 
| 17 var MathMax; | 17 var MathMax; | 
| 18 var MathMin; | 18 var MathMin; | 
|  | 19 var RegExpExec; | 
|  | 20 var RegExpExecNoTests; | 
|  | 21 var RegExpLastMatchInfo; | 
| 19 | 22 | 
| 20 utils.Import(function(from) { | 23 utils.Import(function(from) { | 
| 21   MathMax = from.MathMax; | 24   MathMax = from.MathMax; | 
| 22   MathMin = from.MathMin; | 25   MathMin = from.MathMin; | 
|  | 26   RegExpExec = from.RegExpExec; | 
|  | 27   RegExpExecNoTests = from.RegExpExecNoTests; | 
|  | 28   RegExpLastMatchInfo = from.RegExpLastMatchInfo; | 
| 23 }); | 29 }); | 
| 24 | 30 | 
| 25 //------------------------------------------------------------------- | 31 //------------------------------------------------------------------- | 
| 26 | 32 | 
| 27 function StringConstructor(x) { | 33 function StringConstructor(x) { | 
| 28   if (%_ArgumentsLength() == 0) x = ''; | 34   if (%_ArgumentsLength() == 0) x = ''; | 
| 29   if (%_IsConstructCall()) { | 35   if (%_IsConstructCall()) { | 
| 30     %_SetValueOf(this, TO_STRING_INLINE(x)); | 36     %_SetValueOf(this, TO_STRING_INLINE(x)); | 
| 31   } else { | 37   } else { | 
| 32     return IS_SYMBOL(x) ? | 38     return IS_SYMBOL(x) ? | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 155 // ECMA-262 section 15.5.4.10 | 161 // ECMA-262 section 15.5.4.10 | 
| 156 function StringMatchJS(regexp) { | 162 function StringMatchJS(regexp) { | 
| 157   CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); | 163   CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); | 
| 158 | 164 | 
| 159   var subject = TO_STRING_INLINE(this); | 165   var subject = TO_STRING_INLINE(this); | 
| 160   if (IS_REGEXP(regexp)) { | 166   if (IS_REGEXP(regexp)) { | 
| 161     // Emulate RegExp.prototype.exec's side effect in step 5, even though | 167     // Emulate RegExp.prototype.exec's side effect in step 5, even though | 
| 162     // value is discarded. | 168     // value is discarded. | 
| 163     var lastIndex = regexp.lastIndex; | 169     var lastIndex = regexp.lastIndex; | 
| 164     TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 170     TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 
| 165     if (!regexp.global) return $regexpExecNoTests(regexp, subject, 0); | 171     if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); | 
| 166     var result = %StringMatch(subject, regexp, $regexpLastMatchInfo); | 172     var result = %StringMatch(subject, regexp, RegExpLastMatchInfo); | 
| 167     if (result !== null) $regexpLastMatchInfoOverride = null; | 173     if (result !== null) $regexpLastMatchInfoOverride = null; | 
| 168     regexp.lastIndex = 0; | 174     regexp.lastIndex = 0; | 
| 169     return result; | 175     return result; | 
| 170   } | 176   } | 
| 171   // Non-regexp argument. | 177   // Non-regexp argument. | 
| 172   regexp = new GlobalRegExp(regexp); | 178   regexp = new GlobalRegExp(regexp); | 
| 173   return $regexpExecNoTests(regexp, subject, 0); | 179   return RegExpExecNoTests(regexp, subject, 0); | 
| 174 } | 180 } | 
| 175 | 181 | 
| 176 | 182 | 
| 177 // ECMA-262 v6, section 21.1.3.12 | 183 // ECMA-262 v6, section 21.1.3.12 | 
| 178 // | 184 // | 
| 179 // For now we do nothing, as proper normalization requires big tables. | 185 // For now we do nothing, as proper normalization requires big tables. | 
| 180 // If Intl is enabled, then i18n.js will override it and provide the the | 186 // If Intl is enabled, then i18n.js will override it and provide the the | 
| 181 // proper functionality. | 187 // proper functionality. | 
| 182 function StringNormalizeJS(form) { | 188 function StringNormalizeJS(form) { | 
| 183   CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); | 189   CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); | 
| 184 | 190 | 
| 185   var form = form ? TO_STRING_INLINE(form) : 'NFC'; | 191   var form = form ? TO_STRING_INLINE(form) : 'NFC'; | 
| 186 | 192 | 
| 187   var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; | 193   var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; | 
| 188 | 194 | 
| 189   var normalizationForm = NORMALIZATION_FORMS.indexOf(form); | 195   var normalizationForm = NORMALIZATION_FORMS.indexOf(form); | 
| 190   if (normalizationForm === -1) { | 196   if (normalizationForm === -1) { | 
| 191     throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); | 197     throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); | 
| 192   } | 198   } | 
| 193 | 199 | 
| 194   return %_ValueOf(this); | 200   return %_ValueOf(this); | 
| 195 } | 201 } | 
| 196 | 202 | 
| 197 | 203 | 
| 198 // This has the same size as the $regexpLastMatchInfo array, and can be used | 204 // This has the same size as the RegExpLastMatchInfo array, and can be used | 
| 199 // for functions that expect that structure to be returned.  It is used when | 205 // for functions that expect that structure to be returned.  It is used when | 
| 200 // the needle is a string rather than a regexp.  In this case we can't update | 206 // the needle is a string rather than a regexp.  In this case we can't update | 
| 201 // lastMatchArray without erroneously affecting the properties on the global | 207 // lastMatchArray without erroneously affecting the properties on the global | 
| 202 // RegExp object. | 208 // RegExp object. | 
| 203 var reusableMatchInfo = [2, "", "", -1, -1]; | 209 var reusableMatchInfo = [2, "", "", -1, -1]; | 
| 204 | 210 | 
| 205 | 211 | 
| 206 // ECMA-262, section 15.5.4.11 | 212 // ECMA-262, section 15.5.4.11 | 
| 207 function StringReplace(search, replace) { | 213 function StringReplace(search, replace) { | 
| 208   CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); | 214   CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 230     // Emulate RegExp.prototype.exec's side effect in step 5, even if | 236     // Emulate RegExp.prototype.exec's side effect in step 5, even if | 
| 231     // value is discarded. | 237     // value is discarded. | 
| 232     var lastIndex = search.lastIndex; | 238     var lastIndex = search.lastIndex; | 
| 233     TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 239     TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 
| 234 | 240 | 
| 235     if (!IS_SPEC_FUNCTION(replace)) { | 241     if (!IS_SPEC_FUNCTION(replace)) { | 
| 236       replace = TO_STRING_INLINE(replace); | 242       replace = TO_STRING_INLINE(replace); | 
| 237 | 243 | 
| 238       if (!search.global) { | 244       if (!search.global) { | 
| 239         // Non-global regexp search, string replace. | 245         // Non-global regexp search, string replace. | 
| 240         var match = $regexpExec(search, subject, 0); | 246         var match = RegExpExec(search, subject, 0); | 
| 241         if (match == null) { | 247         if (match == null) { | 
| 242           search.lastIndex = 0 | 248           search.lastIndex = 0 | 
| 243           return subject; | 249           return subject; | 
| 244         } | 250         } | 
| 245         if (replace.length == 0) { | 251         if (replace.length == 0) { | 
| 246           return %_SubString(subject, 0, match[CAPTURE0]) + | 252           return %_SubString(subject, 0, match[CAPTURE0]) + | 
| 247                  %_SubString(subject, match[CAPTURE1], subject.length) | 253                  %_SubString(subject, match[CAPTURE1], subject.length) | 
| 248         } | 254         } | 
| 249         return ExpandReplacement(replace, subject, $regexpLastMatchInfo, | 255         return ExpandReplacement(replace, subject, RegExpLastMatchInfo, | 
| 250                                  %_SubString(subject, 0, match[CAPTURE0])) + | 256                                  %_SubString(subject, 0, match[CAPTURE0])) + | 
| 251                %_SubString(subject, match[CAPTURE1], subject.length); | 257                %_SubString(subject, match[CAPTURE1], subject.length); | 
| 252       } | 258       } | 
| 253 | 259 | 
| 254       // Global regexp search, string replace. | 260       // Global regexp search, string replace. | 
| 255       search.lastIndex = 0; | 261       search.lastIndex = 0; | 
| 256       if ($regexpLastMatchInfoOverride == null) { | 262       if ($regexpLastMatchInfoOverride == null) { | 
| 257         return %StringReplaceGlobalRegExpWithString( | 263         return %StringReplaceGlobalRegExpWithString( | 
| 258             subject, search, replace, $regexpLastMatchInfo); | 264             subject, search, replace, RegExpLastMatchInfo); | 
| 259       } else { | 265       } else { | 
| 260         // We use this hack to detect whether StringReplaceRegExpWithString | 266         // We use this hack to detect whether StringReplaceRegExpWithString | 
| 261         // found at least one hit. In that case we need to remove any | 267         // found at least one hit. In that case we need to remove any | 
| 262         // override. | 268         // override. | 
| 263         var saved_subject = $regexpLastMatchInfo[LAST_SUBJECT_INDEX]; | 269         var saved_subject = RegExpLastMatchInfo[LAST_SUBJECT_INDEX]; | 
| 264         $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = 0; | 270         RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = 0; | 
| 265         var answer = %StringReplaceGlobalRegExpWithString( | 271         var answer = %StringReplaceGlobalRegExpWithString( | 
| 266             subject, search, replace, $regexpLastMatchInfo); | 272             subject, search, replace, RegExpLastMatchInfo); | 
| 267         if (%_IsSmi($regexpLastMatchInfo[LAST_SUBJECT_INDEX])) { | 273         if (%_IsSmi(RegExpLastMatchInfo[LAST_SUBJECT_INDEX])) { | 
| 268           $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; | 274           RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; | 
| 269         } else { | 275         } else { | 
| 270           $regexpLastMatchInfoOverride = null; | 276           $regexpLastMatchInfoOverride = null; | 
| 271         } | 277         } | 
| 272         return answer; | 278         return answer; | 
| 273       } | 279       } | 
| 274     } | 280     } | 
| 275 | 281 | 
| 276     if (search.global) { | 282     if (search.global) { | 
| 277       // Global regexp search, function replace. | 283       // Global regexp search, function replace. | 
| 278       return StringReplaceGlobalRegExpWithFunction(subject, search, replace); | 284       return StringReplaceGlobalRegExpWithFunction(subject, search, replace); | 
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 424     reusableReplaceArray = null; | 430     reusableReplaceArray = null; | 
| 425   } else { | 431   } else { | 
| 426     // Inside a nested replace (replace called from the replacement function | 432     // Inside a nested replace (replace called from the replacement function | 
| 427     // of another replace) or we have failed to set the reusable array | 433     // of another replace) or we have failed to set the reusable array | 
| 428     // back due to an exception in a replacement function. Create a new | 434     // back due to an exception in a replacement function. Create a new | 
| 429     // array to use in the future, or until the original is written back. | 435     // array to use in the future, or until the original is written back. | 
| 430     resultArray = new InternalArray(16); | 436     resultArray = new InternalArray(16); | 
| 431   } | 437   } | 
| 432   var res = %RegExpExecMultiple(regexp, | 438   var res = %RegExpExecMultiple(regexp, | 
| 433                                 subject, | 439                                 subject, | 
| 434                                 $regexpLastMatchInfo, | 440                                 RegExpLastMatchInfo, | 
| 435                                 resultArray); | 441                                 resultArray); | 
| 436   regexp.lastIndex = 0; | 442   regexp.lastIndex = 0; | 
| 437   if (IS_NULL(res)) { | 443   if (IS_NULL(res)) { | 
| 438     // No matches at all. | 444     // No matches at all. | 
| 439     reusableReplaceArray = resultArray; | 445     reusableReplaceArray = resultArray; | 
| 440     return subject; | 446     return subject; | 
| 441   } | 447   } | 
| 442   var len = res.length; | 448   var len = res.length; | 
| 443   if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) { | 449   if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) { | 
| 444     // If the number of captures is two then there are no explicit captures in | 450     // If the number of captures is two then there are no explicit captures in | 
| 445     // the regexp, just the implicit capture that captures the whole match.  In | 451     // the regexp, just the implicit capture that captures the whole match.  In | 
| 446     // this case we can simplify quite a bit and end up with something faster. | 452     // this case we can simplify quite a bit and end up with something faster. | 
| 447     // The builder will consist of some integers that indicate slices of the | 453     // The builder will consist of some integers that indicate slices of the | 
| 448     // input string and some replacements that were returned from the replace | 454     // input string and some replacements that were returned from the replace | 
| 449     // function. | 455     // function. | 
| 450     var match_start = 0; | 456     var match_start = 0; | 
| 451     var override = new InternalPackedArray(null, 0, subject); | 457     var override = new InternalPackedArray(null, 0, subject); | 
| 452     for (var i = 0; i < len; i++) { | 458     for (var i = 0; i < len; i++) { | 
| 453       var elem = res[i]; | 459       var elem = res[i]; | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 487     } | 493     } | 
| 488   } | 494   } | 
| 489   var result = %StringBuilderConcat(res, res.length, subject); | 495   var result = %StringBuilderConcat(res, res.length, subject); | 
| 490   resultArray.length = 0; | 496   resultArray.length = 0; | 
| 491   reusableReplaceArray = resultArray; | 497   reusableReplaceArray = resultArray; | 
| 492   return result; | 498   return result; | 
| 493 } | 499 } | 
| 494 | 500 | 
| 495 | 501 | 
| 496 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { | 502 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { | 
| 497   var matchInfo = $regexpExec(regexp, subject, 0); | 503   var matchInfo = RegExpExec(regexp, subject, 0); | 
| 498   if (IS_NULL(matchInfo)) { | 504   if (IS_NULL(matchInfo)) { | 
| 499     regexp.lastIndex = 0; | 505     regexp.lastIndex = 0; | 
| 500     return subject; | 506     return subject; | 
| 501   } | 507   } | 
| 502   var index = matchInfo[CAPTURE0]; | 508   var index = matchInfo[CAPTURE0]; | 
| 503   var result = %_SubString(subject, 0, index); | 509   var result = %_SubString(subject, 0, index); | 
| 504   var endOfMatch = matchInfo[CAPTURE1]; | 510   var endOfMatch = matchInfo[CAPTURE1]; | 
| 505   // Compute the parameter list consisting of the match, captures, index, | 511   // Compute the parameter list consisting of the match, captures, index, | 
| 506   // and subject for the replace function invocation. | 512   // and subject for the replace function invocation. | 
| 507   // The number of captures plus one for the match. | 513   // The number of captures plus one for the match. | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 535   CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); | 541   CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); | 
| 536 | 542 | 
| 537   var regexp; | 543   var regexp; | 
| 538   if (IS_STRING(re)) { | 544   if (IS_STRING(re)) { | 
| 539     regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); | 545     regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); | 
| 540   } else if (IS_REGEXP(re)) { | 546   } else if (IS_REGEXP(re)) { | 
| 541     regexp = re; | 547     regexp = re; | 
| 542   } else { | 548   } else { | 
| 543     regexp = new GlobalRegExp(re); | 549     regexp = new GlobalRegExp(re); | 
| 544   } | 550   } | 
| 545   var match = $regexpExec(regexp, TO_STRING_INLINE(this), 0); | 551   var match = RegExpExec(regexp, TO_STRING_INLINE(this), 0); | 
| 546   if (match) { | 552   if (match) { | 
| 547     return match[CAPTURE0]; | 553     return match[CAPTURE0]; | 
| 548   } | 554   } | 
| 549   return -1; | 555   return -1; | 
| 550 } | 556 } | 
| 551 | 557 | 
| 552 | 558 | 
| 553 // ECMA-262 section 15.5.4.13 | 559 // ECMA-262 section 15.5.4.13 | 
| 554 function StringSlice(start, end) { | 560 function StringSlice(start, end) { | 
| 555   CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice"); | 561   CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice"); | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 621 | 627 | 
| 622   if (limit === 0) return []; | 628   if (limit === 0) return []; | 
| 623 | 629 | 
| 624   // Separator is a regular expression. | 630   // Separator is a regular expression. | 
| 625   return StringSplitOnRegExp(subject, separator, limit, length); | 631   return StringSplitOnRegExp(subject, separator, limit, length); | 
| 626 } | 632 } | 
| 627 | 633 | 
| 628 | 634 | 
| 629 function StringSplitOnRegExp(subject, separator, limit, length) { | 635 function StringSplitOnRegExp(subject, separator, limit, length) { | 
| 630   if (length === 0) { | 636   if (length === 0) { | 
| 631     if ($regexpExec(separator, subject, 0, 0) != null) { | 637     if (RegExpExec(separator, subject, 0, 0) != null) { | 
| 632       return []; | 638       return []; | 
| 633     } | 639     } | 
| 634     return [subject]; | 640     return [subject]; | 
| 635   } | 641   } | 
| 636 | 642 | 
| 637   var currentIndex = 0; | 643   var currentIndex = 0; | 
| 638   var startIndex = 0; | 644   var startIndex = 0; | 
| 639   var startMatch = 0; | 645   var startMatch = 0; | 
| 640   var result = new InternalArray(); | 646   var result = new InternalArray(); | 
| 641 | 647 | 
| 642   outer_loop: | 648   outer_loop: | 
| 643   while (true) { | 649   while (true) { | 
| 644 | 650 | 
| 645     if (startIndex === length) { | 651     if (startIndex === length) { | 
| 646       result[result.length] = %_SubString(subject, currentIndex, length); | 652       result[result.length] = %_SubString(subject, currentIndex, length); | 
| 647       break; | 653       break; | 
| 648     } | 654     } | 
| 649 | 655 | 
| 650     var matchInfo = $regexpExec(separator, subject, startIndex); | 656     var matchInfo = RegExpExec(separator, subject, startIndex); | 
| 651     if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { | 657     if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { | 
| 652       result[result.length] = %_SubString(subject, currentIndex, length); | 658       result[result.length] = %_SubString(subject, currentIndex, length); | 
| 653       break; | 659       break; | 
| 654     } | 660     } | 
| 655     var endIndex = matchInfo[CAPTURE1]; | 661     var endIndex = matchInfo[CAPTURE1]; | 
| 656 | 662 | 
| 657     // We ignore a zero-length match at the currentIndex. | 663     // We ignore a zero-length match at the currentIndex. | 
| 658     if (startIndex === endIndex && endIndex === currentIndex) { | 664     if (startIndex === endIndex && endIndex === currentIndex) { | 
| 659       startIndex++; | 665       startIndex++; | 
| 660       continue; | 666       continue; | 
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1117 | 1123 | 
| 1118 // Set the String function and constructor. | 1124 // Set the String function and constructor. | 
| 1119 %SetCode(GlobalString, StringConstructor); | 1125 %SetCode(GlobalString, StringConstructor); | 
| 1120 %FunctionSetPrototype(GlobalString, new GlobalString()); | 1126 %FunctionSetPrototype(GlobalString, new GlobalString()); | 
| 1121 | 1127 | 
| 1122 // Set up the constructor property on the String prototype object. | 1128 // Set up the constructor property on the String prototype object. | 
| 1123 %AddNamedProperty( | 1129 %AddNamedProperty( | 
| 1124     GlobalString.prototype, "constructor", GlobalString, DONT_ENUM); | 1130     GlobalString.prototype, "constructor", GlobalString, DONT_ENUM); | 
| 1125 | 1131 | 
| 1126 // Set up the non-enumerable functions on the String object. | 1132 // Set up the non-enumerable functions on the String object. | 
| 1127 $installFunctions(GlobalString, DONT_ENUM, [ | 1133 utils.InstallFunctions(GlobalString, DONT_ENUM, [ | 
| 1128   "fromCharCode", StringFromCharCode, | 1134   "fromCharCode", StringFromCharCode, | 
| 1129   "fromCodePoint", StringFromCodePoint, | 1135   "fromCodePoint", StringFromCodePoint, | 
| 1130   "raw", StringRaw | 1136   "raw", StringRaw | 
| 1131 ]); | 1137 ]); | 
| 1132 | 1138 | 
| 1133 // Set up the non-enumerable functions on the String prototype object. | 1139 // Set up the non-enumerable functions on the String prototype object. | 
| 1134 $installFunctions(GlobalString.prototype, DONT_ENUM, [ | 1140 utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [ | 
| 1135   "valueOf", StringValueOf, | 1141   "valueOf", StringValueOf, | 
| 1136   "toString", StringToString, | 1142   "toString", StringToString, | 
| 1137   "charAt", StringCharAtJS, | 1143   "charAt", StringCharAtJS, | 
| 1138   "charCodeAt", StringCharCodeAtJS, | 1144   "charCodeAt", StringCharCodeAtJS, | 
| 1139   "codePointAt", StringCodePointAt, | 1145   "codePointAt", StringCodePointAt, | 
| 1140   "concat", StringConcat, | 1146   "concat", StringConcat, | 
| 1141   "endsWith", StringEndsWith, | 1147   "endsWith", StringEndsWith, | 
| 1142   "includes", StringIncludes, | 1148   "includes", StringIncludes, | 
| 1143   "indexOf", StringIndexOfJS, | 1149   "indexOf", StringIndexOfJS, | 
| 1144   "lastIndexOf", StringLastIndexOfJS, | 1150   "lastIndexOf", StringLastIndexOfJS, | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1179 // ------------------------------------------------------------------- | 1185 // ------------------------------------------------------------------- | 
| 1180 // Exports | 1186 // Exports | 
| 1181 | 1187 | 
| 1182 utils.Export(function(to) { | 1188 utils.Export(function(to) { | 
| 1183   to.StringCharAt = StringCharAtJS; | 1189   to.StringCharAt = StringCharAtJS; | 
| 1184   to.StringIndexOf = StringIndexOfJS; | 1190   to.StringIndexOf = StringIndexOfJS; | 
| 1185   to.StringSubstring = StringSubstring; | 1191   to.StringSubstring = StringSubstring; | 
| 1186 }); | 1192 }); | 
| 1187 | 1193 | 
| 1188 }) | 1194 }) | 
| OLD | NEW | 
|---|