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 215052: * Remove non-Open Source code from Douglas Crockford.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 3 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/mirror-delay.js ('k') | src/uri.js » ('j') | tools/jsmin.py » ('J')
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 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 var char_code = %_FastCharCodeAt(this, index); 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 = ToString(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
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 var char_code = %_FastCharCodeAt(string, start); 177 var char_code = %_FastCharCodeAt(string, start);
178 if (!%_IsSmi(char_code)) { 178 if (!%_IsSmi(char_code)) {
179 char_code = %StringCharCodeAt(string, start); 179 char_code = %StringCharCodeAt(string, start);
180 } 180 }
181 return %CharFromCode(char_code); 181 return %CharFromCode(char_code);
182 } 182 }
183 return %StringSlice(string, start, end); 183 return %StringSlice(string, start, end);
184 } 184 }
185 185
186 186
187 // This has the same size as the lastMatchInfo array, and can be used for
188 // functions that expect that structure to be returned. It is used when the
189 // needle is a string rather than a regexp. In this case we can't update
190 // lastMatchArray without erroneously affecting the properties on the global
191 // RegExp object.
192 var reusableMatchInfo = [2, "", "", -1, -1];
193
194
187 // ECMA-262, section 15.5.4.11 195 // ECMA-262, section 15.5.4.11
188 function StringReplace(search, replace) { 196 function StringReplace(search, replace) {
189 var subject = ToString(this); 197 var subject = ToString(this);
190 198
191 // Delegate to one of the regular expression variants if necessary. 199 // Delegate to one of the regular expression variants if necessary.
192 if (IS_REGEXP(search)) { 200 if (IS_REGEXP(search)) {
193 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); 201 %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
194 if (IS_FUNCTION(replace)) { 202 if (IS_FUNCTION(replace)) {
195 return StringReplaceRegExpWithFunction(subject, search, replace); 203 return StringReplaceRegExpWithFunction(subject, search, replace);
196 } else { 204 } else {
(...skipping 20 matching lines...) Expand all
217 ExpandReplacement(ToString(replace), subject, reusableMatchInfo, builder); 225 ExpandReplacement(ToString(replace), subject, reusableMatchInfo, builder);
218 } 226 }
219 227
220 // suffix 228 // suffix
221 builder.addSpecialSlice(end, subject.length); 229 builder.addSpecialSlice(end, subject.length);
222 230
223 return builder.generate(); 231 return builder.generate();
224 } 232 }
225 233
226 234
227 // This has the same size as the lastMatchInfo array, and can be used for
228 // functions that expect that structure to be returned. It is used when the
229 // needle is a string rather than a regexp. In this case we can't update
230 // lastMatchArray without erroneously affecting the properties on the global
231 // RegExp object.
232 var reusableMatchInfo = [2, "", "", -1, -1];
233
234
235 // Helper function for regular expressions in String.prototype.replace. 235 // Helper function for regular expressions in String.prototype.replace.
236 function StringReplaceRegExp(subject, regexp, replace) { 236 function StringReplaceRegExp(subject, regexp, replace) {
237 replace = ToString(replace); 237 replace = ToString(replace);
238 return %StringReplaceRegExpWithString(subject, 238 return %StringReplaceRegExpWithString(subject,
239 regexp, 239 regexp,
240 replace, 240 replace,
241 lastMatchInfo); 241 lastMatchInfo);
242 }; 242 };
243 243
244 244
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 363
364 364
365 // Helper function for replacing regular expressions with the result of a 365 // Helper function for replacing regular expressions with the result of a
366 // function application in String.prototype.replace. The function application 366 // function application in String.prototype.replace. The function application
367 // must be interleaved with the regexp matching (contrary to ECMA-262 367 // must be interleaved with the regexp matching (contrary to ECMA-262
368 // 15.5.4.11) to mimic SpiderMonkey and KJS behavior when the function uses 368 // 15.5.4.11) to mimic SpiderMonkey and KJS behavior when the function uses
369 // the static properties of the RegExp constructor. Example: 369 // the static properties of the RegExp constructor. Example:
370 // 'abcd'.replace(/(.)/g, function() { return RegExp.$1; } 370 // 'abcd'.replace(/(.)/g, function() { return RegExp.$1; }
371 // should be 'abcd' and not 'dddd' (or anything else). 371 // should be 'abcd' and not 'dddd' (or anything else).
372 function StringReplaceRegExpWithFunction(subject, regexp, replace) { 372 function StringReplaceRegExpWithFunction(subject, regexp, replace) {
373 var lastMatchInfo = DoRegExpExec(regexp, subject, 0); 373 var matchInfo = DoRegExpExec(regexp, subject, 0);
374 if (IS_NULL(lastMatchInfo)) return subject; 374 if (IS_NULL(matchInfo)) return subject;
375 375
376 var result = new ReplaceResultBuilder(subject); 376 var result = new ReplaceResultBuilder(subject);
377 // There's at least one match. If the regexp is global, we have to loop 377 // There's at least one match. If the regexp is global, we have to loop
378 // over all matches. The loop is not in C++ code here like the one in 378 // over all matches. The loop is not in C++ code here like the one in
379 // RegExp.prototype.exec, because of the interleaved function application. 379 // RegExp.prototype.exec, because of the interleaved function application.
380 // Unfortunately, that means this code is nearly duplicated, here and in 380 // Unfortunately, that means this code is nearly duplicated, here and in
381 // jsregexp.cc. 381 // jsregexp.cc.
382 if (regexp.global) { 382 if (regexp.global) {
383 var previous = 0; 383 var previous = 0;
384 do { 384 do {
385 result.addSpecialSlice(previous, lastMatchInfo[CAPTURE0]); 385 result.addSpecialSlice(previous, matchInfo[CAPTURE0]);
386 var startOfMatch = lastMatchInfo[CAPTURE0]; 386 var startOfMatch = matchInfo[CAPTURE0];
387 previous = lastMatchInfo[CAPTURE1]; 387 previous = matchInfo[CAPTURE1];
388 result.add(ApplyReplacementFunction(replace, lastMatchInfo, subject)); 388 result.add(ApplyReplacementFunction(replace, matchInfo, subject));
389 // Can't use lastMatchInfo any more from here, since the function could 389 // Can't use matchInfo any more from here, since the function could
390 // overwrite it. 390 // overwrite it.
391 // Continue with the next match. 391 // Continue with the next match.
392 // Increment previous if we matched an empty string, as per ECMA-262 392 // Increment previous if we matched an empty string, as per ECMA-262
393 // 15.5.4.10. 393 // 15.5.4.10.
394 if (previous == startOfMatch) { 394 if (previous == startOfMatch) {
395 // Add the skipped character to the output, if any. 395 // Add the skipped character to the output, if any.
396 if (previous < subject.length) { 396 if (previous < subject.length) {
397 result.addSpecialSlice(previous, previous + 1); 397 result.addSpecialSlice(previous, previous + 1);
398 } 398 }
399 previous++; 399 previous++;
400 } 400 }
401 401
402 // Per ECMA-262 15.10.6.2, if the previous index is greater than the 402 // Per ECMA-262 15.10.6.2, if the previous index is greater than the
403 // string length, there is no match 403 // string length, there is no match
404 lastMatchInfo = (previous > subject.length) 404 matchInfo = (previous > subject.length)
405 ? null 405 ? null
406 : DoRegExpExec(regexp, subject, previous); 406 : DoRegExpExec(regexp, subject, previous);
407 } while (!IS_NULL(lastMatchInfo)); 407 } while (!IS_NULL(matchInfo));
408 408
409 // Tack on the final right substring after the last match, if necessary. 409 // Tack on the final right substring after the last match, if necessary.
410 if (previous < subject.length) { 410 if (previous < subject.length) {
411 result.addSpecialSlice(previous, subject.length); 411 result.addSpecialSlice(previous, subject.length);
412 } 412 }
413 } else { // Not a global regexp, no need to loop. 413 } else { // Not a global regexp, no need to loop.
414 result.addSpecialSlice(0, lastMatchInfo[CAPTURE0]); 414 result.addSpecialSlice(0, matchInfo[CAPTURE0]);
415 var endOfMatch = lastMatchInfo[CAPTURE1]; 415 var endOfMatch = matchInfo[CAPTURE1];
416 result.add(ApplyReplacementFunction(replace, lastMatchInfo, subject)); 416 result.add(ApplyReplacementFunction(replace, matchInfo, subject));
417 // Can't use lastMatchInfo any more from here, since the function could 417 // Can't use matchInfo any more from here, since the function could
418 // overwrite it. 418 // overwrite it.
419 result.addSpecialSlice(endOfMatch, subject.length); 419 result.addSpecialSlice(endOfMatch, subject.length);
420 } 420 }
421 421
422 return result.generate(); 422 return result.generate();
423 } 423 }
424 424
425 425
426 // Helper function to apply a string replacement function once. 426 // Helper function to apply a string replacement function once.
427 function ApplyReplacementFunction(replace, lastMatchInfo, subject) { 427 function ApplyReplacementFunction(replace, matchInfo, subject) {
428 // Compute the parameter list consisting of the match, captures, index, 428 // Compute the parameter list consisting of the match, captures, index,
429 // and subject for the replace function invocation. 429 // and subject for the replace function invocation.
430 var index = lastMatchInfo[CAPTURE0]; 430 var index = matchInfo[CAPTURE0];
431 // The number of captures plus one for the match. 431 // The number of captures plus one for the match.
432 var m = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1; 432 var m = NUMBER_OF_CAPTURES(matchInfo) >> 1;
433 if (m == 1) { 433 if (m == 1) {
434 var s = CaptureString(subject, lastMatchInfo, 0); 434 var s = CaptureString(subject, matchInfo, 0);
435 // Don't call directly to avoid exposing the built-in global object. 435 // Don't call directly to avoid exposing the built-in global object.
436 return replace.call(null, s, index, subject); 436 return replace.call(null, s, index, subject);
437 } 437 }
438 var parameters = $Array(m + 2); 438 var parameters = $Array(m + 2);
439 for (var j = 0; j < m; j++) { 439 for (var j = 0; j < m; j++) {
440 parameters[j] = CaptureString(subject, lastMatchInfo, j); 440 parameters[j] = CaptureString(subject, matchInfo, j);
441 } 441 }
442 parameters[j] = index; 442 parameters[j] = index;
443 parameters[j + 1] = subject; 443 parameters[j + 1] = subject;
444 return replace.apply(null, parameters); 444 return replace.apply(null, parameters);
445 } 445 }
446 446
447 447
448 // ECMA-262 section 15.5.4.12 448 // ECMA-262 section 15.5.4.12
449 function StringSearch(re) { 449 function StringSearch(re) {
450 var regexp = new ORIGINAL_REGEXP(re); 450 var regexp = new ORIGINAL_REGEXP(re);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 var startIndex = 0; 532 var startIndex = 0;
533 var result = []; 533 var result = [];
534 534
535 while (true) { 535 while (true) {
536 536
537 if (startIndex === length) { 537 if (startIndex === length) {
538 result[result.length] = subject.slice(currentIndex, length); 538 result[result.length] = subject.slice(currentIndex, length);
539 return result; 539 return result;
540 } 540 }
541 541
542 var lastMatchInfo = splitMatch(separator, subject, currentIndex, startIndex) ; 542 var matchInfo = splitMatch(separator, subject, currentIndex, startIndex);
543 543
544 if (IS_NULL(lastMatchInfo)) { 544 if (IS_NULL(matchInfo)) {
545 result[result.length] = subject.slice(currentIndex, length); 545 result[result.length] = subject.slice(currentIndex, length);
546 return result; 546 return result;
547 } 547 }
548 548
549 var endIndex = lastMatchInfo[CAPTURE1]; 549 var endIndex = matchInfo[CAPTURE1];
550 550
551 // We ignore a zero-length match at the currentIndex. 551 // We ignore a zero-length match at the currentIndex.
552 if (startIndex === endIndex && endIndex === currentIndex) { 552 if (startIndex === endIndex && endIndex === currentIndex) {
553 startIndex++; 553 startIndex++;
554 continue; 554 continue;
555 } 555 }
556 556
557 result[result.length] = SubString(subject, currentIndex, lastMatchInfo[CAPTU RE0]); 557 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] );
558 if (result.length === limit) return result; 558 if (result.length === limit) return result;
559 559
560 for (var i = 2; i < NUMBER_OF_CAPTURES(lastMatchInfo); i += 2) { 560 for (var i = 2; i < NUMBER_OF_CAPTURES(matchInfo); i += 2) {
561 var start = lastMatchInfo[CAPTURE(i)]; 561 var start = matchInfo[CAPTURE(i)];
562 var end = lastMatchInfo[CAPTURE(i + 1)]; 562 var end = matchInfo[CAPTURE(i + 1)];
563 if (start != -1 && end != -1) { 563 if (start != -1 && end != -1) {
564 result[result.length] = SubString(subject, start, end); 564 result[result.length] = SubString(subject, start, end);
565 } else { 565 } else {
566 result[result.length] = void 0; 566 result[result.length] = void 0;
567 } 567 }
568 if (result.length === limit) return result; 568 if (result.length === limit) return result;
569 } 569 }
570 570
571 startIndex = currentIndex = endIndex; 571 startIndex = currentIndex = endIndex;
572 } 572 }
573 } 573 }
574 574
575 575
576 // ECMA-262 section 15.5.4.14 576 // ECMA-262 section 15.5.4.14
577 // Helper function used by split. This version returns the lastMatchInfo 577 // Helper function used by split. This version returns the matchInfo
578 // instead of allocating a new array with basically the same information. 578 // instead of allocating a new array with basically the same information.
579 function splitMatch(separator, subject, current_index, start_index) { 579 function splitMatch(separator, subject, current_index, start_index) {
580 if (IS_REGEXP(separator)) { 580 if (IS_REGEXP(separator)) {
581 var lastMatchInfo = DoRegExpExec(separator, subject, start_index); 581 var matchInfo = DoRegExpExec(separator, subject, start_index);
582 if (lastMatchInfo == null) return null; 582 if (matchInfo == null) return null;
583 // Section 15.5.4.14 paragraph two says that we do not allow zero length 583 // Section 15.5.4.14 paragraph two says that we do not allow zero length
584 // matches at the end of the string. 584 // matches at the end of the string.
585 if (lastMatchInfo[CAPTURE0] === subject.length) return null; 585 if (matchInfo[CAPTURE0] === subject.length) return null;
586 return lastMatchInfo; 586 return matchInfo;
587 } 587 }
588 588
589 var separatorIndex = subject.indexOf(separator, start_index); 589 var separatorIndex = subject.indexOf(separator, start_index);
590 if (separatorIndex === -1) return null; 590 if (separatorIndex === -1) return null;
591 591
592 reusableMatchInfo[CAPTURE0] = separatorIndex; 592 reusableMatchInfo[CAPTURE0] = separatorIndex;
593 reusableMatchInfo[CAPTURE1] = separatorIndex + separator.length; 593 reusableMatchInfo[CAPTURE1] = separatorIndex + separator.length;
594 return reusableMatchInfo; 594 return reusableMatchInfo;
595 }; 595 };
596 596
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 "small", StringSmall, 867 "small", StringSmall,
868 "strike", StringStrike, 868 "strike", StringStrike,
869 "sub", StringSub, 869 "sub", StringSub,
870 "sup", StringSup, 870 "sup", StringSup,
871 "toJSON", StringToJSON 871 "toJSON", StringToJSON
872 )); 872 ));
873 } 873 }
874 874
875 875
876 SetupString(); 876 SetupString();
OLDNEW
« no previous file with comments | « src/mirror-delay.js ('k') | src/uri.js » ('j') | tools/jsmin.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698