| 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 var $stringCharAt; | 5 var $stringCharAt; |
| 6 var $stringIndexOf; | 6 var $stringIndexOf; |
| 7 var $stringSubstring; | 7 var $stringSubstring; |
| 8 | 8 |
| 9 (function() { | 9 (function() { |
| 10 | 10 |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 return %StringReplaceOneCharWithString(subject, search, replace); | 284 return %StringReplaceOneCharWithString(subject, search, replace); |
| 285 } | 285 } |
| 286 var start = %StringIndexOf(subject, search, 0); | 286 var start = %StringIndexOf(subject, search, 0); |
| 287 if (start < 0) return subject; | 287 if (start < 0) return subject; |
| 288 var end = start + search.length; | 288 var end = start + search.length; |
| 289 | 289 |
| 290 var result = %_SubString(subject, 0, start); | 290 var result = %_SubString(subject, 0, start); |
| 291 | 291 |
| 292 // Compute the string to replace with. | 292 // Compute the string to replace with. |
| 293 if (IS_SPEC_FUNCTION(replace)) { | 293 if (IS_SPEC_FUNCTION(replace)) { |
| 294 var receiver = %GetDefaultReceiver(replace); | 294 var receiver = UNDEFINED; |
| 295 result += %_CallFunction(receiver, search, start, subject, replace); | 295 result += %_CallFunction(receiver, search, start, subject, replace); |
| 296 } else { | 296 } else { |
| 297 reusableMatchInfo[CAPTURE0] = start; | 297 reusableMatchInfo[CAPTURE0] = start; |
| 298 reusableMatchInfo[CAPTURE1] = end; | 298 reusableMatchInfo[CAPTURE1] = end; |
| 299 result = ExpandReplacement(TO_STRING_INLINE(replace), | 299 result = ExpandReplacement(TO_STRING_INLINE(replace), |
| 300 subject, | 300 subject, |
| 301 reusableMatchInfo, | 301 reusableMatchInfo, |
| 302 result); | 302 result); |
| 303 } | 303 } |
| 304 | 304 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 var len = res.length; | 433 var len = res.length; |
| 434 if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) { | 434 if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) { |
| 435 // If the number of captures is two then there are no explicit captures in | 435 // If the number of captures is two then there are no explicit captures in |
| 436 // the regexp, just the implicit capture that captures the whole match. In | 436 // the regexp, just the implicit capture that captures the whole match. In |
| 437 // this case we can simplify quite a bit and end up with something faster. | 437 // this case we can simplify quite a bit and end up with something faster. |
| 438 // The builder will consist of some integers that indicate slices of the | 438 // The builder will consist of some integers that indicate slices of the |
| 439 // input string and some replacements that were returned from the replace | 439 // input string and some replacements that were returned from the replace |
| 440 // function. | 440 // function. |
| 441 var match_start = 0; | 441 var match_start = 0; |
| 442 var override = new InternalPackedArray(null, 0, subject); | 442 var override = new InternalPackedArray(null, 0, subject); |
| 443 var receiver = %GetDefaultReceiver(replace); | |
| 444 for (var i = 0; i < len; i++) { | 443 for (var i = 0; i < len; i++) { |
| 445 var elem = res[i]; | 444 var elem = res[i]; |
| 446 if (%_IsSmi(elem)) { | 445 if (%_IsSmi(elem)) { |
| 447 // Integers represent slices of the original string. Use these to | 446 // Integers represent slices of the original string. Use these to |
| 448 // get the offsets we need for the override array (so things like | 447 // get the offsets we need for the override array (so things like |
| 449 // RegExp.leftContext work during the callback function. | 448 // RegExp.leftContext work during the callback function. |
| 450 if (elem > 0) { | 449 if (elem > 0) { |
| 451 match_start = (elem >> 11) + (elem & 0x7ff); | 450 match_start = (elem >> 11) + (elem & 0x7ff); |
| 452 } else { | 451 } else { |
| 453 match_start = res[++i] - elem; | 452 match_start = res[++i] - elem; |
| 454 } | 453 } |
| 455 } else { | 454 } else { |
| 456 override[0] = elem; | 455 override[0] = elem; |
| 457 override[1] = match_start; | 456 override[1] = match_start; |
| 458 $regexpLastMatchInfoOverride = override; | 457 $regexpLastMatchInfoOverride = override; |
| 459 var func_result = | 458 var func_result = |
| 460 %_CallFunction(receiver, elem, match_start, subject, replace); | 459 %_CallFunction(UNDEFINED, elem, match_start, subject, replace); |
| 461 // Overwrite the i'th element in the results with the string we got | 460 // Overwrite the i'th element in the results with the string we got |
| 462 // back from the callback function. | 461 // back from the callback function. |
| 463 res[i] = TO_STRING_INLINE(func_result); | 462 res[i] = TO_STRING_INLINE(func_result); |
| 464 match_start += elem.length; | 463 match_start += elem.length; |
| 465 } | 464 } |
| 466 } | 465 } |
| 467 } else { | 466 } else { |
| 468 var receiver = %GetDefaultReceiver(replace); | |
| 469 for (var i = 0; i < len; i++) { | 467 for (var i = 0; i < len; i++) { |
| 470 var elem = res[i]; | 468 var elem = res[i]; |
| 471 if (!%_IsSmi(elem)) { | 469 if (!%_IsSmi(elem)) { |
| 472 // elem must be an Array. | 470 // elem must be an Array. |
| 473 // Use the apply argument as backing for global RegExp properties. | 471 // Use the apply argument as backing for global RegExp properties. |
| 474 $regexpLastMatchInfoOverride = elem; | 472 $regexpLastMatchInfoOverride = elem; |
| 475 var func_result = %Apply(replace, receiver, elem, 0, elem.length); | 473 var func_result = %Apply(replace, UNDEFINED, elem, 0, elem.length); |
| 476 // Overwrite the i'th element in the results with the string we got | 474 // Overwrite the i'th element in the results with the string we got |
| 477 // back from the callback function. | 475 // back from the callback function. |
| 478 res[i] = TO_STRING_INLINE(func_result); | 476 res[i] = TO_STRING_INLINE(func_result); |
| 479 } | 477 } |
| 480 } | 478 } |
| 481 } | 479 } |
| 482 var result = %StringBuilderConcat(res, res.length, subject); | 480 var result = %StringBuilderConcat(res, res.length, subject); |
| 483 resultArray.length = 0; | 481 resultArray.length = 0; |
| 484 reusableReplaceArray = resultArray; | 482 reusableReplaceArray = resultArray; |
| 485 return result; | 483 return result; |
| 486 } | 484 } |
| 487 | 485 |
| 488 | 486 |
| 489 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { | 487 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { |
| 490 var matchInfo = $regexpExec(regexp, subject, 0); | 488 var matchInfo = $regexpExec(regexp, subject, 0); |
| 491 if (IS_NULL(matchInfo)) { | 489 if (IS_NULL(matchInfo)) { |
| 492 regexp.lastIndex = 0; | 490 regexp.lastIndex = 0; |
| 493 return subject; | 491 return subject; |
| 494 } | 492 } |
| 495 var index = matchInfo[CAPTURE0]; | 493 var index = matchInfo[CAPTURE0]; |
| 496 var result = %_SubString(subject, 0, index); | 494 var result = %_SubString(subject, 0, index); |
| 497 var endOfMatch = matchInfo[CAPTURE1]; | 495 var endOfMatch = matchInfo[CAPTURE1]; |
| 498 // Compute the parameter list consisting of the match, captures, index, | 496 // Compute the parameter list consisting of the match, captures, index, |
| 499 // and subject for the replace function invocation. | 497 // and subject for the replace function invocation. |
| 500 // The number of captures plus one for the match. | 498 // The number of captures plus one for the match. |
| 501 var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; | 499 var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; |
| 502 var replacement; | 500 var replacement; |
| 503 var receiver = %GetDefaultReceiver(replace); | |
| 504 if (m == 1) { | 501 if (m == 1) { |
| 505 // No captures, only the match, which is always valid. | 502 // No captures, only the match, which is always valid. |
| 506 var s = %_SubString(subject, index, endOfMatch); | 503 var s = %_SubString(subject, index, endOfMatch); |
| 507 // Don't call directly to avoid exposing the built-in global object. | 504 // Don't call directly to avoid exposing the built-in global object. |
| 508 replacement = %_CallFunction(receiver, s, index, subject, replace); | 505 replacement = %_CallFunction(UNDEFINED, s, index, subject, replace); |
| 509 } else { | 506 } else { |
| 510 var parameters = new InternalArray(m + 2); | 507 var parameters = new InternalArray(m + 2); |
| 511 for (var j = 0; j < m; j++) { | 508 for (var j = 0; j < m; j++) { |
| 512 parameters[j] = CaptureString(subject, matchInfo, j); | 509 parameters[j] = CaptureString(subject, matchInfo, j); |
| 513 } | 510 } |
| 514 parameters[j] = index; | 511 parameters[j] = index; |
| 515 parameters[j + 1] = subject; | 512 parameters[j + 1] = subject; |
| 516 | 513 |
| 517 replacement = %Apply(replace, receiver, parameters, 0, j + 2); | 514 replacement = %Apply(replace, UNDEFINED, parameters, 0, j + 2); |
| 518 } | 515 } |
| 519 | 516 |
| 520 result += replacement; // The add method converts to string if necessary. | 517 result += replacement; // The add method converts to string if necessary. |
| 521 // Can't use matchInfo any more from here, since the function could | 518 // Can't use matchInfo any more from here, since the function could |
| 522 // overwrite it. | 519 // overwrite it. |
| 523 return result + %_SubString(subject, endOfMatch, subject.length); | 520 return result + %_SubString(subject, endOfMatch, subject.length); |
| 524 } | 521 } |
| 525 | 522 |
| 526 | 523 |
| 527 // ECMA-262 section 15.5.4.12 | 524 // ECMA-262 section 15.5.4.12 |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 "strike", StringStrike, | 1165 "strike", StringStrike, |
| 1169 "sub", StringSub, | 1166 "sub", StringSub, |
| 1170 "sup", StringSup | 1167 "sup", StringSup |
| 1171 ]); | 1168 ]); |
| 1172 | 1169 |
| 1173 $stringCharAt = StringCharAtJS; | 1170 $stringCharAt = StringCharAtJS; |
| 1174 $stringIndexOf = StringIndexOfJS; | 1171 $stringIndexOf = StringIndexOfJS; |
| 1175 $stringSubstring = StringSubstring; | 1172 $stringSubstring = StringSubstring; |
| 1176 | 1173 |
| 1177 })(); | 1174 })(); |
| OLD | NEW |