Chromium Code Reviews| 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 (function(global, utils) { | 5 (function(global, utils) { |
| 6 | 6 |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
| 10 | 10 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 | 260 |
| 261 // Successful match. | 261 // Successful match. |
| 262 if (updateLastIndex) { | 262 if (updateLastIndex) { |
| 263 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; | 263 this.lastIndex = RegExpLastMatchInfo[CAPTURE1]; |
| 264 } | 264 } |
| 265 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); | 265 RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string); |
| 266 } | 266 } |
| 267 | 267 |
| 268 | 268 |
| 269 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) | 269 // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) |
| 270 function RegExpSubclassExec(regexp, string) { | 270 // Also takes an optional exec method in case our caller |
| 271 var exec = regexp.exec; | 271 // has already fetched exec. |
| 272 function RegExpSubclassExec(regexp, string, exec) { | |
| 273 if (IS_UNDEFINED(exec)) { | |
| 274 exec = regexp.exec; | |
| 275 } | |
| 272 if (IS_CALLABLE(exec)) { | 276 if (IS_CALLABLE(exec)) { |
| 273 var result = %_Call(exec, regexp, string); | 277 var result = %_Call(exec, regexp, string); |
| 274 if (!IS_RECEIVER(result) && !IS_NULL(result)) { | 278 if (!IS_RECEIVER(result) && !IS_NULL(result)) { |
| 275 throw MakeTypeError(kInvalidRegExpExecResult); | 279 throw MakeTypeError(kInvalidRegExpExecResult); |
| 276 } | 280 } |
| 277 return result; | 281 return result; |
| 278 } | 282 } |
| 279 return %_Call(RegExpExecJS, regexp, string); | 283 return %_Call(RegExpExecJS, regexp, string); |
| 280 } | 284 } |
| 285 %SetForceInlineFlag(RegExpSubclassExec); | |
| 281 | 286 |
| 282 | 287 |
| 283 // One-element cache for the simplified test regexp. | 288 // One-element cache for the simplified test regexp. |
| 284 var regexp_key; | 289 var regexp_key; |
| 285 var regexp_val; | 290 var regexp_val; |
| 286 | 291 |
| 287 // Legacy implementation of RegExp.prototype.test | 292 // Legacy implementation of RegExp.prototype.test |
| 288 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 293 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
| 289 // that test is defined in terms of String.prototype.exec. However, it probably | 294 // that test is defined in terms of String.prototype.exec. However, it probably |
| 290 // means the original value of String.prototype.exec, which is what everybody | 295 // means the original value of String.prototype.exec, which is what everybody |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 // ES#sec-regexp.prototype-@@split | 481 // ES#sec-regexp.prototype-@@split |
| 477 // RegExp.prototype [ @@split ] ( string, limit ) | 482 // RegExp.prototype [ @@split ] ( string, limit ) |
| 478 function RegExpSubclassSplit(string, limit) { | 483 function RegExpSubclassSplit(string, limit) { |
| 479 if (!IS_RECEIVER(this)) { | 484 if (!IS_RECEIVER(this)) { |
| 480 throw MakeTypeError(kIncompatibleMethodReceiver, | 485 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 481 "RegExp.prototype.@@split", this); | 486 "RegExp.prototype.@@split", this); |
| 482 } | 487 } |
| 483 string = TO_STRING(string); | 488 string = TO_STRING(string); |
| 484 var constructor = SpeciesConstructor(this, GlobalRegExp); | 489 var constructor = SpeciesConstructor(this, GlobalRegExp); |
| 485 var flags = TO_STRING(this.flags); | 490 var flags = TO_STRING(this.flags); |
| 491 | |
| 492 // TODO(adamk): this fast path is wrong with respect to this.global | |
| 493 // and this.sticky, but hopefully the spec will remove those gets | |
| 494 // and thus make the assumption of 'exec' having no side-effects | |
| 495 // more correct. Also, we doesn't ensure that 'exec' is actually | |
| 496 // a data property on RegExp.prototype. | |
| 497 var exec; | |
| 498 if (IS_REGEXP(this) && constructor === GlobalRegExp) { | |
| 499 exec = this.exec; | |
| 500 if (exec === RegExpSubclassExecJS) { | |
| 501 return %_Call(RegExpSplit, this, string, limit); | |
| 502 } | |
| 503 } | |
| 504 | |
| 486 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; | 505 var unicode = %StringIndexOf(flags, 'u', 0) >= 0; |
| 487 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; | 506 var sticky = %StringIndexOf(flags, 'y', 0) >= 0; |
| 488 var newFlags = sticky ? flags : flags + "y"; | 507 var newFlags = sticky ? flags : flags + "y"; |
| 489 var splitter = new constructor(this, newFlags); | 508 var splitter = new constructor(this, newFlags); |
| 490 var array = new GlobalArray(); | 509 var array = new GlobalArray(); |
| 491 var arrayIndex = 0; | 510 var arrayIndex = 0; |
| 492 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); | 511 var lim = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); |
| 493 var size = string.length; | 512 var size = string.length; |
| 494 var prevStringIndex = 0; | 513 var prevStringIndex = 0; |
| 495 if (lim === 0) return array; | 514 if (lim === 0) return array; |
| 496 var result; | 515 var result; |
| 497 if (size === 0) { | 516 if (size === 0) { |
| 498 result = RegExpSubclassExec(splitter, string); | 517 result = RegExpSubclassExec(splitter, string); |
| 499 if (IS_NULL(result)) AddIndexedProperty(array, 0, string); | 518 if (IS_NULL(result)) AddIndexedProperty(array, 0, string); |
| 500 return array; | 519 return array; |
| 501 } | 520 } |
| 502 var stringIndex = prevStringIndex; | 521 var stringIndex = prevStringIndex; |
| 503 while (stringIndex < size) { | 522 while (stringIndex < size) { |
| 504 splitter.lastIndex = stringIndex; | 523 splitter.lastIndex = stringIndex; |
| 505 result = RegExpSubclassExec(splitter, string); | 524 result = RegExpSubclassExec(splitter, string, exec); |
| 525 // Ensure exec will be read again on the next loop through. | |
| 526 exec = UNDEFINED; | |
| 506 if (IS_NULL(result)) { | 527 if (IS_NULL(result)) { |
| 507 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 528 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
| 508 } else { | 529 } else { |
| 509 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); | 530 var end = MinSimple(TO_LENGTH(splitter.lastIndex), size); |
| 510 if (end === stringIndex) { | 531 if (end === stringIndex) { |
| 511 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); | 532 stringIndex += AdvanceStringIndex(string, stringIndex, unicode); |
| 512 } else { | 533 } else { |
| 513 AddIndexedProperty( | 534 AddIndexedProperty( |
| 514 array, arrayIndex, | 535 array, arrayIndex, |
| 515 %_SubString(string, prevStringIndex, stringIndex)); | 536 %_SubString(string, prevStringIndex, stringIndex)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 function RegExpSubclassMatch(string) { | 575 function RegExpSubclassMatch(string) { |
| 555 if (!IS_RECEIVER(this)) { | 576 if (!IS_RECEIVER(this)) { |
| 556 throw MakeTypeError(kIncompatibleMethodReceiver, | 577 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 557 "RegExp.prototype.@@match", this); | 578 "RegExp.prototype.@@match", this); |
| 558 } | 579 } |
| 559 string = TO_STRING(string); | 580 string = TO_STRING(string); |
| 560 var global = this.global; | 581 var global = this.global; |
| 561 if (!global) return RegExpSubclassExec(this, string); | 582 if (!global) return RegExpSubclassExec(this, string); |
| 562 var unicode = this.unicode; | 583 var unicode = this.unicode; |
| 563 this.lastIndex = 0; | 584 this.lastIndex = 0; |
| 564 var array = []; | 585 var array = new InternalArray(); |
| 565 var n = 0; | 586 var n = 0; |
| 566 var result; | 587 var result; |
| 567 while (true) { | 588 while (true) { |
| 568 result = RegExpSubclassExec(this, string); | 589 result = RegExpSubclassExec(this, string); |
| 569 if (IS_NULL(result)) { | 590 if (IS_NULL(result)) { |
| 570 if (n === 0) return null; | 591 if (n === 0) return null; |
| 571 return array; | 592 break; |
| 572 } | 593 } |
| 573 var matchStr = TO_STRING(result[0]); | 594 var matchStr = TO_STRING(result[0]); |
| 574 %AddElement(array, n, matchStr); | 595 array[n] = matchStr; |
| 575 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); | 596 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); |
| 576 n++; | 597 n++; |
| 577 } | 598 } |
| 599 var resultArray = []; | |
| 600 %MoveArrayContents(array, resultArray); | |
| 601 return resultArray; | |
| 578 } | 602 } |
| 579 %FunctionRemovePrototype(RegExpSubclassMatch); | 603 %FunctionRemovePrototype(RegExpSubclassMatch); |
| 580 | 604 |
| 581 | 605 |
| 582 // Legacy implementation of RegExp.prototype[Symbol.replace] which | 606 // Legacy implementation of RegExp.prototype[Symbol.replace] which |
| 583 // doesn't properly call the underlying exec method. | 607 // doesn't properly call the underlying exec method. |
| 584 | 608 |
| 585 // TODO(lrn): This array will survive indefinitely if replace is never | 609 // TODO(lrn): This array will survive indefinitely if replace is never |
| 586 // called again. However, it will be empty, since the contents are cleared | 610 // called again. However, it will be empty, since the contents are cleared |
| 587 // in the finally block. | 611 // in the finally block. |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 844 var first = %_StringCharCodeAt(string, index); | 868 var first = %_StringCharCodeAt(string, index); |
| 845 if (first >= 0xD800 && first <= 0xDBFF && string.length > index + 1) { | 869 if (first >= 0xD800 && first <= 0xDBFF && string.length > index + 1) { |
| 846 var second = %_StringCharCodeAt(string, index + 1); | 870 var second = %_StringCharCodeAt(string, index + 1); |
| 847 if (second >= 0xDC00 && second <= 0xDFFF) { | 871 if (second >= 0xDC00 && second <= 0xDFFF) { |
| 848 increment = 2; | 872 increment = 2; |
| 849 } | 873 } |
| 850 } | 874 } |
| 851 } | 875 } |
| 852 return increment; | 876 return increment; |
| 853 } | 877 } |
| 878 %SetForceInlineFlag(AdvanceStringIndex); | |
| 854 | 879 |
| 855 | 880 |
| 856 function SetAdvancedStringIndex(regexp, string, unicode) { | 881 function SetAdvancedStringIndex(regexp, string, unicode) { |
| 857 var lastIndex = regexp.lastIndex; | 882 var lastIndex = regexp.lastIndex; |
| 858 regexp.lastIndex = lastIndex + | 883 regexp.lastIndex = lastIndex + |
| 859 AdvanceStringIndex(string, lastIndex, unicode); | 884 AdvanceStringIndex(string, lastIndex, unicode); |
| 860 } | 885 } |
| 886 %SetForceInlineFlag(SetAdvancedStringIndex); | |
|
Yang
2016/03/29 12:19:04
I see this is only used as a helper. Can we write
adamk
2016/03/29 20:19:20
For this patch, it turns out we don't need this st
| |
| 861 | 887 |
| 862 | 888 |
| 863 // ES#sec-regexp.prototype-@@replace | 889 // ES#sec-regexp.prototype-@@replace |
| 864 // RegExp.prototype [ @@replace ] ( string, replaceValue ) | 890 // RegExp.prototype [ @@replace ] ( string, replaceValue ) |
| 865 function RegExpSubclassReplace(string, replace) { | 891 function RegExpSubclassReplace(string, replace) { |
| 866 if (!IS_RECEIVER(this)) { | 892 if (!IS_RECEIVER(this)) { |
| 867 throw MakeTypeError(kIncompatibleMethodReceiver, | 893 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 868 "RegExp.prototype.@@replace", this); | 894 "RegExp.prototype.@@replace", this); |
| 869 } | 895 } |
| 870 string = TO_STRING(string); | 896 string = TO_STRING(string); |
| 871 var length = string.length; | 897 var length = string.length; |
| 872 var functionalReplace = IS_CALLABLE(replace); | 898 var functionalReplace = IS_CALLABLE(replace); |
| 873 if (!functionalReplace) replace = TO_STRING(replace); | 899 if (!functionalReplace) replace = TO_STRING(replace); |
| 874 var global = this.global; | 900 var global = TO_BOOLEAN(this.global); |
| 875 if (global) { | 901 if (global) { |
| 876 var unicode = this.unicode; | 902 var unicode = TO_BOOLEAN(this.unicode); |
| 877 this.lastIndex = 0; | 903 this.lastIndex = 0; |
| 878 } | 904 } |
| 905 | |
| 906 // TODO(adamk): this fast path is wrong with respect to this.global | |
| 907 // and this.sticky, but hopefully the spec will remove those gets | |
| 908 // and thus make the assumption of 'exec' having no side-effects | |
| 909 // more correct. Also, we doesn't ensure that 'exec' is actually | |
| 910 // a data property on RegExp.prototype, nor does the fast path | |
| 911 // correctly handle lastIndex setting. | |
| 912 var exec; | |
| 913 if (IS_REGEXP(this)) { | |
| 914 exec = this.exec; | |
| 915 if (exec === RegExpSubclassExecJS) { | |
| 916 return %_Call(RegExpReplace, this, string, replace); | |
| 917 } | |
| 918 } | |
| 919 | |
| 879 var results = new InternalArray(); | 920 var results = new InternalArray(); |
| 880 var result, replacement; | 921 var result, replacement; |
| 881 while (true) { | 922 while (true) { |
| 882 result = RegExpSubclassExec(this, string); | 923 result = RegExpSubclassExec(this, string, exec); |
| 924 // Ensure exec will be read again on the next loop through. | |
| 925 exec = UNDEFINED; | |
| 883 if (IS_NULL(result)) { | 926 if (IS_NULL(result)) { |
| 884 break; | 927 break; |
| 885 } else { | 928 } else { |
| 886 results.push(result); | 929 results.push(result); |
| 887 if (!global) break; | 930 if (!global) break; |
| 888 var matchStr = TO_STRING(result[0]); | 931 var matchStr = TO_STRING(result[0]); |
| 889 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); | 932 if (matchStr === "") SetAdvancedStringIndex(this, string, unicode); |
| 890 } | 933 } |
| 891 } | 934 } |
| 892 var accumulatedResult = ""; | 935 var accumulatedResult = ""; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1027 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); | 1070 kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this)); |
| 1028 } | 1071 } |
| 1029 var result = ''; | 1072 var result = ''; |
| 1030 if (this.global) result += 'g'; | 1073 if (this.global) result += 'g'; |
| 1031 if (this.ignoreCase) result += 'i'; | 1074 if (this.ignoreCase) result += 'i'; |
| 1032 if (this.multiline) result += 'm'; | 1075 if (this.multiline) result += 'm'; |
| 1033 if (this.unicode) result += 'u'; | 1076 if (this.unicode) result += 'u'; |
| 1034 if (this.sticky) result += 'y'; | 1077 if (this.sticky) result += 'y'; |
| 1035 return result; | 1078 return result; |
| 1036 } | 1079 } |
| 1080 %SetForceInlineFlag(RegExpGetFlags); | |
|
Yang
2016/03/29 12:19:04
I can see the need for individual flag getters bel
adamk
2016/03/29 20:19:20
No, flags barely shows up on the profile, these go
| |
| 1037 | 1081 |
| 1038 | 1082 |
| 1039 // ES6 21.2.5.4. | 1083 // ES6 21.2.5.4. |
| 1040 function RegExpGetGlobal() { | 1084 function RegExpGetGlobal() { |
| 1041 if (!IS_REGEXP(this)) { | 1085 if (!IS_REGEXP(this)) { |
| 1042 // TODO(littledan): Remove this RegExp compat workaround | 1086 // TODO(littledan): Remove this RegExp compat workaround |
| 1043 if (this === GlobalRegExpPrototype) { | 1087 if (this === GlobalRegExpPrototype) { |
| 1044 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1088 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1045 return UNDEFINED; | 1089 return UNDEFINED; |
| 1046 } | 1090 } |
| 1047 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); | 1091 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global"); |
| 1048 } | 1092 } |
| 1049 return !!REGEXP_GLOBAL(this); | 1093 return TO_BOOLEAN(REGEXP_GLOBAL(this)); |
| 1050 } | 1094 } |
| 1095 %SetForceInlineFlag(RegExpGetGlobal); | |
| 1051 | 1096 |
| 1052 | 1097 |
| 1053 // ES6 21.2.5.5. | 1098 // ES6 21.2.5.5. |
| 1054 function RegExpGetIgnoreCase() { | 1099 function RegExpGetIgnoreCase() { |
| 1055 if (!IS_REGEXP(this)) { | 1100 if (!IS_REGEXP(this)) { |
| 1056 // TODO(littledan): Remove this RegExp compat workaround | 1101 // TODO(littledan): Remove this RegExp compat workaround |
| 1057 if (this === GlobalRegExpPrototype) { | 1102 if (this === GlobalRegExpPrototype) { |
| 1058 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1103 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1059 return UNDEFINED; | 1104 return UNDEFINED; |
| 1060 } | 1105 } |
| 1061 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); | 1106 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase"); |
| 1062 } | 1107 } |
| 1063 return !!REGEXP_IGNORE_CASE(this); | 1108 return TO_BOOLEAN(REGEXP_IGNORE_CASE(this)); |
| 1064 } | 1109 } |
| 1110 %SetForceInlineFlag(RegExpGetIgnoreCase); | |
| 1065 | 1111 |
| 1066 | 1112 |
| 1067 // ES6 21.2.5.7. | 1113 // ES6 21.2.5.7. |
| 1068 function RegExpGetMultiline() { | 1114 function RegExpGetMultiline() { |
| 1069 if (!IS_REGEXP(this)) { | 1115 if (!IS_REGEXP(this)) { |
| 1070 // TODO(littledan): Remove this RegExp compat workaround | 1116 // TODO(littledan): Remove this RegExp compat workaround |
| 1071 if (this === GlobalRegExpPrototype) { | 1117 if (this === GlobalRegExpPrototype) { |
| 1072 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); | 1118 %IncrementUseCounter(kRegExpPrototypeOldFlagGetter); |
| 1073 return UNDEFINED; | 1119 return UNDEFINED; |
| 1074 } | 1120 } |
| 1075 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); | 1121 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline"); |
| 1076 } | 1122 } |
| 1077 return !!REGEXP_MULTILINE(this); | 1123 return TO_BOOLEAN(REGEXP_MULTILINE(this)); |
| 1078 } | 1124 } |
| 1125 %SetForceInlineFlag(RegExpGetMultiline); | |
|
Yang
2016/03/29 12:19:04
Is this only for symmetry? I don't think any of th
adamk
2016/03/29 20:19:20
Removed, as noted. The only getters that still hav
| |
| 1079 | 1126 |
| 1080 | 1127 |
| 1081 // ES6 21.2.5.10. | 1128 // ES6 21.2.5.10. |
| 1082 function RegExpGetSource() { | 1129 function RegExpGetSource() { |
| 1083 if (!IS_REGEXP(this)) { | 1130 if (!IS_REGEXP(this)) { |
| 1084 // TODO(littledan): Remove this RegExp compat workaround | 1131 // TODO(littledan): Remove this RegExp compat workaround |
| 1085 if (this === GlobalRegExpPrototype) { | 1132 if (this === GlobalRegExpPrototype) { |
| 1086 %IncrementUseCounter(kRegExpPrototypeSourceGetter); | 1133 %IncrementUseCounter(kRegExpPrototypeSourceGetter); |
| 1087 return UNDEFINED; | 1134 return UNDEFINED; |
| 1088 } | 1135 } |
| 1089 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); | 1136 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source"); |
| 1090 } | 1137 } |
| 1091 return REGEXP_SOURCE(this); | 1138 return REGEXP_SOURCE(this); |
| 1092 } | 1139 } |
| 1093 | 1140 |
| 1094 | 1141 |
| 1095 // ES6 21.2.5.12. | 1142 // ES6 21.2.5.12. |
| 1096 function RegExpGetSticky() { | 1143 function RegExpGetSticky() { |
| 1097 if (!IS_REGEXP(this)) { | 1144 if (!IS_REGEXP(this)) { |
| 1098 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it | 1145 // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it |
| 1099 // TODO(littledan): Remove this workaround or standardize it | 1146 // TODO(littledan): Remove this workaround or standardize it |
| 1100 if (this === GlobalRegExpPrototype) { | 1147 if (this === GlobalRegExpPrototype) { |
| 1101 %IncrementUseCounter(kRegExpPrototypeStickyGetter); | 1148 %IncrementUseCounter(kRegExpPrototypeStickyGetter); |
| 1102 return UNDEFINED; | 1149 return UNDEFINED; |
| 1103 } | 1150 } |
| 1104 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky"); | 1151 throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky"); |
| 1105 } | 1152 } |
| 1106 return !!REGEXP_STICKY(this); | 1153 return TO_BOOLEAN(REGEXP_STICKY(this)); |
| 1107 } | 1154 } |
| 1155 %SetForceInlineFlag(RegExpGetSticky); | |
| 1108 | 1156 |
| 1109 // ------------------------------------------------------------------- | 1157 // ------------------------------------------------------------------- |
| 1110 | 1158 |
| 1111 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); | 1159 %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); |
| 1112 GlobalRegExpPrototype = new GlobalObject(); | 1160 GlobalRegExpPrototype = new GlobalObject(); |
| 1113 %FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype); | 1161 %FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype); |
| 1114 %AddNamedProperty( | 1162 %AddNamedProperty( |
| 1115 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); | 1163 GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM); |
| 1116 %SetCode(GlobalRegExp, RegExpConstructor); | 1164 %SetCode(GlobalRegExp, RegExpConstructor); |
| 1117 | 1165 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1188 to.RegExpSubclassMatch = RegExpSubclassMatch; | 1236 to.RegExpSubclassMatch = RegExpSubclassMatch; |
| 1189 to.RegExpSubclassReplace = RegExpSubclassReplace; | 1237 to.RegExpSubclassReplace = RegExpSubclassReplace; |
| 1190 to.RegExpSubclassSearch = RegExpSubclassSearch; | 1238 to.RegExpSubclassSearch = RegExpSubclassSearch; |
| 1191 to.RegExpSubclassSplit = RegExpSubclassSplit; | 1239 to.RegExpSubclassSplit = RegExpSubclassSplit; |
| 1192 to.RegExpSubclassTest = RegExpSubclassTest; | 1240 to.RegExpSubclassTest = RegExpSubclassTest; |
| 1193 to.RegExpTest = RegExpTest; | 1241 to.RegExpTest = RegExpTest; |
| 1194 to.IsRegExp = IsRegExp; | 1242 to.IsRegExp = IsRegExp; |
| 1195 }); | 1243 }); |
| 1196 | 1244 |
| 1197 }) | 1245 }) |
| OLD | NEW |