| 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 ArrayIndexOf; | 12 var ArrayIndexOf; |
| 13 var ArrayJoin; | 13 var ArrayJoin; |
| 14 var GlobalRegExp = global.RegExp; | 14 var GlobalRegExp = global.RegExp; |
| 15 var GlobalString = global.String; | 15 var GlobalString = global.String; |
| 16 var InternalArray = utils.InternalArray; | 16 var InternalArray = utils.InternalArray; |
| 17 var InternalPackedArray = utils.InternalPackedArray; | 17 var InternalPackedArray = utils.InternalPackedArray; |
| 18 var MakeRangeError; | 18 var MakeRangeError; |
| 19 var MakeTypeError; | 19 var MakeTypeError; |
| 20 var RegExpExec; | 20 var RegExpExec; |
| 21 var RegExpExecNoTests; | 21 var RegExpExecNoTests; |
| 22 var RegExpLastMatchInfo; | 22 var RegExpLastMatchInfo; |
| 23 var splitSymbol = utils.ImportNow("split_symbol"); |
| 23 | 24 |
| 24 utils.Import(function(from) { | 25 utils.Import(function(from) { |
| 25 ArrayIndexOf = from.ArrayIndexOf; | 26 ArrayIndexOf = from.ArrayIndexOf; |
| 26 ArrayJoin = from.ArrayJoin; | 27 ArrayJoin = from.ArrayJoin; |
| 27 MakeRangeError = from.MakeRangeError; | 28 MakeRangeError = from.MakeRangeError; |
| 28 MakeTypeError = from.MakeTypeError; | 29 MakeTypeError = from.MakeTypeError; |
| 29 RegExpExec = from.RegExpExec; | 30 RegExpExec = from.RegExpExec; |
| 30 RegExpExecNoTests = from.RegExpExecNoTests; | 31 RegExpExecNoTests = from.RegExpExecNoTests; |
| 31 RegExpLastMatchInfo = from.RegExpLastMatchInfo; | 32 RegExpLastMatchInfo = from.RegExpLastMatchInfo; |
| 32 }); | 33 }); |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 } | 549 } |
| 549 | 550 |
| 550 if (end_i <= start_i) { | 551 if (end_i <= start_i) { |
| 551 return ''; | 552 return ''; |
| 552 } | 553 } |
| 553 | 554 |
| 554 return %_SubString(s, start_i, end_i); | 555 return %_SubString(s, start_i, end_i); |
| 555 } | 556 } |
| 556 | 557 |
| 557 | 558 |
| 558 // ECMA-262 section 15.5.4.14 | 559 // ES6 21.1.3.17. |
| 559 function StringSplitJS(separator, limit) { | 560 function StringSplitJS(separator, limit) { |
| 560 CHECK_OBJECT_COERCIBLE(this, "String.prototype.split"); | 561 CHECK_OBJECT_COERCIBLE(this, "String.prototype.split"); |
| 561 | 562 |
| 563 if (!IS_NULL_OR_UNDEFINED(separator)) { |
| 564 var splitter = separator[splitSymbol]; |
| 565 if (!IS_UNDEFINED(splitter)) { |
| 566 if (!IS_CALLABLE(splitter)) { |
| 567 throw MakeTypeError(kCalledNonCallable, splitter); |
| 568 } |
| 569 return %_Call(splitter, separator, this, limit); |
| 570 } |
| 571 } |
| 572 |
| 562 var subject = TO_STRING(this); | 573 var subject = TO_STRING(this); |
| 563 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit); | 574 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit); |
| 564 | 575 |
| 565 var length = subject.length; | 576 var length = subject.length; |
| 566 if (!IS_REGEXP(separator)) { | 577 var separator_string = TO_STRING(separator); |
| 567 var separator_string = TO_STRING(separator); | |
| 568 | |
| 569 if (limit === 0) return []; | |
| 570 | |
| 571 // ECMA-262 says that if separator is undefined, the result should | |
| 572 // be an array of size 1 containing the entire string. | |
| 573 if (IS_UNDEFINED(separator)) return [subject]; | |
| 574 | |
| 575 var separator_length = separator_string.length; | |
| 576 | |
| 577 // If the separator string is empty then return the elements in the subject. | |
| 578 if (separator_length === 0) return %StringToArray(subject, limit); | |
| 579 | |
| 580 var result = %StringSplit(subject, separator_string, limit); | |
| 581 | |
| 582 return result; | |
| 583 } | |
| 584 | 578 |
| 585 if (limit === 0) return []; | 579 if (limit === 0) return []; |
| 586 | 580 |
| 587 // Separator is a regular expression. | 581 // ECMA-262 says that if separator is undefined, the result should |
| 588 return StringSplitOnRegExp(subject, separator, limit, length); | 582 // be an array of size 1 containing the entire string. |
| 583 if (IS_UNDEFINED(separator)) return [subject]; |
| 584 |
| 585 var separator_length = separator_string.length; |
| 586 |
| 587 // If the separator string is empty then return the elements in the subject. |
| 588 if (separator_length === 0) return %StringToArray(subject, limit); |
| 589 |
| 590 return %StringSplit(subject, separator_string, limit); |
| 589 } | 591 } |
| 590 | 592 |
| 591 | 593 |
| 592 function StringSplitOnRegExp(subject, separator, limit, length) { | |
| 593 if (length === 0) { | |
| 594 if (RegExpExec(separator, subject, 0, 0) != null) { | |
| 595 return []; | |
| 596 } | |
| 597 return [subject]; | |
| 598 } | |
| 599 | |
| 600 var currentIndex = 0; | |
| 601 var startIndex = 0; | |
| 602 var startMatch = 0; | |
| 603 var result = new InternalArray(); | |
| 604 | |
| 605 outer_loop: | |
| 606 while (true) { | |
| 607 | |
| 608 if (startIndex === length) { | |
| 609 result[result.length] = %_SubString(subject, currentIndex, length); | |
| 610 break; | |
| 611 } | |
| 612 | |
| 613 var matchInfo = RegExpExec(separator, subject, startIndex); | |
| 614 if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { | |
| 615 result[result.length] = %_SubString(subject, currentIndex, length); | |
| 616 break; | |
| 617 } | |
| 618 var endIndex = matchInfo[CAPTURE1]; | |
| 619 | |
| 620 // We ignore a zero-length match at the currentIndex. | |
| 621 if (startIndex === endIndex && endIndex === currentIndex) { | |
| 622 startIndex++; | |
| 623 continue; | |
| 624 } | |
| 625 | |
| 626 result[result.length] = %_SubString(subject, currentIndex, startMatch); | |
| 627 | |
| 628 if (result.length === limit) break; | |
| 629 | |
| 630 var matchinfo_len = NUMBER_OF_CAPTURES(matchInfo) + REGEXP_FIRST_CAPTURE; | |
| 631 for (var i = REGEXP_FIRST_CAPTURE + 2; i < matchinfo_len; ) { | |
| 632 var start = matchInfo[i++]; | |
| 633 var end = matchInfo[i++]; | |
| 634 if (end != -1) { | |
| 635 result[result.length] = %_SubString(subject, start, end); | |
| 636 } else { | |
| 637 result[result.length] = UNDEFINED; | |
| 638 } | |
| 639 if (result.length === limit) break outer_loop; | |
| 640 } | |
| 641 | |
| 642 startIndex = currentIndex = endIndex; | |
| 643 } | |
| 644 var array_result = []; | |
| 645 %MoveArrayContents(result, array_result); | |
| 646 return array_result; | |
| 647 } | |
| 648 | |
| 649 | |
| 650 // ECMA-262 section 15.5.4.15 | 594 // ECMA-262 section 15.5.4.15 |
| 651 function StringSubstring(start, end) { | 595 function StringSubstring(start, end) { |
| 652 CHECK_OBJECT_COERCIBLE(this, "String.prototype.subString"); | 596 CHECK_OBJECT_COERCIBLE(this, "String.prototype.subString"); |
| 653 | 597 |
| 654 var s = TO_STRING(this); | 598 var s = TO_STRING(this); |
| 655 var s_len = s.length; | 599 var s_len = s.length; |
| 656 | 600 |
| 657 var start_i = TO_INTEGER(start); | 601 var start_i = TO_INTEGER(start); |
| 658 if (start_i < 0) { | 602 if (start_i < 0) { |
| 659 start_i = 0; | 603 start_i = 0; |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 to.StringLastIndexOf = StringLastIndexOfJS; | 1114 to.StringLastIndexOf = StringLastIndexOfJS; |
| 1171 to.StringMatch = StringMatchJS; | 1115 to.StringMatch = StringMatchJS; |
| 1172 to.StringReplace = StringReplace; | 1116 to.StringReplace = StringReplace; |
| 1173 to.StringSlice = StringSlice; | 1117 to.StringSlice = StringSlice; |
| 1174 to.StringSplit = StringSplitJS; | 1118 to.StringSplit = StringSplitJS; |
| 1175 to.StringSubstr = StringSubstr; | 1119 to.StringSubstr = StringSubstr; |
| 1176 to.StringSubstring = StringSubstring; | 1120 to.StringSubstring = StringSubstring; |
| 1177 }); | 1121 }); |
| 1178 | 1122 |
| 1179 }) | 1123 }) |
| OLD | NEW |