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

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

Powered by Google App Engine
This is Rietveld 408576698