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

Side by Side Diff: src/string.js

Issue 6602: Cleanup string builtins. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 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 | « no previous file | no next file » | 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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 26 matching lines...) Expand all
37 var value = %_ArgumentsLength() == 0 ? '' : ToString(x); 37 var value = %_ArgumentsLength() == 0 ? '' : ToString(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 %AddProperty($String.prototype, "constructor", $String, DONT_ENUM); 47 // ECMA-262 section 15.5.4.2
48 function StringToString() {
49 if (!IS_STRING(this) && %ClassOf(this) !== 'String')
50 throw new $TypeError('String.prototype.toString is not generic');
51 return %_ValueOf(this);
52 }
48 53
49 %AddProperty($String.prototype, "valueOf", function valueOf() { 54
55 // ECMA-262 section 15.5.4.3
56 function StringValueOf() {
50 if (!IS_STRING(this) && %ClassOf(this) !== 'String') 57 if (!IS_STRING(this) && %ClassOf(this) !== 'String')
51 throw new $TypeError('String.prototype.valueOf is not generic'); 58 throw new $TypeError('String.prototype.valueOf is not generic');
52 return %_ValueOf(this); 59 return %_ValueOf(this);
53 }, DONT_ENUM); 60 }
54 61
55 %AddProperty($String.prototype, "toString", function toString() { 62
56 if (!IS_STRING(this) && %ClassOf(this) !== 'String') 63 // ECMA-262, section 15.5.4.4
57 throw new $TypeError('String.prototype.toString is not generic'); 64 function StringCharAt(pos) {
58 return %_ValueOf(this); 65 var subject = ToString(this);
59 }, DONT_ENUM); 66 var index = TO_INTEGER(pos);
67 if (index >= subject.length || index < 0) return "";
68 return %CharFromCode(%StringCharCodeAt(subject, index));
69 }
70
60 71
61 // ECMA-262 section 15.5.4.5 72 // ECMA-262 section 15.5.4.5
62 %AddProperty($String.prototype, "charCodeAt", function charCodeAt(pos) { 73 function StringCharCodeAt(pos) {
63 var fast_answer = %_FastCharCodeAt(this, pos); 74 var fast_answer = %_FastCharCodeAt(this, pos);
64 if (%_IsSmi(fast_answer)) { 75 if (%_IsSmi(fast_answer)) {
65 return fast_answer; 76 return fast_answer;
66 } 77 }
67 var subject = ToString(this); 78 var subject = ToString(this);
68 var index = TO_INTEGER(pos); 79 var index = TO_INTEGER(pos);
69 return %StringCharCodeAt(subject, index); 80 return %StringCharCodeAt(subject, index);
70 }, DONT_ENUM); 81 }
71 82
72 83
73 // ECMA-262, section 15.5.4.6 84 // ECMA-262, section 15.5.4.6
74 %AddProperty($String.prototype, "concat", function concat() { 85 function StringConcat() {
75 var len = %_ArgumentsLength(); 86 var len = %_ArgumentsLength();
76 var parts = new $Array(len + 1); 87 var parts = new $Array(len + 1);
77 parts[0] = ToString(this); 88 parts[0] = ToString(this);
78 for (var i = 0; i < len; i++) 89 for (var i = 0; i < len; i++)
79 parts[i + 1] = ToString(%_Arguments(i)); 90 parts[i + 1] = ToString(%_Arguments(i));
80 return parts.join(''); 91 return parts.join('');
81 }, DONT_ENUM); 92 }
82 93
83 // Match ES3 and Safari 94 // Match ES3 and Safari
84 %FunctionSetLength($String.prototype.concat, 1); 95 %FunctionSetLength(StringConcat, 1);
96
97
98 // ECMA-262 section 15.5.4.7
99 function StringIndexOf(searchString /* position */) { // length == 1
100 var subject_str = ToString(this);
101 var pattern_str = ToString(searchString);
102 var subject_str_len = subject_str.length;
103 var pattern_str_len = pattern_str.length;
104 var index = 0;
105 if (%_ArgumentsLength() > 1) {
106 var arg1 = %_Arguments(1); // position
107 index = TO_INTEGER(arg1);
108 }
109 if (index < 0) index = 0;
110 if (index > subject_str_len) index = subject_str_len;
111 if (pattern_str_len + index > subject_str_len) return -1;
112 return %StringIndexOf(subject_str, pattern_str, index);
113 }
114
115
116 // ECMA-262 section 15.5.4.8
117 function StringLastIndexOf(searchString /* position */) { // length == 1
118 var sub = ToString(this);
119 var pat = ToString(searchString);
120 var index = (%_ArgumentsLength() > 1)
121 ? ToNumber(%_Arguments(1) /* position */)
122 : $NaN;
123 var firstIndex;
124 if ($isNaN(index)) {
125 firstIndex = sub.length - pat.length;
126 } else {
127 firstIndex = TO_INTEGER(index);
128 if (firstIndex + pat.length > sub.length) {
129 firstIndex = sub.length - pat.length;
130 }
131 }
132 return %StringLastIndexOf(sub, pat, firstIndex);
133 }
134
135
136 // ECMA-262 section 15.5.4.9
137 //
138 // This function is implementation specific. For now, we do not
139 // do anything locale specific.
140 function StringLocaleCompare(other) {
141 if (%_ArgumentsLength() === 0) return 0;
142
143 var this_str = ToString(this);
144 var other_str = ToString(other);
145 return %StringLocaleCompare(this_str, other_str);
146 }
147
148
149 // ECMA-262 section 15.5.4.10
150 function StringMatch(regexp) {
151 if (!IS_REGEXP(regexp)) regexp = new ORIGINAL_REGEXP(regexp);
152 var subject = ToString(this);
153
154 if (!regexp.global) return regexp.exec(subject);
155 var matches = DoRegExpExecGlobal(regexp, subject);
156
157 // If the regexp did not match, return null.
158 if (matches.length == 0) return null;
159
160 // Build the result array.
161 var result = new $Array(match_string);
162 for (var i = 0; i < matches.length; ++i) {
163 var match = matches[i];
164 var match_string = subject.slice(match[0], match[1]);
165 result[i] = match_string;
166 }
167
168 return result;
169 }
85 170
86 171
87 // SubString is an internal function that returns the sub string of 'string'. 172 // SubString is an internal function that returns the sub string of 'string'.
88 // If resulting string is of length 1, we use the one character cache 173 // If resulting string is of length 1, we use the one character cache
89 // otherwise we call the runtime system. 174 // otherwise we call the runtime system.
90 function SubString(string, start, end) { 175 function SubString(string, start, end) {
91 // Use the one character string cache. 176 // Use the one character string cache.
92 if (start + 1 == end) return %CharFromCode(%StringCharCodeAt(string, start)); 177 if (start + 1 == end) return %CharFromCode(%StringCharCodeAt(string, start));
93 return %StringSlice(string, start, end); 178 return %StringSlice(string, start, end);
94 } 179 }
95 180
96 181
97 // ECMA-262, section 15.5.4.11 182 // ECMA-262, section 15.5.4.11
98 %AddProperty($String.prototype, "replace", function replace(search, replace) { 183 function StringReplace(search, replace) {
99 var subject = ToString(this); 184 var subject = ToString(this);
100 185
101 // Delegate to one of the regular expression variants if necessary. 186 // Delegate to one of the regular expression variants if necessary.
102 if (IS_REGEXP(search)) { 187 if (IS_REGEXP(search)) {
103 if (IS_FUNCTION(replace)) { 188 if (IS_FUNCTION(replace)) {
104 return StringReplaceRegExpWithFunction(subject, search, replace); 189 return StringReplaceRegExpWithFunction(subject, search, replace);
105 } else { 190 } else {
106 return StringReplaceRegExp(subject, search, replace); 191 return StringReplaceRegExp(subject, search, replace);
107 } 192 }
108 } 193 }
(...skipping 12 matching lines...) Expand all
121 if (IS_FUNCTION(replace)) { 206 if (IS_FUNCTION(replace)) {
122 builder.add(replace.call(null, search, start, subject)); 207 builder.add(replace.call(null, search, start, subject));
123 } else { 208 } else {
124 ExpandReplacement(ToString(replace), subject, [ start, end ], builder); 209 ExpandReplacement(ToString(replace), subject, [ start, end ], builder);
125 } 210 }
126 211
127 // suffix 212 // suffix
128 builder.add(SubString(subject, end, subject.length)); 213 builder.add(SubString(subject, end, subject.length));
129 214
130 return builder.generate(); 215 return builder.generate();
131 }, DONT_ENUM); 216 }
132 217
133 218
134 // Helper function for regular expressions in String.prototype.replace. 219 // Helper function for regular expressions in String.prototype.replace.
135 function StringReplaceRegExp(subject, regexp, replace) { 220 function StringReplaceRegExp(subject, regexp, replace) {
136 // Compute an array of matches; each match is really a list of 221 // Compute an array of matches; each match is really a list of
137 // captures - pairs of (start, end) indexes into the subject string. 222 // captures - pairs of (start, end) indexes into the subject string.
138 var matches; 223 var matches;
139 if (regexp.global) { 224 if (regexp.global) {
140 matches = DoRegExpExecGlobal(regexp, subject); 225 matches = DoRegExpExecGlobal(regexp, subject);
141 if (matches.length == 0) return subject; 226 if (matches.length == 0) return subject;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 var parameters = $Array(m + 2); 410 var parameters = $Array(m + 2);
326 for (var j = 0; j < m; j++) { 411 for (var j = 0; j < m; j++) {
327 parameters[j] = CaptureString(subject, captures, j); 412 parameters[j] = CaptureString(subject, captures, j);
328 } 413 }
329 parameters[j] = index; 414 parameters[j] = index;
330 parameters[j + 1] = subject; 415 parameters[j + 1] = subject;
331 return ToString(replace.apply(null, parameters)); 416 return ToString(replace.apply(null, parameters));
332 } 417 }
333 418
334 419
335 // ECMA-262 section 15.5.4.7
336 %AddProperty($String.prototype, "indexOf", function indexOf(searchString /* posi tion */) { // length == 1
337 var subject_str = ToString(this);
338 var pattern_str = ToString(searchString);
339 var subject_str_len = subject_str.length;
340 var pattern_str_len = pattern_str.length;
341 var index = 0;
342 if (%_ArgumentsLength() > 1) {
343 var arg1 = %_Arguments(1); // position
344 index = TO_INTEGER(arg1);
345 }
346 if (index < 0) index = 0;
347 if (index > subject_str_len) index = subject_str_len;
348 if (pattern_str_len + index > subject_str_len) return -1;
349 return %StringIndexOf(subject_str, pattern_str, index);
350 }, DONT_ENUM);
351
352
353 // ECMA-262 section 15.5.4.8
354 %AddProperty($String.prototype, "lastIndexOf", function lastIndexOf(searchString /* position */) { // length == 1
355 var sub = ToString(this);
356 var pat = ToString(searchString);
357 var index = (%_ArgumentsLength() > 1)
358 ? ToNumber(%_Arguments(1) /* position */)
359 : $NaN;
360 var firstIndex;
361 if ($isNaN(index)) {
362 firstIndex = sub.length - pat.length;
363 } else {
364 firstIndex = TO_INTEGER(index);
365 if (firstIndex + pat.length > sub.length) {
366 firstIndex = sub.length - pat.length;
367 }
368 }
369 return %StringLastIndexOf(sub, pat, firstIndex);
370 }, DONT_ENUM);
371
372
373 // ECMA-262 section 15.5.4.9
374 //
375 // This function is implementation specific. For now, we do not
376 // do anything locale specific.
377 %AddProperty($String.prototype, "localeCompare", function localeCompare(other) {
378 if (%_ArgumentsLength() === 0) return 0;
379
380 var this_str = ToString(this);
381 var other_str = ToString(other);
382 return %StringLocaleCompare(this_str, other_str);
383 }, DONT_ENUM);
384
385
386 // ECMA-262 section 15.5.4.10
387 %AddProperty($String.prototype, "match", function match(regexp) {
388 if (!IS_REGEXP(regexp)) regexp = new ORIGINAL_REGEXP(regexp);
389 var subject = ToString(this);
390
391 if (!regexp.global) return regexp.exec(subject);
392 var matches = DoRegExpExecGlobal(regexp, subject);
393
394 // If the regexp did not match, return null.
395 if (matches.length == 0) return null;
396
397 // Build the result array.
398 var result = new $Array(match_string);
399 for (var i = 0; i < matches.length; ++i) {
400 var match = matches[i];
401 var match_string = subject.slice(match[0], match[1]);
402 result[i] = match_string;
403 }
404
405 return result;
406 }, DONT_ENUM);
407
408
409 // ECMA-262 section 15.5.4.12 420 // ECMA-262 section 15.5.4.12
410 %AddProperty($String.prototype, "search", function search(re) { 421 function StringSearch(re) {
411 var regexp = new ORIGINAL_REGEXP(re); 422 var regexp = new ORIGINAL_REGEXP(re);
412 var s = ToString(this); 423 var s = ToString(this);
413 var last_idx = regexp.lastIndex; // keep old lastIndex 424 var last_idx = regexp.lastIndex; // keep old lastIndex
414 regexp.lastIndex = 0; // ignore re.global property 425 regexp.lastIndex = 0; // ignore re.global property
415 var result = regexp.exec(s); 426 var result = regexp.exec(s);
416 regexp.lastIndex = last_idx; // restore lastIndex 427 regexp.lastIndex = last_idx; // restore lastIndex
417 if (result == null) 428 if (result == null)
418 return -1; 429 return -1;
419 else 430 else
420 return result.index; 431 return result.index;
421 }, DONT_ENUM); 432 }
422 433
423 434
424 // ECMA-262 section 15.5.4.13 435 // ECMA-262 section 15.5.4.13
425 %AddProperty($String.prototype, "slice", function slice(start, end) { 436 function StringSlice(start, end) {
426 var s = ToString(this); 437 var s = ToString(this);
427 var s_len = s.length; 438 var s_len = s.length;
428 var start_i = TO_INTEGER(start); 439 var start_i = TO_INTEGER(start);
429 var end_i = s_len; 440 var end_i = s_len;
430 if (end !== void 0) 441 if (end !== void 0)
431 end_i = TO_INTEGER(end); 442 end_i = TO_INTEGER(end);
432 443
433 if (start_i < 0) { 444 if (start_i < 0) {
434 start_i += s_len; 445 start_i += s_len;
435 if (start_i < 0) 446 if (start_i < 0)
(...skipping 10 matching lines...) Expand all
446 } else { 457 } else {
447 if (end_i > s_len) 458 if (end_i > s_len)
448 end_i = s_len; 459 end_i = s_len;
449 } 460 }
450 461
451 var num_c = end_i - start_i; 462 var num_c = end_i - start_i;
452 if (num_c < 0) 463 if (num_c < 0)
453 num_c = 0; 464 num_c = 0;
454 465
455 return SubString(s, start_i, start_i + num_c); 466 return SubString(s, start_i, start_i + num_c);
456 }, DONT_ENUM); 467 }
457 468
458 469
459 // ECMA-262 section 15.5.4.14 470 // ECMA-262 section 15.5.4.14
460 %AddProperty($String.prototype, "split", function split(separator, limit) { 471 function StringSplit(separator, limit) {
461 var subject = ToString(this); 472 var subject = ToString(this);
462 var result = []; 473 var result = [];
463 var lim = (limit === void 0) ? 0xffffffff : ToUint32(limit); 474 var lim = (limit === void 0) ? 0xffffffff : ToUint32(limit);
464 475
465 if (lim === 0) return result; 476 if (lim === 0) return result;
466 477
467 // ECMA-262 says that if separator is undefined, the result should 478 // ECMA-262 says that if separator is undefined, the result should
468 // be an array of size 1 containing the entire string. SpiderMonkey 479 // be an array of size 1 containing the entire string. SpiderMonkey
469 // and KJS have this behaviour only when no separator is given. If 480 // and KJS have this behaviour only when no separator is given. If
470 // undefined is explicitly given, they convert it to a string and 481 // undefined is explicitly given, they convert it to a string and
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 result[result.length] = match[1]; 522 result[result.length] = match[1];
512 if (result.length === lim) return result; 523 if (result.length === lim) return result;
513 524
514 for (var i = 2; i < match.length; i++) { 525 for (var i = 2; i < match.length; i++) {
515 result[result.length] = match[i]; 526 result[result.length] = match[i];
516 if (result.length === lim) return result; 527 if (result.length === lim) return result;
517 } 528 }
518 529
519 startIndex = currentIndex = endIndex; 530 startIndex = currentIndex = endIndex;
520 } 531 }
521 }, DONT_ENUM); 532 }
522 533
523 534
524 // ECMA-262 section 15.5.4.14 535 // ECMA-262 section 15.5.4.14
525 // Helper function used by split. 536 // Helper function used by split.
526 function splitMatch(separator, subject, current_index, start_index) { 537 function splitMatch(separator, subject, current_index, start_index) {
527 if (IS_REGEXP(separator)) { 538 if (IS_REGEXP(separator)) {
528 var ovector = DoRegExpExec(separator, subject, start_index); 539 var ovector = DoRegExpExec(separator, subject, start_index);
529 if (ovector == null) return null; 540 if (ovector == null) return null;
530 var nof_results = ovector.length >> 1; 541 var nof_results = ovector.length >> 1;
531 var result = new $Array(nof_results + 1); 542 var result = new $Array(nof_results + 1);
(...skipping 10 matching lines...) Expand all
542 } 553 }
543 554
544 var separatorIndex = subject.indexOf(separator, start_index); 555 var separatorIndex = subject.indexOf(separator, start_index);
545 if (separatorIndex === -1) return null; 556 if (separatorIndex === -1) return null;
546 557
547 return [ separatorIndex + separator.length, subject.slice(current_index, separ atorIndex) ]; 558 return [ separatorIndex + separator.length, subject.slice(current_index, separ atorIndex) ];
548 }; 559 };
549 560
550 561
551 // ECMA-262 section 15.5.4.15 562 // ECMA-262 section 15.5.4.15
552 %AddProperty($String.prototype, "substring", function substring(start, end) { 563 function StringSubstring(start, end) {
553 var s = ToString(this); 564 var s = ToString(this);
554 var s_len = s.length; 565 var s_len = s.length;
555 var start_i = TO_INTEGER(start); 566 var start_i = TO_INTEGER(start);
556 var end_i = s_len; 567 var end_i = s_len;
557 if (!IS_UNDEFINED(end)) 568 if (!IS_UNDEFINED(end))
558 end_i = TO_INTEGER(end); 569 end_i = TO_INTEGER(end);
559 570
560 if (start_i < 0) start_i = 0; 571 if (start_i < 0) start_i = 0;
561 if (start_i > s_len) start_i = s_len; 572 if (start_i > s_len) start_i = s_len;
562 if (end_i < 0) end_i = 0; 573 if (end_i < 0) end_i = 0;
563 if (end_i > s_len) end_i = s_len; 574 if (end_i > s_len) end_i = s_len;
564 575
565 if (start_i > end_i) { 576 if (start_i > end_i) {
566 var tmp = end_i; 577 var tmp = end_i;
567 end_i = start_i; 578 end_i = start_i;
568 start_i = tmp; 579 start_i = tmp;
569 } 580 }
570 581
571 return SubString(s, start_i, end_i); 582 return SubString(s, start_i, end_i);
572 }, DONT_ENUM); 583 }
573 584
574 585
575 // This is not a part of ECMA-262. 586 // This is not a part of ECMA-262.
576 %AddProperty($String.prototype, "substr", function substr(start, n) { 587 function StringSubstr(start, n) {
577 var s = ToString(this); 588 var s = ToString(this);
578 var len; 589 var len;
579 590
580 // Correct n: If not given, set to string length; if explicitly 591 // Correct n: If not given, set to string length; if explicitly
581 // set to undefined, zero, or negative, returns empty string. 592 // set to undefined, zero, or negative, returns empty string.
582 if (n === void 0) { 593 if (n === void 0) {
583 len = s.length; 594 len = s.length;
584 } else { 595 } else {
585 len = TO_INTEGER(n); 596 len = TO_INTEGER(n);
586 if (len <= 0) return ''; 597 if (len <= 0) return '';
(...skipping 13 matching lines...) Expand all
600 if (start < 0) { 611 if (start < 0) {
601 start += s.length; 612 start += s.length;
602 if (start < 0) start = 0; 613 if (start < 0) start = 0;
603 } 614 }
604 } 615 }
605 616
606 var end = start + len; 617 var end = start + len;
607 if (end > s.length) end = s.length; 618 if (end > s.length) end = s.length;
608 619
609 return SubString(s, start, end); 620 return SubString(s, start, end);
610 }, DONT_ENUM); 621 }
611 622
612 623
613 // ECMA-262, 15.5.4.16 624 // ECMA-262, 15.5.4.16
614 %AddProperty($String.prototype, "toLowerCase", function toLowerCase() { 625 function StringToLowerCase() {
615 return %StringToLowerCase(ToString(this)); 626 return %StringToLowerCase(ToString(this));
616 }, DONT_ENUM); 627 }
617 628
618 629
619 // ECMA-262, 15.5.4.17 630 // ECMA-262, 15.5.4.17
620 %AddProperty($String.prototype, "toLocaleLowerCase", function toLocaleLowerCase( ) { 631 function StringToLocaleLowerCase() {
621 return %StringToLowerCase(ToString(this)); 632 return %StringToLowerCase(ToString(this));
622 }, DONT_ENUM); 633 }
623 634
624 635
625 // ECMA-262, 15.5.4.18 636 // ECMA-262, 15.5.4.18
626 %AddProperty($String.prototype, "toUpperCase", function toUpperCase() { 637 function StringToUpperCase() {
627 return %StringToUpperCase(ToString(this)); 638 return %StringToUpperCase(ToString(this));
628 }, DONT_ENUM); 639 }
629 640
630 641
631 // ECMA-262, 15.5.4.19 642 // ECMA-262, 15.5.4.19
632 %AddProperty($String.prototype, "toLocaleUpperCase", function toLocaleUpperCase( ) { 643 function StringToLocaleUpperCase() {
633 return %StringToUpperCase(ToString(this)); 644 return %StringToUpperCase(ToString(this));
634 }, DONT_ENUM); 645 }
635 646
636 647
637 // ECMA-262, section 15.5.3.2 648 // ECMA-262, section 15.5.3.2
638 %AddProperty($String, "fromCharCode", function fromCharCode(code) { 649 function StringFromCharCode(code) {
639 var n = %_ArgumentsLength(); 650 var n = %_ArgumentsLength();
640 if (n == 1) return %CharFromCode(ToNumber(code) & 0xffff) 651 if (n == 1) return %CharFromCode(ToNumber(code) & 0xffff)
641 652
642 // NOTE: This is not super-efficient, but it is necessary because we 653 // NOTE: This is not super-efficient, but it is necessary because we
643 // want to avoid converting to numbers from within the virtual 654 // want to avoid converting to numbers from within the virtual
644 // machine. Maybe we can find another way of doing this? 655 // machine. Maybe we can find another way of doing this?
645 var codes = new $Array(n); 656 var codes = new $Array(n);
646 for (var i = 0; i < n; i++) codes[i] = ToNumber(%_Arguments(i)); 657 for (var i = 0; i < n; i++) codes[i] = ToNumber(%_Arguments(i));
647 return %StringFromCharCodeArray(codes); 658 return %StringFromCharCodeArray(codes);
648 }, DONT_ENUM); 659 }
649
650
651 // ECMA-262, section 15.5.4.4
652 function charAt(pos) {
653 var subject = ToString(this);
654 var index = TO_INTEGER(pos);
655 if (index >= subject.length || index < 0) return "";
656 return %CharFromCode(%StringCharCodeAt(subject, index));
657 };
658
659 %AddProperty($String.prototype, "charAt", charAt, DONT_ENUM);
660 660
661 661
662 // Helper function for very basic XSS protection. 662 // Helper function for very basic XSS protection.
663 function HtmlEscape(str) { 663 function HtmlEscape(str) {
664 return ToString(str).replace(/</g, "&lt;") 664 return ToString(str).replace(/</g, "&lt;")
665 .replace(/>/g, "&gt;") 665 .replace(/>/g, "&gt;")
666 .replace(/"/g, "&quot;") 666 .replace(/"/g, "&quot;")
667 .replace(/'/g, "&#039;"); 667 .replace(/'/g, "&#039;");
668 }; 668 };
669 669
670 670
671 // Compatibility support for KJS. 671 // Compatibility support for KJS.
672 // Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js. 672 // Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js.
673 %AddProperty($String.prototype, "link", function link(s) { 673 function StringLink(s) {
674 return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>"; 674 return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>";
675 }, DONT_ENUM); 675 }
676 676
677 677
678 %AddProperty($String.prototype, "anchor", function anchor(name) { 678 function StringAnchor(name) {
679 return "<a name=\"" + HtmlEscape(name) + "\">" + this + "</a>"; 679 return "<a name=\"" + HtmlEscape(name) + "\">" + this + "</a>";
680 }, DONT_ENUM); 680 }
681 681
682 682
683 %AddProperty($String.prototype, "fontcolor", function fontcolor(color) { 683 function StringFontcolor(color) {
684 return "<font color=\"" + HtmlEscape(color) + "\">" + this + "</font>"; 684 return "<font color=\"" + HtmlEscape(color) + "\">" + this + "</font>";
685 }, DONT_ENUM); 685 }
686 686
687 687
688 %AddProperty($String.prototype, "fontsize", function fontsize(size) { 688 function StringFontsize(size) {
689 return "<font size=\"" + HtmlEscape(size) + "\">" + this + "</font>"; 689 return "<font size=\"" + HtmlEscape(size) + "\">" + this + "</font>";
690 }, DONT_ENUM); 690 }
691 691
692 692
693 %AddProperty($String.prototype, "big", function big() { 693 function StringBig() {
694 return "<big>" + this + "</big>"; 694 return "<big>" + this + "</big>";
695 }, DONT_ENUM); 695 }
696 696
697 697
698 %AddProperty($String.prototype, "blink", function blink() { 698 function StringBlink() {
699 return "<blink>" + this + "</blink>"; 699 return "<blink>" + this + "</blink>";
700 }, DONT_ENUM); 700 }
701 701
702 702
703 %AddProperty($String.prototype, "bold", function bold() { 703 function StringBold() {
704 return "<b>" + this + "</b>"; 704 return "<b>" + this + "</b>";
705 }, DONT_ENUM); 705 }
706 706
707 707
708 %AddProperty($String.prototype, "fixed", function fixed() { 708 function StringFixed() {
709 return "<tt>" + this + "</tt>"; 709 return "<tt>" + this + "</tt>";
710 }, DONT_ENUM); 710 }
711 711
712 712
713 %AddProperty($String.prototype, "italics", function italics() { 713 function StringItalics() {
714 return "<i>" + this + "</i>"; 714 return "<i>" + this + "</i>";
715 }, DONT_ENUM); 715 }
716 716
717 717
718 %AddProperty($String.prototype, "small", function small() { 718 function StringSmall() {
719 return "<small>" + this + "</small>"; 719 return "<small>" + this + "</small>";
720 }, DONT_ENUM); 720 }
721 721
722 722
723 %AddProperty($String.prototype, "strike", function strike() { 723 function StringStrike() {
724 return "<strike>" + this + "</strike>"; 724 return "<strike>" + this + "</strike>";
725 }, DONT_ENUM); 725 }
726 726
727 727
728 %AddProperty($String.prototype, "sub", function sub() { 728 function StringSub() {
729 return "<sub>" + this + "</sub>"; 729 return "<sub>" + this + "</sub>";
730 }, DONT_ENUM); 730 }
731 731
732 732
733 %AddProperty($String.prototype, "sup", function sup() { 733 function StringSup() {
734 return "<sup>" + this + "</sup>"; 734 return "<sup>" + this + "</sup>";
735 }, DONT_ENUM); 735 }
736 736
737 737
738 // StringBuilder support. 738 // StringBuilder support.
739 739
740 function StringBuilder() { 740 function StringBuilder() {
741 this.elements = new $Array(); 741 this.elements = new $Array();
742 } 742 }
743 743
744 744
745 function ReplaceResultBuilder(str) { 745 function ReplaceResultBuilder(str) {
(...skipping 25 matching lines...) Expand all
771 771
772 772
773 StringBuilder.prototype.generate = function() { 773 StringBuilder.prototype.generate = function() {
774 return %StringBuilderConcat(this.elements, ""); 774 return %StringBuilderConcat(this.elements, "");
775 } 775 }
776 776
777 777
778 ReplaceResultBuilder.prototype.generate = function() { 778 ReplaceResultBuilder.prototype.generate = function() {
779 return %StringBuilderConcat(this.elements, this.special_string); 779 return %StringBuilderConcat(this.elements, this.special_string);
780 } 780 }
781
782
783 // -------------------------------------------------------------------
784
785 function SetupString() {
786 // Setup the constructor property on the String prototype object.
787 %AddProperty($String.prototype, "constructor", $String, DONT_ENUM);
788
789
790 // Setup the non-enumerable functions on the String object.
791 InstallFunctions($String, DONT_ENUM, $Array(
792 "fromCharCode", StringFromCharCode
793 ));
794
795
796 // Setup the non-enumerable functions on the String prototype object.
797 InstallFunctions($String.prototype, DONT_ENUM, $Array(
798 "valueOf", StringValueOf,
799 "toString", StringToString,
800 "charAt", StringCharAt,
801 "charCodeAt", StringCharCodeAt,
802 "concat", StringConcat,
803 "indexOf", StringIndexOf,
804 "lastIndexOf", StringLastIndexOf,
805 "localeCompare", StringLocaleCompare,
806 "match", StringMatch,
807 "replace", StringReplace,
808 "search", StringSearch,
809 "slice", StringSlice,
810 "split", StringSplit,
811 "substring", StringSubstring,
812 "substr", StringSubstr,
813 "toLowerCase", StringToLowerCase,
814 "toLocaleLowerCase", StringToLocaleLowerCase,
815 "toUpperCase", StringToUpperCase,
816 "toLocaleUpperCase", StringToLocaleUpperCase,
817 "link", StringLink,
818 "anchor", StringAnchor,
819 "fontcolor", StringFontcolor,
820 "fontsize", StringFontsize,
821 "big", StringBig,
822 "blink", StringBlink,
823 "bold", StringBold,
824 "fixed", StringFixed,
825 "italics", StringItalics,
826 "small", StringSmall,
827 "strike", StringStrike,
828 "sub", StringSub,
829 "sup", StringSup
830 ));
831 }
832
833
834 SetupString();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698