| OLD | NEW |
| 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 // This file relies on the fact that the following declaration has been made | 5 var $stringCharAt; |
| 6 // in runtime.js: | 6 var $stringIndexOf; |
| 7 // var $String = global.String; | 7 var $stringSubstring; |
| 8 | 8 |
| 9 // ------------------------------------------------------------------- | 9 (function() { |
| 10 |
| 11 %CheckIsBootstrapping(); |
| 12 |
| 13 var GlobalArray = global.Array; |
| 14 var GlobalRegExp = global.RegExp; |
| 15 var GlobalString = global.String; |
| 16 |
| 17 //------------------------------------------------------------------- |
| 10 | 18 |
| 11 function StringConstructor(x) { | 19 function StringConstructor(x) { |
| 12 if (%_ArgumentsLength() == 0) x = ''; | 20 if (%_ArgumentsLength() == 0) x = ''; |
| 13 if (%_IsConstructCall()) { | 21 if (%_IsConstructCall()) { |
| 14 %_SetValueOf(this, TO_STRING_INLINE(x)); | 22 %_SetValueOf(this, TO_STRING_INLINE(x)); |
| 15 } else { | 23 } else { |
| 16 return IS_SYMBOL(x) ? | 24 return IS_SYMBOL(x) ? |
| 17 %_CallFunction(x, SymbolToString) : TO_STRING_INLINE(x); | 25 %_CallFunction(x, SymbolToString) : TO_STRING_INLINE(x); |
| 18 } | 26 } |
| 19 } | 27 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 // ECMA-262 section 15.5.4.10 | 148 // ECMA-262 section 15.5.4.10 |
| 141 function StringMatchJS(regexp) { | 149 function StringMatchJS(regexp) { |
| 142 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); | 150 CHECK_OBJECT_COERCIBLE(this, "String.prototype.match"); |
| 143 | 151 |
| 144 var subject = TO_STRING_INLINE(this); | 152 var subject = TO_STRING_INLINE(this); |
| 145 if (IS_REGEXP(regexp)) { | 153 if (IS_REGEXP(regexp)) { |
| 146 // Emulate RegExp.prototype.exec's side effect in step 5, even though | 154 // Emulate RegExp.prototype.exec's side effect in step 5, even though |
| 147 // value is discarded. | 155 // value is discarded. |
| 148 var lastIndex = regexp.lastIndex; | 156 var lastIndex = regexp.lastIndex; |
| 149 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 157 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); |
| 150 if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); | 158 if (!regexp.global) return $regexpExecNoTests(regexp, subject, 0); |
| 151 // lastMatchInfo is defined in regexp.js. | 159 var result = %StringMatch(subject, regexp, $regexpLastMatchInfo); |
| 152 var result = %StringMatch(subject, regexp, lastMatchInfo); | 160 if (result !== null) $regexpLastMatchInfoOverride = null; |
| 153 if (result !== null) lastMatchInfoOverride = null; | |
| 154 regexp.lastIndex = 0; | 161 regexp.lastIndex = 0; |
| 155 return result; | 162 return result; |
| 156 } | 163 } |
| 157 // Non-regexp argument. | 164 // Non-regexp argument. |
| 158 regexp = new $RegExp(regexp); | 165 regexp = new GlobalRegExp(regexp); |
| 159 return RegExpExecNoTests(regexp, subject, 0); | 166 return $regexpExecNoTests(regexp, subject, 0); |
| 160 } | 167 } |
| 161 | 168 |
| 162 | 169 |
| 163 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; | 170 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; |
| 164 | 171 |
| 165 | 172 |
| 166 // ECMA-262 v6, section 21.1.3.12 | 173 // ECMA-262 v6, section 21.1.3.12 |
| 167 // | 174 // |
| 168 // For now we do nothing, as proper normalization requires big tables. | 175 // For now we do nothing, as proper normalization requires big tables. |
| 169 // If Intl is enabled, then i18n.js will override it and provide the the | 176 // If Intl is enabled, then i18n.js will override it and provide the the |
| 170 // proper functionality. | 177 // proper functionality. |
| 171 function StringNormalizeJS(form) { | 178 function StringNormalizeJS(form) { |
| 172 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); | 179 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); |
| 173 | 180 |
| 174 var form = form ? TO_STRING_INLINE(form) : 'NFC'; | 181 var form = form ? TO_STRING_INLINE(form) : 'NFC'; |
| 175 var normalizationForm = NORMALIZATION_FORMS.indexOf(form); | 182 var normalizationForm = NORMALIZATION_FORMS.indexOf(form); |
| 176 if (normalizationForm === -1) { | 183 if (normalizationForm === -1) { |
| 177 throw new $RangeError('The normalization form should be one of ' | 184 throw new $RangeError('The normalization form should be one of ' |
| 178 + NORMALIZATION_FORMS.join(', ') + '.'); | 185 + NORMALIZATION_FORMS.join(', ') + '.'); |
| 179 } | 186 } |
| 180 | 187 |
| 181 return %_ValueOf(this); | 188 return %_ValueOf(this); |
| 182 } | 189 } |
| 183 | 190 |
| 184 | 191 |
| 185 // This has the same size as the lastMatchInfo array, and can be used for | 192 // This has the same size as the $regexpLastMatchInfo array, and can be used |
| 186 // functions that expect that structure to be returned. It is used when the | 193 // for functions that expect that structure to be returned. It is used when |
| 187 // needle is a string rather than a regexp. In this case we can't update | 194 // the needle is a string rather than a regexp. In this case we can't update |
| 188 // lastMatchArray without erroneously affecting the properties on the global | 195 // lastMatchArray without erroneously affecting the properties on the global |
| 189 // RegExp object. | 196 // RegExp object. |
| 190 var reusableMatchInfo = [2, "", "", -1, -1]; | 197 var reusableMatchInfo = [2, "", "", -1, -1]; |
| 191 | 198 |
| 192 | 199 |
| 193 // ECMA-262, section 15.5.4.11 | 200 // ECMA-262, section 15.5.4.11 |
| 194 function StringReplace(search, replace) { | 201 function StringReplace(search, replace) { |
| 195 CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); | 202 CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); |
| 196 | 203 |
| 197 var subject = TO_STRING_INLINE(this); | 204 var subject = TO_STRING_INLINE(this); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 217 // Emulate RegExp.prototype.exec's side effect in step 5, even if | 224 // Emulate RegExp.prototype.exec's side effect in step 5, even if |
| 218 // value is discarded. | 225 // value is discarded. |
| 219 var lastIndex = search.lastIndex; | 226 var lastIndex = search.lastIndex; |
| 220 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); | 227 TO_INTEGER_FOR_SIDE_EFFECT(lastIndex); |
| 221 | 228 |
| 222 if (!IS_SPEC_FUNCTION(replace)) { | 229 if (!IS_SPEC_FUNCTION(replace)) { |
| 223 replace = TO_STRING_INLINE(replace); | 230 replace = TO_STRING_INLINE(replace); |
| 224 | 231 |
| 225 if (!search.global) { | 232 if (!search.global) { |
| 226 // Non-global regexp search, string replace. | 233 // Non-global regexp search, string replace. |
| 227 var match = DoRegExpExec(search, subject, 0); | 234 var match = $regexpExec(search, subject, 0); |
| 228 if (match == null) { | 235 if (match == null) { |
| 229 search.lastIndex = 0 | 236 search.lastIndex = 0 |
| 230 return subject; | 237 return subject; |
| 231 } | 238 } |
| 232 if (replace.length == 0) { | 239 if (replace.length == 0) { |
| 233 return %_SubString(subject, 0, match[CAPTURE0]) + | 240 return %_SubString(subject, 0, match[CAPTURE0]) + |
| 234 %_SubString(subject, match[CAPTURE1], subject.length) | 241 %_SubString(subject, match[CAPTURE1], subject.length) |
| 235 } | 242 } |
| 236 return ExpandReplacement(replace, subject, lastMatchInfo, | 243 return ExpandReplacement(replace, subject, $regexpLastMatchInfo, |
| 237 %_SubString(subject, 0, match[CAPTURE0])) + | 244 %_SubString(subject, 0, match[CAPTURE0])) + |
| 238 %_SubString(subject, match[CAPTURE1], subject.length); | 245 %_SubString(subject, match[CAPTURE1], subject.length); |
| 239 } | 246 } |
| 240 | 247 |
| 241 // Global regexp search, string replace. | 248 // Global regexp search, string replace. |
| 242 search.lastIndex = 0; | 249 search.lastIndex = 0; |
| 243 if (lastMatchInfoOverride == null) { | 250 if ($regexpLastMatchInfoOverride == null) { |
| 244 return %StringReplaceGlobalRegExpWithString( | 251 return %StringReplaceGlobalRegExpWithString( |
| 245 subject, search, replace, lastMatchInfo); | 252 subject, search, replace, $regexpLastMatchInfo); |
| 246 } else { | 253 } else { |
| 247 // We use this hack to detect whether StringReplaceRegExpWithString | 254 // We use this hack to detect whether StringReplaceRegExpWithString |
| 248 // found at least one hit. In that case we need to remove any | 255 // found at least one hit. In that case we need to remove any |
| 249 // override. | 256 // override. |
| 250 var saved_subject = lastMatchInfo[LAST_SUBJECT_INDEX]; | 257 var saved_subject = $regexpLastMatchInfo[LAST_SUBJECT_INDEX]; |
| 251 lastMatchInfo[LAST_SUBJECT_INDEX] = 0; | 258 $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = 0; |
| 252 var answer = %StringReplaceGlobalRegExpWithString( | 259 var answer = %StringReplaceGlobalRegExpWithString( |
| 253 subject, search, replace, lastMatchInfo); | 260 subject, search, replace, $regexpLastMatchInfo); |
| 254 if (%_IsSmi(lastMatchInfo[LAST_SUBJECT_INDEX])) { | 261 if (%_IsSmi($regexpLastMatchInfo[LAST_SUBJECT_INDEX])) { |
| 255 lastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; | 262 $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; |
| 256 } else { | 263 } else { |
| 257 lastMatchInfoOverride = null; | 264 $regexpLastMatchInfoOverride = null; |
| 258 } | 265 } |
| 259 return answer; | 266 return answer; |
| 260 } | 267 } |
| 261 } | 268 } |
| 262 | 269 |
| 263 if (search.global) { | 270 if (search.global) { |
| 264 // Global regexp search, function replace. | 271 // Global regexp search, function replace. |
| 265 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); | 272 return StringReplaceGlobalRegExpWithFunction(subject, search, replace); |
| 266 } | 273 } |
| 267 // Non-global regexp search, function replace. | 274 // Non-global regexp search, function replace. |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 reusableReplaceArray = null; | 418 reusableReplaceArray = null; |
| 412 } else { | 419 } else { |
| 413 // Inside a nested replace (replace called from the replacement function | 420 // Inside a nested replace (replace called from the replacement function |
| 414 // of another replace) or we have failed to set the reusable array | 421 // of another replace) or we have failed to set the reusable array |
| 415 // back due to an exception in a replacement function. Create a new | 422 // back due to an exception in a replacement function. Create a new |
| 416 // array to use in the future, or until the original is written back. | 423 // array to use in the future, or until the original is written back. |
| 417 resultArray = new InternalArray(16); | 424 resultArray = new InternalArray(16); |
| 418 } | 425 } |
| 419 var res = %RegExpExecMultiple(regexp, | 426 var res = %RegExpExecMultiple(regexp, |
| 420 subject, | 427 subject, |
| 421 lastMatchInfo, | 428 $regexpLastMatchInfo, |
| 422 resultArray); | 429 resultArray); |
| 423 regexp.lastIndex = 0; | 430 regexp.lastIndex = 0; |
| 424 if (IS_NULL(res)) { | 431 if (IS_NULL(res)) { |
| 425 // No matches at all. | 432 // No matches at all. |
| 426 reusableReplaceArray = resultArray; | 433 reusableReplaceArray = resultArray; |
| 427 return subject; | 434 return subject; |
| 428 } | 435 } |
| 429 var len = res.length; | 436 var len = res.length; |
| 430 if (NUMBER_OF_CAPTURES(lastMatchInfo) == 2) { | 437 if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) { |
| 431 // If the number of captures is two then there are no explicit captures in | 438 // If the number of captures is two then there are no explicit captures in |
| 432 // the regexp, just the implicit capture that captures the whole match. In | 439 // the regexp, just the implicit capture that captures the whole match. In |
| 433 // this case we can simplify quite a bit and end up with something faster. | 440 // this case we can simplify quite a bit and end up with something faster. |
| 434 // The builder will consist of some integers that indicate slices of the | 441 // The builder will consist of some integers that indicate slices of the |
| 435 // input string and some replacements that were returned from the replace | 442 // input string and some replacements that were returned from the replace |
| 436 // function. | 443 // function. |
| 437 var match_start = 0; | 444 var match_start = 0; |
| 438 var override = new InternalPackedArray(null, 0, subject); | 445 var override = new InternalPackedArray(null, 0, subject); |
| 439 var receiver = %GetDefaultReceiver(replace); | 446 var receiver = %GetDefaultReceiver(replace); |
| 440 for (var i = 0; i < len; i++) { | 447 for (var i = 0; i < len; i++) { |
| 441 var elem = res[i]; | 448 var elem = res[i]; |
| 442 if (%_IsSmi(elem)) { | 449 if (%_IsSmi(elem)) { |
| 443 // Integers represent slices of the original string. Use these to | 450 // Integers represent slices of the original string. Use these to |
| 444 // get the offsets we need for the override array (so things like | 451 // get the offsets we need for the override array (so things like |
| 445 // RegExp.leftContext work during the callback function. | 452 // RegExp.leftContext work during the callback function. |
| 446 if (elem > 0) { | 453 if (elem > 0) { |
| 447 match_start = (elem >> 11) + (elem & 0x7ff); | 454 match_start = (elem >> 11) + (elem & 0x7ff); |
| 448 } else { | 455 } else { |
| 449 match_start = res[++i] - elem; | 456 match_start = res[++i] - elem; |
| 450 } | 457 } |
| 451 } else { | 458 } else { |
| 452 override[0] = elem; | 459 override[0] = elem; |
| 453 override[1] = match_start; | 460 override[1] = match_start; |
| 454 lastMatchInfoOverride = override; | 461 $regexpLastMatchInfoOverride = override; |
| 455 var func_result = | 462 var func_result = |
| 456 %_CallFunction(receiver, elem, match_start, subject, replace); | 463 %_CallFunction(receiver, elem, match_start, subject, replace); |
| 457 // Overwrite the i'th element in the results with the string we got | 464 // Overwrite the i'th element in the results with the string we got |
| 458 // back from the callback function. | 465 // back from the callback function. |
| 459 res[i] = TO_STRING_INLINE(func_result); | 466 res[i] = TO_STRING_INLINE(func_result); |
| 460 match_start += elem.length; | 467 match_start += elem.length; |
| 461 } | 468 } |
| 462 } | 469 } |
| 463 } else { | 470 } else { |
| 464 var receiver = %GetDefaultReceiver(replace); | 471 var receiver = %GetDefaultReceiver(replace); |
| 465 for (var i = 0; i < len; i++) { | 472 for (var i = 0; i < len; i++) { |
| 466 var elem = res[i]; | 473 var elem = res[i]; |
| 467 if (!%_IsSmi(elem)) { | 474 if (!%_IsSmi(elem)) { |
| 468 // elem must be an Array. | 475 // elem must be an Array. |
| 469 // Use the apply argument as backing for global RegExp properties. | 476 // Use the apply argument as backing for global RegExp properties. |
| 470 lastMatchInfoOverride = elem; | 477 $regexpLastMatchInfoOverride = elem; |
| 471 var func_result = %Apply(replace, receiver, elem, 0, elem.length); | 478 var func_result = %Apply(replace, receiver, elem, 0, elem.length); |
| 472 // Overwrite the i'th element in the results with the string we got | 479 // Overwrite the i'th element in the results with the string we got |
| 473 // back from the callback function. | 480 // back from the callback function. |
| 474 res[i] = TO_STRING_INLINE(func_result); | 481 res[i] = TO_STRING_INLINE(func_result); |
| 475 } | 482 } |
| 476 } | 483 } |
| 477 } | 484 } |
| 478 var result = %StringBuilderConcat(res, res.length, subject); | 485 var result = %StringBuilderConcat(res, res.length, subject); |
| 479 resultArray.length = 0; | 486 resultArray.length = 0; |
| 480 reusableReplaceArray = resultArray; | 487 reusableReplaceArray = resultArray; |
| 481 return result; | 488 return result; |
| 482 } | 489 } |
| 483 | 490 |
| 484 | 491 |
| 485 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { | 492 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { |
| 486 var matchInfo = DoRegExpExec(regexp, subject, 0); | 493 var matchInfo = $regexpExec(regexp, subject, 0); |
| 487 if (IS_NULL(matchInfo)) { | 494 if (IS_NULL(matchInfo)) { |
| 488 regexp.lastIndex = 0; | 495 regexp.lastIndex = 0; |
| 489 return subject; | 496 return subject; |
| 490 } | 497 } |
| 491 var index = matchInfo[CAPTURE0]; | 498 var index = matchInfo[CAPTURE0]; |
| 492 var result = %_SubString(subject, 0, index); | 499 var result = %_SubString(subject, 0, index); |
| 493 var endOfMatch = matchInfo[CAPTURE1]; | 500 var endOfMatch = matchInfo[CAPTURE1]; |
| 494 // Compute the parameter list consisting of the match, captures, index, | 501 // Compute the parameter list consisting of the match, captures, index, |
| 495 // and subject for the replace function invocation. | 502 // and subject for the replace function invocation. |
| 496 // The number of captures plus one for the match. | 503 // The number of captures plus one for the match. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 523 // ECMA-262 section 15.5.4.12 | 530 // ECMA-262 section 15.5.4.12 |
| 524 function StringSearch(re) { | 531 function StringSearch(re) { |
| 525 CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); | 532 CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); |
| 526 | 533 |
| 527 var regexp; | 534 var regexp; |
| 528 if (IS_STRING(re)) { | 535 if (IS_STRING(re)) { |
| 529 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); | 536 regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); |
| 530 } else if (IS_REGEXP(re)) { | 537 } else if (IS_REGEXP(re)) { |
| 531 regexp = re; | 538 regexp = re; |
| 532 } else { | 539 } else { |
| 533 regexp = new $RegExp(re); | 540 regexp = new GlobalRegExp(re); |
| 534 } | 541 } |
| 535 var match = DoRegExpExec(regexp, TO_STRING_INLINE(this), 0); | 542 var match = $regexpExec(regexp, TO_STRING_INLINE(this), 0); |
| 536 if (match) { | 543 if (match) { |
| 537 return match[CAPTURE0]; | 544 return match[CAPTURE0]; |
| 538 } | 545 } |
| 539 return -1; | 546 return -1; |
| 540 } | 547 } |
| 541 | 548 |
| 542 | 549 |
| 543 // ECMA-262 section 15.5.4.13 | 550 // ECMA-262 section 15.5.4.13 |
| 544 function StringSlice(start, end) { | 551 function StringSlice(start, end) { |
| 545 CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice"); | 552 CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice"); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 618 |
| 612 if (limit === 0) return []; | 619 if (limit === 0) return []; |
| 613 | 620 |
| 614 // Separator is a regular expression. | 621 // Separator is a regular expression. |
| 615 return StringSplitOnRegExp(subject, separator, limit, length); | 622 return StringSplitOnRegExp(subject, separator, limit, length); |
| 616 } | 623 } |
| 617 | 624 |
| 618 | 625 |
| 619 function StringSplitOnRegExp(subject, separator, limit, length) { | 626 function StringSplitOnRegExp(subject, separator, limit, length) { |
| 620 if (length === 0) { | 627 if (length === 0) { |
| 621 if (DoRegExpExec(separator, subject, 0, 0) != null) { | 628 if ($regexpExec(separator, subject, 0, 0) != null) { |
| 622 return []; | 629 return []; |
| 623 } | 630 } |
| 624 return [subject]; | 631 return [subject]; |
| 625 } | 632 } |
| 626 | 633 |
| 627 var currentIndex = 0; | 634 var currentIndex = 0; |
| 628 var startIndex = 0; | 635 var startIndex = 0; |
| 629 var startMatch = 0; | 636 var startMatch = 0; |
| 630 var result = new InternalArray(); | 637 var result = new InternalArray(); |
| 631 | 638 |
| 632 outer_loop: | 639 outer_loop: |
| 633 while (true) { | 640 while (true) { |
| 634 | 641 |
| 635 if (startIndex === length) { | 642 if (startIndex === length) { |
| 636 result[result.length] = %_SubString(subject, currentIndex, length); | 643 result[result.length] = %_SubString(subject, currentIndex, length); |
| 637 break; | 644 break; |
| 638 } | 645 } |
| 639 | 646 |
| 640 var matchInfo = DoRegExpExec(separator, subject, startIndex); | 647 var matchInfo = $regexpExec(separator, subject, startIndex); |
| 641 if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { | 648 if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { |
| 642 result[result.length] = %_SubString(subject, currentIndex, length); | 649 result[result.length] = %_SubString(subject, currentIndex, length); |
| 643 break; | 650 break; |
| 644 } | 651 } |
| 645 var endIndex = matchInfo[CAPTURE1]; | 652 var endIndex = matchInfo[CAPTURE1]; |
| 646 | 653 |
| 647 // We ignore a zero-length match at the currentIndex. | 654 // We ignore a zero-length match at the currentIndex. |
| 648 if (startIndex === endIndex && endIndex === currentIndex) { | 655 if (startIndex === endIndex && endIndex === currentIndex) { |
| 649 startIndex++; | 656 startIndex++; |
| 650 continue; | 657 continue; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 | 926 |
| 920 | 927 |
| 921 // ES6 draft, revision 26 (2014-07-18), section B.2.3.14 | 928 // ES6 draft, revision 26 (2014-07-18), section B.2.3.14 |
| 922 function StringSup() { | 929 function StringSup() { |
| 923 CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup"); | 930 CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup"); |
| 924 return "<sup>" + this + "</sup>"; | 931 return "<sup>" + this + "</sup>"; |
| 925 } | 932 } |
| 926 | 933 |
| 927 // ------------------------------------------------------------------- | 934 // ------------------------------------------------------------------- |
| 928 | 935 |
| 929 function SetUpString() { | 936 // Set the String function and constructor. |
| 930 %CheckIsBootstrapping(); | 937 %SetCode(GlobalString, StringConstructor); |
| 938 %FunctionSetPrototype(GlobalString, new GlobalString()); |
| 931 | 939 |
| 932 // Set the String function and constructor. | 940 // Set up the constructor property on the String prototype object. |
| 933 %SetCode($String, StringConstructor); | 941 %AddNamedProperty( |
| 934 %FunctionSetPrototype($String, new $String()); | 942 GlobalString.prototype, "constructor", GlobalString, DONT_ENUM); |
| 935 | 943 |
| 936 // Set up the constructor property on the String prototype object. | 944 // Set up the non-enumerable functions on the String object. |
| 937 %AddNamedProperty($String.prototype, "constructor", $String, DONT_ENUM); | 945 InstallFunctions(GlobalString, DONT_ENUM, GlobalArray( |
| 946 "fromCharCode", StringFromCharCode |
| 947 )); |
| 938 | 948 |
| 939 // Set up the non-enumerable functions on the String object. | 949 // Set up the non-enumerable functions on the String prototype object. |
| 940 InstallFunctions($String, DONT_ENUM, $Array( | 950 InstallFunctions(GlobalString.prototype, DONT_ENUM, GlobalArray( |
| 941 "fromCharCode", StringFromCharCode | 951 "valueOf", StringValueOf, |
| 942 )); | 952 "toString", StringToString, |
| 953 "charAt", StringCharAt, |
| 954 "charCodeAt", StringCharCodeAt, |
| 955 "concat", StringConcat, |
| 956 "indexOf", StringIndexOfJS, |
| 957 "lastIndexOf", StringLastIndexOfJS, |
| 958 "localeCompare", StringLocaleCompareJS, |
| 959 "match", StringMatchJS, |
| 960 "normalize", StringNormalizeJS, |
| 961 "replace", StringReplace, |
| 962 "search", StringSearch, |
| 963 "slice", StringSlice, |
| 964 "split", StringSplitJS, |
| 965 "substring", StringSubstring, |
| 966 "substr", StringSubstr, |
| 967 "toLowerCase", StringToLowerCaseJS, |
| 968 "toLocaleLowerCase", StringToLocaleLowerCase, |
| 969 "toUpperCase", StringToUpperCaseJS, |
| 970 "toLocaleUpperCase", StringToLocaleUpperCase, |
| 971 "trim", StringTrimJS, |
| 972 "trimLeft", StringTrimLeft, |
| 973 "trimRight", StringTrimRight, |
| 974 "link", StringLink, |
| 975 "anchor", StringAnchor, |
| 976 "fontcolor", StringFontcolor, |
| 977 "fontsize", StringFontsize, |
| 978 "big", StringBig, |
| 979 "blink", StringBlink, |
| 980 "bold", StringBold, |
| 981 "fixed", StringFixed, |
| 982 "italics", StringItalics, |
| 983 "small", StringSmall, |
| 984 "strike", StringStrike, |
| 985 "sub", StringSub, |
| 986 "sup", StringSup |
| 987 )); |
| 943 | 988 |
| 944 // Set up the non-enumerable functions on the String prototype object. | 989 $stringCharAt = StringCharAt; |
| 945 InstallFunctions($String.prototype, DONT_ENUM, $Array( | 990 $stringIndexOf = StringIndexOfJS; |
| 946 "valueOf", StringValueOf, | 991 $stringSubstring = StringSubstring; |
| 947 "toString", StringToString, | |
| 948 "charAt", StringCharAt, | |
| 949 "charCodeAt", StringCharCodeAt, | |
| 950 "concat", StringConcat, | |
| 951 "indexOf", StringIndexOfJS, | |
| 952 "lastIndexOf", StringLastIndexOfJS, | |
| 953 "localeCompare", StringLocaleCompareJS, | |
| 954 "match", StringMatchJS, | |
| 955 "normalize", StringNormalizeJS, | |
| 956 "replace", StringReplace, | |
| 957 "search", StringSearch, | |
| 958 "slice", StringSlice, | |
| 959 "split", StringSplitJS, | |
| 960 "substring", StringSubstring, | |
| 961 "substr", StringSubstr, | |
| 962 "toLowerCase", StringToLowerCaseJS, | |
| 963 "toLocaleLowerCase", StringToLocaleLowerCase, | |
| 964 "toUpperCase", StringToUpperCaseJS, | |
| 965 "toLocaleUpperCase", StringToLocaleUpperCase, | |
| 966 "trim", StringTrimJS, | |
| 967 "trimLeft", StringTrimLeft, | |
| 968 "trimRight", StringTrimRight, | |
| 969 "link", StringLink, | |
| 970 "anchor", StringAnchor, | |
| 971 "fontcolor", StringFontcolor, | |
| 972 "fontsize", StringFontsize, | |
| 973 "big", StringBig, | |
| 974 "blink", StringBlink, | |
| 975 "bold", StringBold, | |
| 976 "fixed", StringFixed, | |
| 977 "italics", StringItalics, | |
| 978 "small", StringSmall, | |
| 979 "strike", StringStrike, | |
| 980 "sub", StringSub, | |
| 981 "sup", StringSup | |
| 982 )); | |
| 983 } | |
| 984 | 992 |
| 985 SetUpString(); | 993 })(); |
| OLD | NEW |