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

Side by Side Diff: src/string.js

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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
« no previous file with comments | « src/spaces-inl.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 16 matching lines...) Expand all
27 27
28 28
29 // This file relies on the fact that the following declaration has been made 29 // This file relies on the fact that the following declaration has been made
30 // in runtime.js: 30 // in runtime.js:
31 // const $String = global.String; 31 // const $String = global.String;
32 // const $NaN = 0/0; 32 // const $NaN = 0/0;
33 33
34 34
35 // Set the String function and constructor. 35 // Set the String function and constructor.
36 %SetCode($String, function(x) { 36 %SetCode($String, function(x) {
37 var value = %_ArgumentsLength() == 0 ? '' : ToString(x); 37 var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x);
38 if (%_IsConstructCall()) { 38 if (%_IsConstructCall()) {
39 %_SetValueOf(this, value); 39 %_SetValueOf(this, value);
40 } else { 40 } else {
41 return value; 41 return value;
42 } 42 }
43 }); 43 });
44 44
45 %FunctionSetPrototype($String, new $String()); 45 %FunctionSetPrototype($String, new $String());
46 46
47 // ECMA-262 section 15.5.4.2 47 // ECMA-262 section 15.5.4.2
48 function StringToString() { 48 function StringToString() {
49 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) 49 if (!IS_STRING(this) && !IS_STRING_WRAPPER(this))
50 throw new $TypeError('String.prototype.toString is not generic'); 50 throw new $TypeError('String.prototype.toString is not generic');
51 return %_ValueOf(this); 51 return %_ValueOf(this);
52 } 52 }
53 53
54 54
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 var char_code = %_FastCharCodeAt(this, pos); 65 var char_code = %_FastCharCodeAt(this, pos);
66 if (!%_IsSmi(char_code)) { 66 if (!%_IsSmi(char_code)) {
67 var subject = ToString(this); 67 var subject = TO_STRING_INLINE(this);
68 var index = TO_INTEGER(pos); 68 var index = TO_INTEGER(pos);
69 if (index >= subject.length || index < 0) return ""; 69 if (index >= subject.length || index < 0) return "";
70 char_code = %StringCharCodeAt(subject, index); 70 char_code = %StringCharCodeAt(subject, index);
71 } 71 }
72 return %CharFromCode(char_code); 72 return %CharFromCode(char_code);
73 } 73 }
74 74
75 75
76 // ECMA-262 section 15.5.4.5 76 // ECMA-262 section 15.5.4.5
77 function StringCharCodeAt(pos) { 77 function StringCharCodeAt(pos) {
78 var fast_answer = %_FastCharCodeAt(this, pos); 78 var fast_answer = %_FastCharCodeAt(this, pos);
79 if (%_IsSmi(fast_answer)) { 79 if (%_IsSmi(fast_answer)) {
80 return fast_answer; 80 return fast_answer;
81 } 81 }
82 var subject = ToString(this); 82 var subject = TO_STRING_INLINE(this);
83 var index = TO_INTEGER(pos); 83 var index = TO_INTEGER(pos);
84 return %StringCharCodeAt(subject, index); 84 return %StringCharCodeAt(subject, index);
85 } 85 }
86 86
87 87
88 // ECMA-262, section 15.5.4.6 88 // ECMA-262, section 15.5.4.6
89 function StringConcat() { 89 function StringConcat() {
90 var len = %_ArgumentsLength() + 1; 90 var len = %_ArgumentsLength();
91 var parts = new $Array(len); 91 var this_as_string = TO_STRING_INLINE(this);
92 parts[0] = IS_STRING(this) ? this : ToString(this); 92 if (len === 1) {
93 for (var i = 1; i < len; i++) { 93 return this_as_string + %_Arguments(0);
94 var part = %_Arguments(i - 1);
95 parts[i] = IS_STRING(part) ? part : ToString(part);
96 } 94 }
97 return %StringBuilderConcat(parts, len, ""); 95 var parts = new $Array(len + 1);
96 parts[0] = this_as_string;
97 for (var i = 0; i < len; i++) {
98 var part = %_Arguments(i);
99 parts[i + 1] = TO_STRING_INLINE(part);
100 }
101 return %StringBuilderConcat(parts, len + 1, "");
98 } 102 }
99 103
100 // Match ES3 and Safari 104 // Match ES3 and Safari
101 %FunctionSetLength(StringConcat, 1); 105 %FunctionSetLength(StringConcat, 1);
102 106
103 107
104 // ECMA-262 section 15.5.4.7 108 // ECMA-262 section 15.5.4.7
105 function StringIndexOf(searchString /* position */) { // length == 1 109 function StringIndexOf(searchString /* position */) { // length == 1
106 var subject_str = ToString(this); 110 var subject_str = TO_STRING_INLINE(this);
107 var pattern_str = ToString(searchString); 111 var pattern_str = TO_STRING_INLINE(searchString);
108 var subject_str_len = subject_str.length; 112 var subject_str_len = subject_str.length;
109 var pattern_str_len = pattern_str.length; 113 var pattern_str_len = pattern_str.length;
110 var index = 0; 114 var index = 0;
111 if (%_ArgumentsLength() > 1) { 115 if (%_ArgumentsLength() > 1) {
112 var arg1 = %_Arguments(1); // position 116 var arg1 = %_Arguments(1); // position
113 index = TO_INTEGER(arg1); 117 index = TO_INTEGER(arg1);
114 } 118 }
115 if (index < 0) index = 0; 119 if (index < 0) index = 0;
116 if (index > subject_str_len) index = subject_str_len; 120 if (index > subject_str_len) index = subject_str_len;
117 if (pattern_str_len + index > subject_str_len) return -1; 121 if (pattern_str_len + index > subject_str_len) return -1;
118 return %StringIndexOf(subject_str, pattern_str, index); 122 return %StringIndexOf(subject_str, pattern_str, index);
119 } 123 }
120 124
121 125
122 // ECMA-262 section 15.5.4.8 126 // ECMA-262 section 15.5.4.8
123 function StringLastIndexOf(searchString /* position */) { // length == 1 127 function StringLastIndexOf(searchString /* position */) { // length == 1
124 var sub = ToString(this); 128 var sub = TO_STRING_INLINE(this);
125 var subLength = sub.length; 129 var subLength = sub.length;
126 var pat = ToString(searchString); 130 var pat = TO_STRING_INLINE(searchString);
127 var patLength = pat.length; 131 var patLength = pat.length;
128 var index = subLength - patLength; 132 var index = subLength - patLength;
129 if (%_ArgumentsLength() > 1) { 133 if (%_ArgumentsLength() > 1) {
130 var position = ToNumber(%_Arguments(1)); 134 var position = ToNumber(%_Arguments(1));
131 if (!$isNaN(position)) { 135 if (!$isNaN(position)) {
132 position = TO_INTEGER(position); 136 position = TO_INTEGER(position);
133 if (position < 0) { 137 if (position < 0) {
134 position = 0; 138 position = 0;
135 } 139 }
136 if (position + patLength < subLength) { 140 if (position + patLength < subLength) {
137 index = position 141 index = position
138 } 142 }
139 } 143 }
140 } 144 }
141 if (index < 0) { 145 if (index < 0) {
142 return -1; 146 return -1;
143 } 147 }
144 return %StringLastIndexOf(sub, pat, index); 148 return %StringLastIndexOf(sub, pat, index);
145 } 149 }
146 150
147 151
148 // ECMA-262 section 15.5.4.9 152 // ECMA-262 section 15.5.4.9
149 // 153 //
150 // This function is implementation specific. For now, we do not 154 // This function is implementation specific. For now, we do not
151 // do anything locale specific. 155 // do anything locale specific.
152 function StringLocaleCompare(other) { 156 function StringLocaleCompare(other) {
153 if (%_ArgumentsLength() === 0) return 0; 157 if (%_ArgumentsLength() === 0) return 0;
154 158
155 var this_str = ToString(this); 159 var this_str = TO_STRING_INLINE(this);
156 var other_str = ToString(other); 160 var other_str = TO_STRING_INLINE(other);
157 return %StringLocaleCompare(this_str, other_str); 161 return %StringLocaleCompare(this_str, other_str);
158 } 162 }
159 163
160 164
161 // ECMA-262 section 15.5.4.10 165 // ECMA-262 section 15.5.4.10
162 function StringMatch(regexp) { 166 function StringMatch(regexp) {
163 if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp); 167 if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp);
164 var subject = ToString(this); 168 var subject = TO_STRING_INLINE(this);
165 169
166 if (!regexp.global) return regexp.exec(subject); 170 if (!regexp.global) return regexp.exec(subject);
167 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); 171 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
168 // lastMatchInfo is defined in regexp.js. 172 // lastMatchInfo is defined in regexp.js.
169 return %StringMatch(subject, regexp, lastMatchInfo); 173 return %StringMatch(subject, regexp, lastMatchInfo);
170 } 174 }
171 175
172 176
173 // SubString is an internal function that returns the sub string of 'string'. 177 // SubString is an internal function that returns the sub string of 'string'.
174 // If resulting string is of length 1, we use the one character cache 178 // If resulting string is of length 1, we use the one character cache
(...skipping 14 matching lines...) Expand all
189 // This has the same size as the lastMatchInfo array, and can be used for 193 // This has the same size as the lastMatchInfo array, and can be used for
190 // functions that expect that structure to be returned. It is used when the 194 // functions that expect that structure to be returned. It is used when the
191 // needle is a string rather than a regexp. In this case we can't update 195 // needle is a string rather than a regexp. In this case we can't update
192 // lastMatchArray without erroneously affecting the properties on the global 196 // lastMatchArray without erroneously affecting the properties on the global
193 // RegExp object. 197 // RegExp object.
194 var reusableMatchInfo = [2, "", "", -1, -1]; 198 var reusableMatchInfo = [2, "", "", -1, -1];
195 199
196 200
197 // ECMA-262, section 15.5.4.11 201 // ECMA-262, section 15.5.4.11
198 function StringReplace(search, replace) { 202 function StringReplace(search, replace) {
199 var subject = IS_STRING(this) ? this : ToString(this); 203 var subject = TO_STRING_INLINE(this);
200 204
201 // Delegate to one of the regular expression variants if necessary. 205 // Delegate to one of the regular expression variants if necessary.
202 if (IS_REGEXP(search)) { 206 if (IS_REGEXP(search)) {
203 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); 207 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
204 if (IS_FUNCTION(replace)) { 208 if (IS_FUNCTION(replace)) {
205 return StringReplaceRegExpWithFunction(subject, search, replace); 209 return StringReplaceRegExpWithFunction(subject, search, replace);
206 } else { 210 } else {
207 return StringReplaceRegExp(subject, search, replace); 211 return StringReplaceRegExp(subject, search, replace);
208 } 212 }
209 } 213 }
210 214
211 // Convert the search argument to a string and search for it. 215 // Convert the search argument to a string and search for it.
212 search = IS_STRING(search) ? search : ToString(search); 216 search = TO_STRING_INLINE(search);
213 var start = %StringIndexOf(subject, search, 0); 217 var start = %StringIndexOf(subject, search, 0);
214 if (start < 0) return subject; 218 if (start < 0) return subject;
215 var end = start + search.length; 219 var end = start + search.length;
216 220
217 var builder = new ReplaceResultBuilder(subject); 221 var builder = new ReplaceResultBuilder(subject);
218 // prefix 222 // prefix
219 builder.addSpecialSlice(0, start); 223 builder.addSpecialSlice(0, start);
220 224
221 // Compute the string to replace with. 225 // Compute the string to replace with.
222 if (IS_FUNCTION(replace)) { 226 if (IS_FUNCTION(replace)) {
223 builder.add(replace.call(null, search, start, subject)); 227 builder.add(replace.call(null, search, start, subject));
224 } else { 228 } else {
225 reusableMatchInfo[CAPTURE0] = start; 229 reusableMatchInfo[CAPTURE0] = start;
226 reusableMatchInfo[CAPTURE1] = end; 230 reusableMatchInfo[CAPTURE1] = end;
227 if (!IS_STRING(replace)) replace = ToString(replace); 231 replace = TO_STRING_INLINE(replace);
228 ExpandReplacement(replace, subject, reusableMatchInfo, builder); 232 ExpandReplacement(replace, subject, reusableMatchInfo, builder);
229 } 233 }
230 234
231 // suffix 235 // suffix
232 builder.addSpecialSlice(end, subject.length); 236 builder.addSpecialSlice(end, subject.length);
233 237
234 return builder.generate(); 238 return builder.generate();
235 } 239 }
236 240
237 241
238 // Helper function for regular expressions in String.prototype.replace. 242 // Helper function for regular expressions in String.prototype.replace.
239 function StringReplaceRegExp(subject, regexp, replace) { 243 function StringReplaceRegExp(subject, regexp, replace) {
240 replace = ToString(replace); 244 replace = TO_STRING_INLINE(replace);
241 return %StringReplaceRegExpWithString(subject, 245 return %StringReplaceRegExpWithString(subject,
242 regexp, 246 regexp,
243 replace, 247 replace,
244 lastMatchInfo); 248 lastMatchInfo);
245 }; 249 };
246 250
247 251
248 // Expand the $-expressions in the string and return a new string with 252 // Expand the $-expressions in the string and return a new string with
249 // the result. 253 // the result.
250 function ExpandReplacement(string, subject, matchInfo, builder) { 254 function ExpandReplacement(string, subject, matchInfo, builder) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 } 455 }
452 parameters[j] = index; 456 parameters[j] = index;
453 parameters[j + 1] = subject; 457 parameters[j + 1] = subject;
454 return replace.apply(null, parameters); 458 return replace.apply(null, parameters);
455 } 459 }
456 460
457 461
458 // ECMA-262 section 15.5.4.12 462 // ECMA-262 section 15.5.4.12
459 function StringSearch(re) { 463 function StringSearch(re) {
460 var regexp = new $RegExp(re); 464 var regexp = new $RegExp(re);
461 var s = ToString(this); 465 var s = TO_STRING_INLINE(this);
462 var last_idx = regexp.lastIndex; // keep old lastIndex 466 var last_idx = regexp.lastIndex; // keep old lastIndex
463 regexp.lastIndex = 0; // ignore re.global property 467 regexp.lastIndex = 0; // ignore re.global property
464 var result = regexp.exec(s); 468 var result = regexp.exec(s);
465 regexp.lastIndex = last_idx; // restore lastIndex 469 regexp.lastIndex = last_idx; // restore lastIndex
466 if (result == null) 470 if (result == null)
467 return -1; 471 return -1;
468 else 472 else
469 return result.index; 473 return result.index;
470 } 474 }
471 475
472 476
473 // ECMA-262 section 15.5.4.13 477 // ECMA-262 section 15.5.4.13
474 function StringSlice(start, end) { 478 function StringSlice(start, end) {
475 var s = ToString(this); 479 var s = TO_STRING_INLINE(this);
476 var s_len = s.length; 480 var s_len = s.length;
477 var start_i = TO_INTEGER(start); 481 var start_i = TO_INTEGER(start);
478 var end_i = s_len; 482 var end_i = s_len;
479 if (end !== void 0) 483 if (end !== void 0)
480 end_i = TO_INTEGER(end); 484 end_i = TO_INTEGER(end);
481 485
482 if (start_i < 0) { 486 if (start_i < 0) {
483 start_i += s_len; 487 start_i += s_len;
484 if (start_i < 0) 488 if (start_i < 0)
485 start_i = 0; 489 start_i = 0;
(...skipping 14 matching lines...) Expand all
500 var num_c = end_i - start_i; 504 var num_c = end_i - start_i;
501 if (num_c < 0) 505 if (num_c < 0)
502 num_c = 0; 506 num_c = 0;
503 507
504 return SubString(s, start_i, start_i + num_c); 508 return SubString(s, start_i, start_i + num_c);
505 } 509 }
506 510
507 511
508 // ECMA-262 section 15.5.4.14 512 // ECMA-262 section 15.5.4.14
509 function StringSplit(separator, limit) { 513 function StringSplit(separator, limit) {
510 var subject = ToString(this); 514 var subject = TO_STRING_INLINE(this);
511 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit); 515 limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit);
512 if (limit === 0) return []; 516 if (limit === 0) return [];
513 517
514 // ECMA-262 says that if separator is undefined, the result should 518 // ECMA-262 says that if separator is undefined, the result should
515 // be an array of size 1 containing the entire string. SpiderMonkey 519 // be an array of size 1 containing the entire string. SpiderMonkey
516 // and KJS have this behaviour only when no separator is given. If 520 // and KJS have this behaviour only when no separator is given. If
517 // undefined is explicitly given, they convert it to a string and 521 // undefined is explicitly given, they convert it to a string and
518 // use that. We do as SpiderMonkey and KJS. 522 // use that. We do as SpiderMonkey and KJS.
519 if (%_ArgumentsLength() === 0) { 523 if (%_ArgumentsLength() === 0) {
520 return [subject]; 524 return [subject];
521 } 525 }
522 526
523 var length = subject.length; 527 var length = subject.length;
524 if (IS_REGEXP(separator)) { 528 if (!IS_REGEXP(separator)) {
525 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); 529 separator = TO_STRING_INLINE(separator);
526 } else { 530 var separator_length = separator.length;
527 separator = ToString(separator); 531
528 // If the separator string is empty then return the elements in the subject. 532 // If the separator string is empty then return the elements in the subject.
529 if (separator.length == 0) { 533 if (separator_length === 0) {
530 var result = $Array(length); 534 var result = $Array(length);
531 for (var i = 0; i < length; i++) result[i] = subject[i]; 535 for (var i = 0; i < length; i++) result[i] = subject[i];
532 return result; 536 return result;
533 } 537 }
538
539 var result = [];
540 var start_index = 0;
541 var index;
542 while (true) {
543 if (start_index + separator_length > length ||
544 (index = %StringIndexOf(subject, separator, start_index)) === -1) {
545 result.push(SubString(subject, start_index, length));
546 break;
547 }
548 if (result.push(SubString(subject, start_index, index)) === limit) break;
549 start_index = index + separator_length;
550 }
551
552 return result;
534 } 553 }
535 554
555 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
556
536 if (length === 0) { 557 if (length === 0) {
537 if (splitMatch(separator, subject, 0, 0) != null) return []; 558 if (splitMatch(separator, subject, 0, 0) != null) return [];
538 return [subject]; 559 return [subject];
539 } 560 }
540 561
541 var currentIndex = 0; 562 var currentIndex = 0;
542 var startIndex = 0; 563 var startIndex = 0;
543 var result = []; 564 var result = [];
544 565
545 while (true) { 566 while (true) {
(...skipping 14 matching lines...) Expand all
560 581
561 // We ignore a zero-length match at the currentIndex. 582 // We ignore a zero-length match at the currentIndex.
562 if (startIndex === endIndex && endIndex === currentIndex) { 583 if (startIndex === endIndex && endIndex === currentIndex) {
563 startIndex++; 584 startIndex++;
564 continue; 585 continue;
565 } 586 }
566 587
567 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] ); 588 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] );
568 if (result.length === limit) return result; 589 if (result.length === limit) return result;
569 590
570 for (var i = 2; i < NUMBER_OF_CAPTURES(matchInfo); i += 2) { 591 var num_captures = NUMBER_OF_CAPTURES(matchInfo);
592 for (var i = 2; i < num_captures; i += 2) {
571 var start = matchInfo[CAPTURE(i)]; 593 var start = matchInfo[CAPTURE(i)];
572 var end = matchInfo[CAPTURE(i + 1)]; 594 var end = matchInfo[CAPTURE(i + 1)];
573 if (start != -1 && end != -1) { 595 if (start != -1 && end != -1) {
574 result[result.length] = SubString(subject, start, end); 596 result[result.length] = SubString(subject, start, end);
575 } else { 597 } else {
576 result[result.length] = void 0; 598 result[result.length] = void 0;
577 } 599 }
578 if (result.length === limit) return result; 600 if (result.length === limit) return result;
579 } 601 }
580 602
581 startIndex = currentIndex = endIndex; 603 startIndex = currentIndex = endIndex;
582 } 604 }
583 } 605 }
584 606
585 607
586 // ECMA-262 section 15.5.4.14 608 // ECMA-262 section 15.5.4.14
587 // Helper function used by split. This version returns the matchInfo 609 // Helper function used by split. This version returns the matchInfo
588 // instead of allocating a new array with basically the same information. 610 // instead of allocating a new array with basically the same information.
589 function splitMatch(separator, subject, current_index, start_index) { 611 function splitMatch(separator, subject, current_index, start_index) {
590 if (IS_REGEXP(separator)) { 612 var matchInfo = DoRegExpExec(separator, subject, start_index);
591 var matchInfo = DoRegExpExec(separator, subject, start_index); 613 if (matchInfo == null) return null;
592 if (matchInfo == null) return null; 614 // Section 15.5.4.14 paragraph two says that we do not allow zero length
593 // Section 15.5.4.14 paragraph two says that we do not allow zero length 615 // matches at the end of the string.
594 // matches at the end of the string. 616 if (matchInfo[CAPTURE0] === subject.length) return null;
595 if (matchInfo[CAPTURE0] === subject.length) return null; 617 return matchInfo;
596 return matchInfo; 618 }
597 }
598
599 var separatorIndex = subject.indexOf(separator, start_index);
600 if (separatorIndex === -1) return null;
601
602 reusableMatchInfo[CAPTURE0] = separatorIndex;
603 reusableMatchInfo[CAPTURE1] = separatorIndex + separator.length;
604 return reusableMatchInfo;
605 };
606 619
607 620
608 // ECMA-262 section 15.5.4.15 621 // ECMA-262 section 15.5.4.15
609 function StringSubstring(start, end) { 622 function StringSubstring(start, end) {
610 var s = this; 623 var s = TO_STRING_INLINE(this);
611 if (!IS_STRING(s)) s = ToString(s);
612 var s_len = s.length; 624 var s_len = s.length;
613 625
614 var start_i = TO_INTEGER(start); 626 var start_i = TO_INTEGER(start);
615 if (start_i < 0) { 627 if (start_i < 0) {
616 start_i = 0; 628 start_i = 0;
617 } else if (start_i > s_len) { 629 } else if (start_i > s_len) {
618 start_i = s_len; 630 start_i = s_len;
619 } 631 }
620 632
621 var end_i = s_len; 633 var end_i = s_len;
(...skipping 10 matching lines...) Expand all
632 } 644 }
633 } 645 }
634 } 646 }
635 647
636 return SubString(s, start_i, end_i); 648 return SubString(s, start_i, end_i);
637 } 649 }
638 650
639 651
640 // This is not a part of ECMA-262. 652 // This is not a part of ECMA-262.
641 function StringSubstr(start, n) { 653 function StringSubstr(start, n) {
642 var s = ToString(this); 654 var s = TO_STRING_INLINE(this);
643 var len; 655 var len;
644 656
645 // Correct n: If not given, set to string length; if explicitly 657 // Correct n: If not given, set to string length; if explicitly
646 // set to undefined, zero, or negative, returns empty string. 658 // set to undefined, zero, or negative, returns empty string.
647 if (n === void 0) { 659 if (n === void 0) {
648 len = s.length; 660 len = s.length;
649 } else { 661 } else {
650 len = TO_INTEGER(n); 662 len = TO_INTEGER(n);
651 if (len <= 0) return ''; 663 if (len <= 0) return '';
652 } 664 }
(...skipping 17 matching lines...) Expand all
670 682
671 var end = start + len; 683 var end = start + len;
672 if (end > s.length) end = s.length; 684 if (end > s.length) end = s.length;
673 685
674 return SubString(s, start, end); 686 return SubString(s, start, end);
675 } 687 }
676 688
677 689
678 // ECMA-262, 15.5.4.16 690 // ECMA-262, 15.5.4.16
679 function StringToLowerCase() { 691 function StringToLowerCase() {
680 return %StringToLowerCase(ToString(this)); 692 return %StringToLowerCase(TO_STRING_INLINE(this));
681 } 693 }
682 694
683 695
684 // ECMA-262, 15.5.4.17 696 // ECMA-262, 15.5.4.17
685 function StringToLocaleLowerCase() { 697 function StringToLocaleLowerCase() {
686 return %StringToLowerCase(ToString(this)); 698 return %StringToLowerCase(TO_STRING_INLINE(this));
687 } 699 }
688 700
689 701
690 // ECMA-262, 15.5.4.18 702 // ECMA-262, 15.5.4.18
691 function StringToUpperCase() { 703 function StringToUpperCase() {
692 return %StringToUpperCase(ToString(this)); 704 return %StringToUpperCase(TO_STRING_INLINE(this));
693 } 705 }
694 706
695 707
696 // ECMA-262, 15.5.4.19 708 // ECMA-262, 15.5.4.19
697 function StringToLocaleUpperCase() { 709 function StringToLocaleUpperCase() {
698 return %StringToUpperCase(ToString(this)); 710 return %StringToUpperCase(TO_STRING_INLINE(this));
699 } 711 }
700 712
701 // ES5, 15.5.4.20 713 // ES5, 15.5.4.20
702 function StringTrim() { 714 function StringTrim() {
703 return %StringTrim(ToString(this), true, true); 715 return %StringTrim(TO_STRING_INLINE(this), true, true);
704 } 716 }
705 717
706 function StringTrimLeft() { 718 function StringTrimLeft() {
707 return %StringTrim(ToString(this), true, false); 719 return %StringTrim(TO_STRING_INLINE(this), true, false);
708 } 720 }
709 721
710 function StringTrimRight() { 722 function StringTrimRight() {
711 return %StringTrim(ToString(this), false, true); 723 return %StringTrim(TO_STRING_INLINE(this), false, true);
712 } 724 }
713 725
714 // ECMA-262, section 15.5.3.2 726 // ECMA-262, section 15.5.3.2
715 function StringFromCharCode(code) { 727 function StringFromCharCode(code) {
716 var n = %_ArgumentsLength(); 728 var n = %_ArgumentsLength();
717 if (n == 1) return %CharFromCode(ToNumber(code) & 0xffff) 729 if (n == 1) return %CharFromCode(ToNumber(code) & 0xffff)
718 730
719 // NOTE: This is not super-efficient, but it is necessary because we 731 // NOTE: This is not super-efficient, but it is necessary because we
720 // want to avoid converting to numbers from within the virtual 732 // want to avoid converting to numbers from within the virtual
721 // machine. Maybe we can find another way of doing this? 733 // machine. Maybe we can find another way of doing this?
722 var codes = new $Array(n); 734 var codes = new $Array(n);
723 for (var i = 0; i < n; i++) codes[i] = ToNumber(%_Arguments(i)); 735 for (var i = 0; i < n; i++) codes[i] = ToNumber(%_Arguments(i));
724 return %StringFromCharCodeArray(codes); 736 return %StringFromCharCodeArray(codes);
725 } 737 }
726 738
727 739
728 // Helper function for very basic XSS protection. 740 // Helper function for very basic XSS protection.
729 function HtmlEscape(str) { 741 function HtmlEscape(str) {
730 return ToString(str).replace(/</g, "&lt;") 742 return TO_STRING_INLINE(str).replace(/</g, "&lt;")
731 .replace(/>/g, "&gt;") 743 .replace(/>/g, "&gt;")
732 .replace(/"/g, "&quot;") 744 .replace(/"/g, "&quot;")
733 .replace(/'/g, "&#039;"); 745 .replace(/'/g, "&#039;");
734 }; 746 };
735 747
736 748
737 // Compatibility support for KJS. 749 // Compatibility support for KJS.
738 // Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js. 750 // Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js.
739 function StringLink(s) { 751 function StringLink(s) {
740 return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>"; 752 return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>";
741 } 753 }
742 754
743 755
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 814
803 815
804 // ReplaceResultBuilder support. 816 // ReplaceResultBuilder support.
805 function ReplaceResultBuilder(str) { 817 function ReplaceResultBuilder(str) {
806 this.elements = new $Array(); 818 this.elements = new $Array();
807 this.special_string = str; 819 this.special_string = str;
808 } 820 }
809 821
810 822
811 ReplaceResultBuilder.prototype.add = function(str) { 823 ReplaceResultBuilder.prototype.add = function(str) {
812 if (!IS_STRING(str)) str = ToString(str); 824 str = TO_STRING_INLINE(str);
813 if (str.length > 0) { 825 if (str.length > 0) {
814 var elements = this.elements; 826 var elements = this.elements;
815 elements[elements.length] = str; 827 elements[elements.length] = str;
816 } 828 }
817 } 829 }
818 830
819 831
820 ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) { 832 ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
821 var len = end - start; 833 var len = end - start;
822 if (len == 0) return; 834 if (len == 0) return;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 "small", StringSmall, 904 "small", StringSmall,
893 "strike", StringStrike, 905 "strike", StringStrike,
894 "sub", StringSub, 906 "sub", StringSub,
895 "sup", StringSup, 907 "sup", StringSup,
896 "toJSON", StringToJSON 908 "toJSON", StringToJSON
897 )); 909 ));
898 } 910 }
899 911
900 912
901 SetupString(); 913 SetupString();
OLDNEW
« no previous file with comments | « src/spaces-inl.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698