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

Side by Side Diff: src/string.js

Issue 1149773003: Revert of Revert of Hook up more import/exports in natives. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « src/regexp.js ('k') | src/string-iterator.js » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 (function(global, utils) { 5 (function(global, utils) {
6 6
7 %CheckIsBootstrapping(); 7 %CheckIsBootstrapping();
8 8
9 // ------------------------------------------------------------------- 9 // -------------------------------------------------------------------
10 // Imports 10 // Imports
11 11
12 var GlobalRegExp = global.RegExp; 12 var GlobalRegExp = global.RegExp;
13 var GlobalString = global.String; 13 var GlobalString = global.String;
14 var InternalArray = utils.InternalArray; 14 var InternalArray = utils.InternalArray;
15 var InternalPackedArray = utils.InternalPackedArray; 15 var InternalPackedArray = utils.InternalPackedArray;
16 16
17 var MathMax; 17 var MathMax;
18 var MathMin; 18 var MathMin;
19 var RegExpExec;
20 var RegExpExecNoTests;
21 var RegExpLastMatchInfo;
19 22
20 utils.Import(function(from) { 23 utils.Import(function(from) {
21 MathMax = from.MathMax; 24 MathMax = from.MathMax;
22 MathMin = from.MathMin; 25 MathMin = from.MathMin;
26 RegExpExec = from.RegExpExec;
27 RegExpExecNoTests = from.RegExpExecNoTests;
28 RegExpLastMatchInfo = from.RegExpLastMatchInfo;
23 }); 29 });
24 30
25 //------------------------------------------------------------------- 31 //-------------------------------------------------------------------
26 32
27 function StringConstructor(x) { 33 function StringConstructor(x) {
28 if (%_ArgumentsLength() == 0) x = ''; 34 if (%_ArgumentsLength() == 0) x = '';
29 if (%_IsConstructCall()) { 35 if (%_IsConstructCall()) {
30 %_SetValueOf(this, TO_STRING_INLINE(x)); 36 %_SetValueOf(this, TO_STRING_INLINE(x));
31 } else { 37 } else {
32 return IS_SYMBOL(x) ? 38 return IS_SYMBOL(x) ?
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // ECMA-262 section 15.5.4.10 161 // ECMA-262 section 15.5.4.10
156 function StringMatchJS(regexp) { 162 function StringMatchJS(regexp) {
157 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); 163 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match");
158 164
159 var subject = TO_STRING_INLINE(this); 165 var subject = TO_STRING_INLINE(this);
160 if (IS_REGEXP(regexp)) { 166 if (IS_REGEXP(regexp)) {
161 // Emulate RegExp.prototype.exec's side effect in step 5, even though 167 // Emulate RegExp.prototype.exec's side effect in step 5, even though
162 // value is discarded. 168 // value is discarded.
163 var lastIndex = regexp.lastIndex; 169 var lastIndex = regexp.lastIndex;
164 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); 170 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
165 if (!regexp.global) return $regexpExecNoTests(regexp, subject, 0); 171 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
166 var result = %StringMatch(subject, regexp, $regexpLastMatchInfo); 172 var result = %StringMatch(subject, regexp, RegExpLastMatchInfo);
167 if (result !== null) $regexpLastMatchInfoOverride = null; 173 if (result !== null) $regexpLastMatchInfoOverride = null;
168 regexp.lastIndex = 0; 174 regexp.lastIndex = 0;
169 return result; 175 return result;
170 } 176 }
171 // Non-regexp argument. 177 // Non-regexp argument.
172 regexp = new GlobalRegExp(regexp); 178 regexp = new GlobalRegExp(regexp);
173 return $regexpExecNoTests(regexp, subject, 0); 179 return RegExpExecNoTests(regexp, subject, 0);
174 } 180 }
175 181
176 182
177 // ECMA-262 v6, section 21.1.3.12 183 // ECMA-262 v6, section 21.1.3.12
178 // 184 //
179 // For now we do nothing, as proper normalization requires big tables. 185 // For now we do nothing, as proper normalization requires big tables.
180 // If Intl is enabled, then i18n.js will override it and provide the the 186 // If Intl is enabled, then i18n.js will override it and provide the the
181 // proper functionality. 187 // proper functionality.
182 function StringNormalizeJS(form) { 188 function StringNormalizeJS(form) {
183 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); 189 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
184 190
185 var form = form ? TO_STRING_INLINE(form) : 'NFC'; 191 var form = form ? TO_STRING_INLINE(form) : 'NFC';
186 192
187 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; 193 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
188 194
189 var normalizationForm = NORMALIZATION_FORMS.indexOf(form); 195 var normalizationForm = NORMALIZATION_FORMS.indexOf(form);
190 if (normalizationForm === -1) { 196 if (normalizationForm === -1) {
191 throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); 197 throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', '));
192 } 198 }
193 199
194 return %_ValueOf(this); 200 return %_ValueOf(this);
195 } 201 }
196 202
197 203
198 // This has the same size as the $regexpLastMatchInfo array, and can be used 204 // This has the same size as the RegExpLastMatchInfo array, and can be used
199 // for functions that expect that structure to be returned. It is used when 205 // for functions that expect that structure to be returned. It is used when
200 // the needle is a string rather than a regexp. In this case we can't update 206 // the needle is a string rather than a regexp. In this case we can't update
201 // lastMatchArray without erroneously affecting the properties on the global 207 // lastMatchArray without erroneously affecting the properties on the global
202 // RegExp object. 208 // RegExp object.
203 var reusableMatchInfo = [2, "", "", -1, -1]; 209 var reusableMatchInfo = [2, "", "", -1, -1];
204 210
205 211
206 // ECMA-262, section 15.5.4.11 212 // ECMA-262, section 15.5.4.11
207 function StringReplace(search, replace) { 213 function StringReplace(search, replace) {
208 CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); 214 CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace");
(...skipping 21 matching lines...) Expand all
230 // Emulate RegExp.prototype.exec's side effect in step 5, even if 236 // Emulate RegExp.prototype.exec's side effect in step 5, even if
231 // value is discarded. 237 // value is discarded.
232 var lastIndex = search.lastIndex; 238 var lastIndex = search.lastIndex;
233 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); 239 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
234 240
235 if (!IS_SPEC_FUNCTION(replace)) { 241 if (!IS_SPEC_FUNCTION(replace)) {
236 replace = TO_STRING_INLINE(replace); 242 replace = TO_STRING_INLINE(replace);
237 243
238 if (!search.global) { 244 if (!search.global) {
239 // Non-global regexp search, string replace. 245 // Non-global regexp search, string replace.
240 var match = $regexpExec(search, subject, 0); 246 var match = RegExpExec(search, subject, 0);
241 if (match == null) { 247 if (match == null) {
242 search.lastIndex = 0 248 search.lastIndex = 0
243 return subject; 249 return subject;
244 } 250 }
245 if (replace.length == 0) { 251 if (replace.length == 0) {
246 return %_SubString(subject, 0, match[CAPTURE0]) + 252 return %_SubString(subject, 0, match[CAPTURE0]) +
247 %_SubString(subject, match[CAPTURE1], subject.length) 253 %_SubString(subject, match[CAPTURE1], subject.length)
248 } 254 }
249 return ExpandReplacement(replace, subject, $regexpLastMatchInfo, 255 return ExpandReplacement(replace, subject, RegExpLastMatchInfo,
250 %_SubString(subject, 0, match[CAPTURE0])) + 256 %_SubString(subject, 0, match[CAPTURE0])) +
251 %_SubString(subject, match[CAPTURE1], subject.length); 257 %_SubString(subject, match[CAPTURE1], subject.length);
252 } 258 }
253 259
254 // Global regexp search, string replace. 260 // Global regexp search, string replace.
255 search.lastIndex = 0; 261 search.lastIndex = 0;
256 if ($regexpLastMatchInfoOverride == null) { 262 if ($regexpLastMatchInfoOverride == null) {
257 return %StringReplaceGlobalRegExpWithString( 263 return %StringReplaceGlobalRegExpWithString(
258 subject, search, replace, $regexpLastMatchInfo); 264 subject, search, replace, RegExpLastMatchInfo);
259 } else { 265 } else {
260 // We use this hack to detect whether StringReplaceRegExpWithString 266 // We use this hack to detect whether StringReplaceRegExpWithString
261 // found at least one hit. In that case we need to remove any 267 // found at least one hit. In that case we need to remove any
262 // override. 268 // override.
263 var saved_subject = $regexpLastMatchInfo[LAST_SUBJECT_INDEX]; 269 var saved_subject = RegExpLastMatchInfo[LAST_SUBJECT_INDEX];
264 $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = 0; 270 RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = 0;
265 var answer = %StringReplaceGlobalRegExpWithString( 271 var answer = %StringReplaceGlobalRegExpWithString(
266 subject, search, replace, $regexpLastMatchInfo); 272 subject, search, replace, RegExpLastMatchInfo);
267 if (%_IsSmi($regexpLastMatchInfo[LAST_SUBJECT_INDEX])) { 273 if (%_IsSmi(RegExpLastMatchInfo[LAST_SUBJECT_INDEX])) {
268 $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; 274 RegExpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
269 } else { 275 } else {
270 $regexpLastMatchInfoOverride = null; 276 $regexpLastMatchInfoOverride = null;
271 } 277 }
272 return answer; 278 return answer;
273 } 279 }
274 } 280 }
275 281
276 if (search.global) { 282 if (search.global) {
277 // Global regexp search, function replace. 283 // Global regexp search, function replace.
278 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); 284 return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 reusableReplaceArray = null; 430 reusableReplaceArray = null;
425 } else { 431 } else {
426 // Inside a nested replace (replace called from the replacement function 432 // Inside a nested replace (replace called from the replacement function
427 // of another replace) or we have failed to set the reusable array 433 // of another replace) or we have failed to set the reusable array
428 // back due to an exception in a replacement function. Create a new 434 // back due to an exception in a replacement function. Create a new
429 // array to use in the future, or until the original is written back. 435 // array to use in the future, or until the original is written back.
430 resultArray = new InternalArray(16); 436 resultArray = new InternalArray(16);
431 } 437 }
432 var res = %RegExpExecMultiple(regexp, 438 var res = %RegExpExecMultiple(regexp,
433 subject, 439 subject,
434 $regexpLastMatchInfo, 440 RegExpLastMatchInfo,
435 resultArray); 441 resultArray);
436 regexp.lastIndex = 0; 442 regexp.lastIndex = 0;
437 if (IS_NULL(res)) { 443 if (IS_NULL(res)) {
438 // No matches at all. 444 // No matches at all.
439 reusableReplaceArray = resultArray; 445 reusableReplaceArray = resultArray;
440 return subject; 446 return subject;
441 } 447 }
442 var len = res.length; 448 var len = res.length;
443 if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) { 449 if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
444 // If the number of captures is two then there are no explicit captures in 450 // If the number of captures is two then there are no explicit captures in
445 // the regexp, just the implicit capture that captures the whole match. In 451 // the regexp, just the implicit capture that captures the whole match. In
446 // this case we can simplify quite a bit and end up with something faster. 452 // this case we can simplify quite a bit and end up with something faster.
447 // The builder will consist of some integers that indicate slices of the 453 // The builder will consist of some integers that indicate slices of the
448 // input string and some replacements that were returned from the replace 454 // input string and some replacements that were returned from the replace
449 // function. 455 // function.
450 var match_start = 0; 456 var match_start = 0;
451 var override = new InternalPackedArray(null, 0, subject); 457 var override = new InternalPackedArray(null, 0, subject);
452 for (var i = 0; i < len; i++) { 458 for (var i = 0; i < len; i++) {
453 var elem = res[i]; 459 var elem = res[i];
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 } 493 }
488 } 494 }
489 var result = %StringBuilderConcat(res, res.length, subject); 495 var result = %StringBuilderConcat(res, res.length, subject);
490 resultArray.length = 0; 496 resultArray.length = 0;
491 reusableReplaceArray = resultArray; 497 reusableReplaceArray = resultArray;
492 return result; 498 return result;
493 } 499 }
494 500
495 501
496 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { 502 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
497 var matchInfo = $regexpExec(regexp, subject, 0); 503 var matchInfo = RegExpExec(regexp, subject, 0);
498 if (IS_NULL(matchInfo)) { 504 if (IS_NULL(matchInfo)) {
499 regexp.lastIndex = 0; 505 regexp.lastIndex = 0;
500 return subject; 506 return subject;
501 } 507 }
502 var index = matchInfo[CAPTURE0]; 508 var index = matchInfo[CAPTURE0];
503 var result = %_SubString(subject, 0, index); 509 var result = %_SubString(subject, 0, index);
504 var endOfMatch = matchInfo[CAPTURE1]; 510 var endOfMatch = matchInfo[CAPTURE1];
505 // Compute the parameter list consisting of the match, captures, index, 511 // Compute the parameter list consisting of the match, captures, index,
506 // and subject for the replace function invocation. 512 // and subject for the replace function invocation.
507 // The number of captures plus one for the match. 513 // The number of captures plus one for the match.
(...skipping 27 matching lines...) Expand all
535 CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); 541 CHECK_OBJECT_COERCIBLE(this, "String.prototype.search");
536 542
537 var regexp; 543 var regexp;
538 if (IS_STRING(re)) { 544 if (IS_STRING(re)) {
539 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); 545 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re);
540 } else if (IS_REGEXP(re)) { 546 } else if (IS_REGEXP(re)) {
541 regexp = re; 547 regexp = re;
542 } else { 548 } else {
543 regexp = new GlobalRegExp(re); 549 regexp = new GlobalRegExp(re);
544 } 550 }
545 var match = $regexpExec(regexp, TO_STRING_INLINE(this), 0); 551 var match = RegExpExec(regexp, TO_STRING_INLINE(this), 0);
546 if (match) { 552 if (match) {
547 return match[CAPTURE0]; 553 return match[CAPTURE0];
548 } 554 }
549 return -1; 555 return -1;
550 } 556 }
551 557
552 558
553 // ECMA-262 section 15.5.4.13 559 // ECMA-262 section 15.5.4.13
554 function StringSlice(start, end) { 560 function StringSlice(start, end) {
555 CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice"); 561 CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice");
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 627
622 if (limit === 0) return []; 628 if (limit === 0) return [];
623 629
624 // Separator is a regular expression. 630 // Separator is a regular expression.
625 return StringSplitOnRegExp(subject, separator, limit, length); 631 return StringSplitOnRegExp(subject, separator, limit, length);
626 } 632 }
627 633
628 634
629 function StringSplitOnRegExp(subject, separator, limit, length) { 635 function StringSplitOnRegExp(subject, separator, limit, length) {
630 if (length === 0) { 636 if (length === 0) {
631 if ($regexpExec(separator, subject, 0, 0) != null) { 637 if (RegExpExec(separator, subject, 0, 0) != null) {
632 return []; 638 return [];
633 } 639 }
634 return [subject]; 640 return [subject];
635 } 641 }
636 642
637 var currentIndex = 0; 643 var currentIndex = 0;
638 var startIndex = 0; 644 var startIndex = 0;
639 var startMatch = 0; 645 var startMatch = 0;
640 var result = new InternalArray(); 646 var result = new InternalArray();
641 647
642 outer_loop: 648 outer_loop:
643 while (true) { 649 while (true) {
644 650
645 if (startIndex === length) { 651 if (startIndex === length) {
646 result[result.length] = %_SubString(subject, currentIndex, length); 652 result[result.length] = %_SubString(subject, currentIndex, length);
647 break; 653 break;
648 } 654 }
649 655
650 var matchInfo = $regexpExec(separator, subject, startIndex); 656 var matchInfo = RegExpExec(separator, subject, startIndex);
651 if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { 657 if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) {
652 result[result.length] = %_SubString(subject, currentIndex, length); 658 result[result.length] = %_SubString(subject, currentIndex, length);
653 break; 659 break;
654 } 660 }
655 var endIndex = matchInfo[CAPTURE1]; 661 var endIndex = matchInfo[CAPTURE1];
656 662
657 // We ignore a zero-length match at the currentIndex. 663 // We ignore a zero-length match at the currentIndex.
658 if (startIndex === endIndex && endIndex === currentIndex) { 664 if (startIndex === endIndex && endIndex === currentIndex) {
659 startIndex++; 665 startIndex++;
660 continue; 666 continue;
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 1123
1118 // Set the String function and constructor. 1124 // Set the String function and constructor.
1119 %SetCode(GlobalString, StringConstructor); 1125 %SetCode(GlobalString, StringConstructor);
1120 %FunctionSetPrototype(GlobalString, new GlobalString()); 1126 %FunctionSetPrototype(GlobalString, new GlobalString());
1121 1127
1122 // Set up the constructor property on the String prototype object. 1128 // Set up the constructor property on the String prototype object.
1123 %AddNamedProperty( 1129 %AddNamedProperty(
1124 GlobalString.prototype, "constructor", GlobalString, DONT_ENUM); 1130 GlobalString.prototype, "constructor", GlobalString, DONT_ENUM);
1125 1131
1126 // Set up the non-enumerable functions on the String object. 1132 // Set up the non-enumerable functions on the String object.
1127 $installFunctions(GlobalString, DONT_ENUM, [ 1133 utils.InstallFunctions(GlobalString, DONT_ENUM, [
1128 "fromCharCode", StringFromCharCode, 1134 "fromCharCode", StringFromCharCode,
1129 "fromCodePoint", StringFromCodePoint, 1135 "fromCodePoint", StringFromCodePoint,
1130 "raw", StringRaw 1136 "raw", StringRaw
1131 ]); 1137 ]);
1132 1138
1133 // Set up the non-enumerable functions on the String prototype object. 1139 // Set up the non-enumerable functions on the String prototype object.
1134 $installFunctions(GlobalString.prototype, DONT_ENUM, [ 1140 utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
1135 "valueOf", StringValueOf, 1141 "valueOf", StringValueOf,
1136 "toString", StringToString, 1142 "toString", StringToString,
1137 "charAt", StringCharAtJS, 1143 "charAt", StringCharAtJS,
1138 "charCodeAt", StringCharCodeAtJS, 1144 "charCodeAt", StringCharCodeAtJS,
1139 "codePointAt", StringCodePointAt, 1145 "codePointAt", StringCodePointAt,
1140 "concat", StringConcat, 1146 "concat", StringConcat,
1141 "endsWith", StringEndsWith, 1147 "endsWith", StringEndsWith,
1142 "includes", StringIncludes, 1148 "includes", StringIncludes,
1143 "indexOf", StringIndexOfJS, 1149 "indexOf", StringIndexOfJS,
1144 "lastIndexOf", StringLastIndexOfJS, 1150 "lastIndexOf", StringLastIndexOfJS,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 // ------------------------------------------------------------------- 1185 // -------------------------------------------------------------------
1180 // Exports 1186 // Exports
1181 1187
1182 utils.Export(function(to) { 1188 utils.Export(function(to) {
1183 to.StringCharAt = StringCharAtJS; 1189 to.StringCharAt = StringCharAtJS;
1184 to.StringIndexOf = StringIndexOfJS; 1190 to.StringIndexOf = StringIndexOfJS;
1185 to.StringSubstring = StringSubstring; 1191 to.StringSubstring = StringSubstring;
1186 }); 1192 });
1187 1193
1188 }) 1194 })
OLDNEW
« no previous file with comments | « src/regexp.js ('k') | src/string-iterator.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698