Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: src/string.js

Issue 6902104: Don't exchange null and undefined with the global object in function.prototype.{call, apply} for ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // ECMA-262 section 15.5.4.3 55 // ECMA-262 section 15.5.4.3
56 function StringValueOf() { 56 function StringValueOf() {
57 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) 57 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this))
58 throw new $TypeError('String.prototype.valueOf is not generic'); 58 throw new $TypeError('String.prototype.valueOf is not generic');
59 return %_ValueOf(this); 59 return %_ValueOf(this);
60 } 60 }
61 61
62 62
63 // ECMA-262, section 15.5.4.4 63 // ECMA-262, section 15.5.4.4
64 function StringCharAt(pos) { 64 function StringCharAt(pos) {
65 if (IS_NULL_OR_UNDEFINED(this)) {
66 throw MakeTypeError("obj_ctor_property_non_object", ["charAt"]);
Lasse Reichstein 2011/04/28 10:44:38 Why "Array.some" but not "String.charAt"?
Rico 2011/05/03 08:47:20 Done.
67 }
65 var result = %_StringCharAt(this, pos); 68 var result = %_StringCharAt(this, pos);
66 if (%_IsSmi(result)) { 69 if (%_IsSmi(result)) {
67 result = %_StringCharAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); 70 result = %_StringCharAt(TO_STRING_INLINE(this), TO_INTEGER(pos));
68 } 71 }
69 return result; 72 return result;
70 } 73 }
71 74
72 75
73 // ECMA-262 section 15.5.4.5 76 // ECMA-262 section 15.5.4.5
74 function StringCharCodeAt(pos) { 77 function StringCharCodeAt(pos) {
78 if (IS_NULL_OR_UNDEFINED(this)) {
79 throw MakeTypeError("obj_ctor_property_non_object", ["charCodeAt"]);
80 }
75 var result = %_StringCharCodeAt(this, pos); 81 var result = %_StringCharCodeAt(this, pos);
76 if (!%_IsSmi(result)) { 82 if (!%_IsSmi(result)) {
77 result = %_StringCharCodeAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); 83 result = %_StringCharCodeAt(TO_STRING_INLINE(this), TO_INTEGER(pos));
78 } 84 }
79 return result; 85 return result;
80 } 86 }
81 87
82 88
83 // ECMA-262, section 15.5.4.6 89 // ECMA-262, section 15.5.4.6
84 function StringConcat() { 90 function StringConcat() {
91 if (IS_NULL_OR_UNDEFINED(this)) {
92 throw MakeTypeError("obj_ctor_property_non_object", ["concat"]);
93 }
85 var len = %_ArgumentsLength(); 94 var len = %_ArgumentsLength();
86 var this_as_string = TO_STRING_INLINE(this); 95 var this_as_string = TO_STRING_INLINE(this);
87 if (len === 1) { 96 if (len === 1) {
88 return this_as_string + %_Arguments(0); 97 return this_as_string + %_Arguments(0);
89 } 98 }
90 var parts = new InternalArray(len + 1); 99 var parts = new InternalArray(len + 1);
91 parts[0] = this_as_string; 100 parts[0] = this_as_string;
92 for (var i = 0; i < len; i++) { 101 for (var i = 0; i < len; i++) {
93 var part = %_Arguments(i); 102 var part = %_Arguments(i);
94 parts[i + 1] = TO_STRING_INLINE(part); 103 parts[i + 1] = TO_STRING_INLINE(part);
95 } 104 }
96 return %StringBuilderConcat(parts, len + 1, ""); 105 return %StringBuilderConcat(parts, len + 1, "");
97 } 106 }
98 107
99 // Match ES3 and Safari 108 // Match ES3 and Safari
100 %FunctionSetLength(StringConcat, 1); 109 %FunctionSetLength(StringConcat, 1);
101 110
102 111
103 // ECMA-262 section 15.5.4.7 112 // ECMA-262 section 15.5.4.7
104 function StringIndexOf(pattern /* position */) { // length == 1 113 function StringIndexOf(pattern /* position */) { // length == 1
114 if (IS_NULL_OR_UNDEFINED(this)) {
115 throw MakeTypeError("obj_ctor_property_non_object", ["indexOf"]);
116 }
105 var subject = TO_STRING_INLINE(this); 117 var subject = TO_STRING_INLINE(this);
106 pattern = TO_STRING_INLINE(pattern); 118 pattern = TO_STRING_INLINE(pattern);
107 var index = 0; 119 var index = 0;
108 if (%_ArgumentsLength() > 1) { 120 if (%_ArgumentsLength() > 1) {
109 index = %_Arguments(1); // position 121 index = %_Arguments(1); // position
110 index = TO_INTEGER(index); 122 index = TO_INTEGER(index);
111 if (index < 0) index = 0; 123 if (index < 0) index = 0;
112 if (index > subject.length) index = subject.length; 124 if (index > subject.length) index = subject.length;
113 } 125 }
114 return %StringIndexOf(subject, pattern, index); 126 return %StringIndexOf(subject, pattern, index);
115 } 127 }
116 128
117 129
118 // ECMA-262 section 15.5.4.8 130 // ECMA-262 section 15.5.4.8
119 function StringLastIndexOf(pat /* position */) { // length == 1 131 function StringLastIndexOf(pat /* position */) { // length == 1
132 if (IS_NULL_OR_UNDEFINED(this)) {
133 throw MakeTypeError("obj_ctor_property_non_object", ["lastIndexOf"]);
134 }
120 var sub = TO_STRING_INLINE(this); 135 var sub = TO_STRING_INLINE(this);
121 var subLength = sub.length; 136 var subLength = sub.length;
122 var pat = TO_STRING_INLINE(pat); 137 var pat = TO_STRING_INLINE(pat);
123 var patLength = pat.length; 138 var patLength = pat.length;
124 var index = subLength - patLength; 139 var index = subLength - patLength;
125 if (%_ArgumentsLength() > 1) { 140 if (%_ArgumentsLength() > 1) {
126 var position = ToNumber(%_Arguments(1)); 141 var position = ToNumber(%_Arguments(1));
127 if (!NUMBER_IS_NAN(position)) { 142 if (!NUMBER_IS_NAN(position)) {
128 position = TO_INTEGER(position); 143 position = TO_INTEGER(position);
129 if (position < 0) { 144 if (position < 0) {
130 position = 0; 145 position = 0;
131 } 146 }
132 if (position + patLength < subLength) { 147 if (position + patLength < subLength) {
133 index = position 148 index = position
134 } 149 }
135 } 150 }
136 } 151 }
137 if (index < 0) { 152 if (index < 0) {
138 return -1; 153 return -1;
139 } 154 }
140 return %StringLastIndexOf(sub, pat, index); 155 return %StringLastIndexOf(sub, pat, index);
141 } 156 }
142 157
143 158
144 // ECMA-262 section 15.5.4.9 159 // ECMA-262 section 15.5.4.9
145 // 160 //
146 // This function is implementation specific. For now, we do not 161 // This function is implementation specific. For now, we do not
147 // do anything locale specific. 162 // do anything locale specific.
148 function StringLocaleCompare(other) { 163 function StringLocaleCompare(other) {
164 if (IS_NULL_OR_UNDEFINED(this)) {
165 throw MakeTypeError("obj_ctor_property_non_object", ["localeCompare"]);
166 }
149 if (%_ArgumentsLength() === 0) return 0; 167 if (%_ArgumentsLength() === 0) return 0;
150 return %StringLocaleCompare(TO_STRING_INLINE(this), 168 return %StringLocaleCompare(TO_STRING_INLINE(this),
151 TO_STRING_INLINE(other)); 169 TO_STRING_INLINE(other));
152 } 170 }
153 171
154 172
155 // ECMA-262 section 15.5.4.10 173 // ECMA-262 section 15.5.4.10
156 function StringMatch(regexp) { 174 function StringMatch(regexp) {
175 if (IS_NULL_OR_UNDEFINED(this)) {
176 throw MakeTypeError("obj_ctor_property_non_object", ["match"]);
177 }
157 var subject = TO_STRING_INLINE(this); 178 var subject = TO_STRING_INLINE(this);
158 if (IS_REGEXP(regexp)) { 179 if (IS_REGEXP(regexp)) {
159 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); 180 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
160 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); 181 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
161 // lastMatchInfo is defined in regexp.js. 182 // lastMatchInfo is defined in regexp.js.
162 return %StringMatch(subject, regexp, lastMatchInfo); 183 return %StringMatch(subject, regexp, lastMatchInfo);
163 } 184 }
164 // Non-regexp argument. 185 // Non-regexp argument.
165 regexp = new $RegExp(regexp); 186 regexp = new $RegExp(regexp);
166 return RegExpExecNoTests(regexp, subject, 0); 187 return RegExpExecNoTests(regexp, subject, 0);
(...skipping 13 matching lines...) Expand all
180 // This has the same size as the lastMatchInfo array, and can be used for 201 // This has the same size as the lastMatchInfo array, and can be used for
181 // functions that expect that structure to be returned. It is used when the 202 // functions that expect that structure to be returned. It is used when the
182 // needle is a string rather than a regexp. In this case we can't update 203 // needle is a string rather than a regexp. In this case we can't update
183 // lastMatchArray without erroneously affecting the properties on the global 204 // lastMatchArray without erroneously affecting the properties on the global
184 // RegExp object. 205 // RegExp object.
185 var reusableMatchInfo = [2, "", "", -1, -1]; 206 var reusableMatchInfo = [2, "", "", -1, -1];
186 207
187 208
188 // ECMA-262, section 15.5.4.11 209 // ECMA-262, section 15.5.4.11
189 function StringReplace(search, replace) { 210 function StringReplace(search, replace) {
211 if (IS_NULL_OR_UNDEFINED(this)) {
212 throw MakeTypeError("obj_ctor_property_non_object", ["replace"]);
213 }
190 var subject = TO_STRING_INLINE(this); 214 var subject = TO_STRING_INLINE(this);
191 215
192 // Delegate to one of the regular expression variants if necessary. 216 // Delegate to one of the regular expression variants if necessary.
193 if (IS_REGEXP(search)) { 217 if (IS_REGEXP(search)) {
194 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); 218 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
195 if (IS_FUNCTION(replace)) { 219 if (IS_FUNCTION(replace)) {
196 if (search.global) { 220 if (search.global) {
197 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); 221 return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
198 } else { 222 } else {
199 return StringReplaceNonGlobalRegExpWithFunction(subject, 223 return StringReplaceNonGlobalRegExpWithFunction(subject,
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 result.add(replacement); // The add method converts to string if necessary. 484 result.add(replacement); // The add method converts to string if necessary.
461 // Can't use matchInfo any more from here, since the function could 485 // Can't use matchInfo any more from here, since the function could
462 // overwrite it. 486 // overwrite it.
463 result.addSpecialSlice(endOfMatch, subject.length); 487 result.addSpecialSlice(endOfMatch, subject.length);
464 return result.generate(); 488 return result.generate();
465 } 489 }
466 490
467 491
468 // ECMA-262 section 15.5.4.12 492 // ECMA-262 section 15.5.4.12
469 function StringSearch(re) { 493 function StringSearch(re) {
494 if (IS_NULL_OR_UNDEFINED(this)) {
495 throw MakeTypeError("obj_ctor_property_non_object", ["search"]);
496 }
470 var regexp; 497 var regexp;
471 if (IS_STRING(re)) { 498 if (IS_STRING(re)) {
472 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); 499 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re);
473 } else if (IS_REGEXP(re)) { 500 } else if (IS_REGEXP(re)) {
474 regexp = re; 501 regexp = re;
475 } else { 502 } else {
476 regexp = new $RegExp(re); 503 regexp = new $RegExp(re);
477 } 504 }
478 var match = DoRegExpExec(regexp, TO_STRING_INLINE(this), 0); 505 var match = DoRegExpExec(regexp, TO_STRING_INLINE(this), 0);
479 if (match) { 506 if (match) {
480 return match[CAPTURE0]; 507 return match[CAPTURE0];
481 } 508 }
482 return -1; 509 return -1;
483 } 510 }
484 511
485 512
486 // ECMA-262 section 15.5.4.13 513 // ECMA-262 section 15.5.4.13
487 function StringSlice(start, end) { 514 function StringSlice(start, end) {
515 if (IS_NULL_OR_UNDEFINED(this)) {
516 throw MakeTypeError("obj_ctor_property_non_object", ["slice"]);
517 }
488 var s = TO_STRING_INLINE(this); 518 var s = TO_STRING_INLINE(this);
489 var s_len = s.length; 519 var s_len = s.length;
490 var start_i = TO_INTEGER(start); 520 var start_i = TO_INTEGER(start);
491 var end_i = s_len; 521 var end_i = s_len;
492 if (end !== void 0) 522 if (end !== void 0)
493 end_i = TO_INTEGER(end); 523 end_i = TO_INTEGER(end);
494 524
495 if (start_i < 0) { 525 if (start_i < 0) {
496 start_i += s_len; 526 start_i += s_len;
497 if (start_i < 0) 527 if (start_i < 0)
(...skipping 15 matching lines...) Expand all
513 var num_c = end_i - start_i; 543 var num_c = end_i - start_i;
514 if (num_c < 0) 544 if (num_c < 0)
515 num_c = 0; 545 num_c = 0;
516 546
517 return SubString(s, start_i, start_i + num_c); 547 return SubString(s, start_i, start_i + num_c);
518 } 548 }
519 549
520 550
521 // ECMA-262 section 15.5.4.14 551 // ECMA-262 section 15.5.4.14
522 function StringSplit(separator, limit) { 552 function StringSplit(separator, limit) {
553 if (IS_NULL_OR_UNDEFINED(this)) {
554 throw MakeTypeError("obj_ctor_property_non_object", ["split"]);
555 }
523 var subject = TO_STRING_INLINE(this); 556 var subject = TO_STRING_INLINE(this);
524 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit); 557 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit);
525 if (limit === 0) return []; 558 if (limit === 0) return [];
526 559
527 // ECMA-262 says that if separator is undefined, the result should 560 // ECMA-262 says that if separator is undefined, the result should
528 // be an array of size 1 containing the entire string. SpiderMonkey 561 // be an array of size 1 containing the entire string. SpiderMonkey
529 // and KJS have this behavior only when no separator is given. If 562 // and KJS have this behavior only when no separator is given. If
530 // undefined is explicitly given, they convert it to a string and 563 // undefined is explicitly given, they convert it to a string and
531 // use that. We do as SpiderMonkey and KJS. 564 // use that. We do as SpiderMonkey and KJS.
532 if (%_ArgumentsLength() === 0) { 565 if (%_ArgumentsLength() === 0) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } 639 }
607 640
608 startIndex = currentIndex = endIndex; 641 startIndex = currentIndex = endIndex;
609 } 642 }
610 return result; 643 return result;
611 } 644 }
612 645
613 646
614 // ECMA-262 section 15.5.4.15 647 // ECMA-262 section 15.5.4.15
615 function StringSubstring(start, end) { 648 function StringSubstring(start, end) {
649 if (IS_NULL_OR_UNDEFINED(this)) {
650 throw MakeTypeError("obj_ctor_property_non_object", ["subString"]);
651 }
616 var s = TO_STRING_INLINE(this); 652 var s = TO_STRING_INLINE(this);
617 var s_len = s.length; 653 var s_len = s.length;
618 654
619 var start_i = TO_INTEGER(start); 655 var start_i = TO_INTEGER(start);
620 if (start_i < 0) { 656 if (start_i < 0) {
621 start_i = 0; 657 start_i = 0;
622 } else if (start_i > s_len) { 658 } else if (start_i > s_len) {
623 start_i = s_len; 659 start_i = s_len;
624 } 660 }
625 661
(...skipping 13 matching lines...) Expand all
639 } 675 }
640 676
641 return (start_i + 1 == end_i 677 return (start_i + 1 == end_i
642 ? %_StringCharAt(s, start_i) 678 ? %_StringCharAt(s, start_i)
643 : %_SubString(s, start_i, end_i)); 679 : %_SubString(s, start_i, end_i));
644 } 680 }
645 681
646 682
647 // This is not a part of ECMA-262. 683 // This is not a part of ECMA-262.
648 function StringSubstr(start, n) { 684 function StringSubstr(start, n) {
685 if (IS_NULL_OR_UNDEFINED(this)) {
686 throw MakeTypeError("obj_ctor_property_non_object", ["substr"]);
687 }
649 var s = TO_STRING_INLINE(this); 688 var s = TO_STRING_INLINE(this);
650 var len; 689 var len;
651 690
652 // Correct n: If not given, set to string length; if explicitly 691 // Correct n: If not given, set to string length; if explicitly
653 // set to undefined, zero, or negative, returns empty string. 692 // set to undefined, zero, or negative, returns empty string.
654 if (n === void 0) { 693 if (n === void 0) {
655 len = s.length; 694 len = s.length;
656 } else { 695 } else {
657 len = TO_INTEGER(n); 696 len = TO_INTEGER(n);
658 if (len <= 0) return ''; 697 if (len <= 0) return '';
(...skipping 20 matching lines...) Expand all
679 if (end > s.length) end = s.length; 718 if (end > s.length) end = s.length;
680 719
681 return (start + 1 == end 720 return (start + 1 == end
682 ? %_StringCharAt(s, start) 721 ? %_StringCharAt(s, start)
683 : %_SubString(s, start, end)); 722 : %_SubString(s, start, end));
684 } 723 }
685 724
686 725
687 // ECMA-262, 15.5.4.16 726 // ECMA-262, 15.5.4.16
688 function StringToLowerCase() { 727 function StringToLowerCase() {
728 if (IS_NULL_OR_UNDEFINED(this)) {
729 throw MakeTypeError("obj_ctor_property_non_object", ["toLowerCase"]);
730 }
689 return %StringToLowerCase(TO_STRING_INLINE(this)); 731 return %StringToLowerCase(TO_STRING_INLINE(this));
690 } 732 }
691 733
692 734
693 // ECMA-262, 15.5.4.17 735 // ECMA-262, 15.5.4.17
694 function StringToLocaleLowerCase() { 736 function StringToLocaleLowerCase() {
737 if (IS_NULL_OR_UNDEFINED(this)) {
738 throw MakeTypeError("obj_ctor_property_non_object", ["toLocaleLowerCase"]);
739 }
695 return %StringToLowerCase(TO_STRING_INLINE(this)); 740 return %StringToLowerCase(TO_STRING_INLINE(this));
696 } 741 }
697 742
698 743
699 // ECMA-262, 15.5.4.18 744 // ECMA-262, 15.5.4.18
700 function StringToUpperCase() { 745 function StringToUpperCase() {
746 if (IS_NULL_OR_UNDEFINED(this)) {
747 throw MakeTypeError("obj_ctor_property_non_object", ["toUpperCase"]);
748 }
701 return %StringToUpperCase(TO_STRING_INLINE(this)); 749 return %StringToUpperCase(TO_STRING_INLINE(this));
702 } 750 }
703 751
704 752
705 // ECMA-262, 15.5.4.19 753 // ECMA-262, 15.5.4.19
706 function StringToLocaleUpperCase() { 754 function StringToLocaleUpperCase() {
755 if (IS_NULL_OR_UNDEFINED(this)) {
756 throw MakeTypeError("obj_ctor_property_non_object", ["toLocaleUpperCase"]);
757 }
707 return %StringToUpperCase(TO_STRING_INLINE(this)); 758 return %StringToUpperCase(TO_STRING_INLINE(this));
708 } 759 }
709 760
710 // ES5, 15.5.4.20 761 // ES5, 15.5.4.20
711 function StringTrim() { 762 function StringTrim() {
763 if (IS_NULL_OR_UNDEFINED(this)) {
764 throw MakeTypeError("obj_ctor_property_non_object", ["trim"]);
765 }
712 return %StringTrim(TO_STRING_INLINE(this), true, true); 766 return %StringTrim(TO_STRING_INLINE(this), true, true);
713 } 767 }
714 768
715 function StringTrimLeft() { 769 function StringTrimLeft() {
770 if (IS_NULL_OR_UNDEFINED(this)) {
771 throw MakeTypeError("obj_ctor_property_non_object", ["trimLeft"]);
772 }
716 return %StringTrim(TO_STRING_INLINE(this), true, false); 773 return %StringTrim(TO_STRING_INLINE(this), true, false);
717 } 774 }
718 775
719 function StringTrimRight() { 776 function StringTrimRight() {
777 if (IS_NULL_OR_UNDEFINED(this)) {
778 throw MakeTypeError("obj_ctor_property_non_object", ["trimRight"]);
779 }
720 return %StringTrim(TO_STRING_INLINE(this), false, true); 780 return %StringTrim(TO_STRING_INLINE(this), false, true);
721 } 781 }
722 782
723 var static_charcode_array = new InternalArray(4); 783 var static_charcode_array = new InternalArray(4);
724 784
725 // ECMA-262, section 15.5.3.2 785 // ECMA-262, section 15.5.3.2
726 function StringFromCharCode(code) { 786 function StringFromCharCode(code) {
727 var n = %_ArgumentsLength(); 787 var n = %_ArgumentsLength();
728 if (n == 1) { 788 if (n == 1) {
729 if (!%_IsSmi(code)) code = ToNumber(code); 789 if (!%_IsSmi(code)) code = ToNumber(code);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 "italics", StringItalics, 966 "italics", StringItalics,
907 "small", StringSmall, 967 "small", StringSmall,
908 "strike", StringStrike, 968 "strike", StringStrike,
909 "sub", StringSub, 969 "sub", StringSub,
910 "sup", StringSup 970 "sup", StringSup
911 )); 971 ));
912 } 972 }
913 973
914 974
915 SetupString(); 975 SetupString();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698