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 |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 end_i = start_i; | 440 end_i = start_i; |
441 start_i = tmp; | 441 start_i = tmp; |
442 } | 442 } |
443 } | 443 } |
444 } | 444 } |
445 | 445 |
446 return %_SubString(s, start_i, end_i); | 446 return %_SubString(s, start_i, end_i); |
447 } | 447 } |
448 | 448 |
449 | 449 |
450 // ES6 draft, revision 26 (2014-07-18), section B.2.3.1 | 450 // ecma262/#sec-string.prototype.substr |
451 function StringSubstr(start, n) { | 451 function StringSubstr(start, length) { |
452 CHECK_OBJECT_COERCIBLE(this, "String.prototype.substr"); | 452 CHECK_OBJECT_COERCIBLE(this, "String.prototype.substr"); |
| 453 var s = TO_STRING(this); |
| 454 var size = s.length; |
| 455 start = TO_INTEGER(start); |
| 456 length = IS_UNDEFINED(length) ? size : TO_INTEGER(length); |
453 | 457 |
454 var s = TO_STRING(this); | 458 if (start < 0) start = MaxSimple(size + start, 0); |
455 var len; | 459 length = MinSimple(MaxSimple(length, 0), size - start); |
456 | 460 |
457 // Correct n: If not given, set to string length; if explicitly | 461 if (length <= 0) return ''; |
458 // set to undefined, zero, or negative, returns empty string. | 462 return %_SubString(s, start, start + length); |
459 if (IS_UNDEFINED(n)) { | |
460 len = s.length; | |
461 } else { | |
462 len = TO_INTEGER(n); | |
463 if (len <= 0) return ''; | |
464 } | |
465 | |
466 // Correct start: If not given (or undefined), set to zero; otherwise | |
467 // convert to integer and handle negative case. | |
468 if (IS_UNDEFINED(start)) { | |
469 start = 0; | |
470 } else { | |
471 start = TO_INTEGER(start); | |
472 // If positive, and greater than or equal to the string length, | |
473 // return empty string. | |
474 if (start >= s.length) return ''; | |
475 // If negative and absolute value is larger than the string length, | |
476 // use zero. | |
477 if (start < 0) { | |
478 start += s.length; | |
479 if (start < 0) start = 0; | |
480 } | |
481 } | |
482 | |
483 var end = start + len; | |
484 if (end > s.length) end = s.length; | |
485 | |
486 return %_SubString(s, start, end); | |
487 } | 463 } |
488 | 464 |
489 | 465 |
490 // ECMA-262, 15.5.4.16 | 466 // ECMA-262, 15.5.4.16 |
491 function StringToLowerCaseJS() { | 467 function StringToLowerCaseJS() { |
492 CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase"); | 468 CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase"); |
493 | 469 |
494 return %StringToLowerCase(TO_STRING(this)); | 470 return %StringToLowerCase(TO_STRING(this)); |
495 } | 471 } |
496 | 472 |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 to.StringLastIndexOf = StringLastIndexOf; | 804 to.StringLastIndexOf = StringLastIndexOf; |
829 to.StringMatch = StringMatchJS; | 805 to.StringMatch = StringMatchJS; |
830 to.StringReplace = StringReplace; | 806 to.StringReplace = StringReplace; |
831 to.StringSlice = StringSlice; | 807 to.StringSlice = StringSlice; |
832 to.StringSplit = StringSplitJS; | 808 to.StringSplit = StringSplitJS; |
833 to.StringSubstr = StringSubstr; | 809 to.StringSubstr = StringSubstr; |
834 to.StringSubstring = StringSubstring; | 810 to.StringSubstring = StringSubstring; |
835 }); | 811 }); |
836 | 812 |
837 }) | 813 }) |
OLD | NEW |