Changeset 242047 in webkit
- Timestamp:
- Feb 25, 2019 10:32:18 AM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r242019 r242047 1189 1189 ${JAVASCRIPTCORE_DIR}/builtins/ModuleLoader.js 1190 1190 ${JAVASCRIPTCORE_DIR}/builtins/NumberConstructor.js 1191 ${JAVASCRIPTCORE_DIR}/builtins/NumberPrototype.js1192 1191 ${JAVASCRIPTCORE_DIR}/builtins/ObjectConstructor.js 1193 1192 ${JAVASCRIPTCORE_DIR}/builtins/PromiseConstructor.js -
trunk/Source/JavaScriptCore/ChangeLog
r242019 r242047 1 2019-02-25 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Drop direct references to Intl constructors by rewriting Intl JS builtins in C++ 4 https://bugs.webkit.org/show_bug.cgi?id=194976 5 6 Reviewed by Michael Saboff. 7 8 This patch paves the way to making IntlObject allocation lazy by removing direct references 9 to Intl constructors (Intl.Collator etc.) from builtin JS. To achieve that, 10 11 1. We implement String.prototype.toLocaleCompare and Number.prototype.toLocaleString in C++ 12 instead of JS builtins. Since these functions end up calling ICU C++ runtime, writing them in 13 JS does not offer performance improvement. 14 15 2. We remove @DateTimeFormat constructor reference, and instead, exposing @dateTimeFormat function, 16 which returns formatted string directly. We still have JS builtins for DateTimeFormat things 17 because the initialization of its "options" JSObject involves many get_by_id / put_by_id things, 18 which are efficient in JS. But we avoid exposing @DateTimeFormat directly, so that Intl constructors 19 can be lazily allocated. 20 21 * CMakeLists.txt: 22 * DerivedSources-input.xcfilelist: 23 * DerivedSources.make: 24 * JavaScriptCore.xcodeproj/project.pbxproj: 25 * builtins/BuiltinNames.h: 26 * builtins/DatePrototype.js: 27 (toLocaleString): 28 (toLocaleDateString): 29 (toLocaleTimeString): 30 * builtins/NumberPrototype.js: Removed. 31 * builtins/StringPrototype.js: 32 (intrinsic.StringPrototypeReplaceIntrinsic.replace): 33 (globalPrivate.getDefaultCollator): Deleted. 34 * runtime/JSGlobalObject.cpp: 35 (JSC::JSGlobalObject::init): 36 (JSC::JSGlobalObject::visitChildren): 37 (JSC::JSGlobalObject::defaultCollator): 38 * runtime/JSGlobalObject.h: 39 * runtime/JSGlobalObjectFunctions.cpp: 40 (JSC::globalFuncDateTimeFormat): 41 * runtime/JSGlobalObjectFunctions.h: 42 * runtime/NumberPrototype.cpp: 43 (JSC::NumberPrototype::finishCreation): 44 (JSC::throwVMToThisNumberError): 45 (JSC::numberProtoFuncToExponential): 46 (JSC::numberProtoFuncToFixed): 47 (JSC::numberProtoFuncToPrecision): 48 (JSC::numberProtoFuncToString): 49 (JSC::numberProtoFuncToLocaleString): 50 (JSC::numberProtoFuncValueOf): 51 * runtime/StringPrototype.cpp: 52 (JSC::StringPrototype::finishCreation): 53 (JSC::stringProtoFuncLocaleCompare): 54 1 55 2019-02-24 Devin Rousso <drousso@apple.com> 2 56 -
trunk/Source/JavaScriptCore/DerivedSources-input.xcfilelist
r242019 r242047 44 44 $(PROJECT_DIR)/builtins/ModuleLoader.js 45 45 $(PROJECT_DIR)/builtins/NumberConstructor.js 46 $(PROJECT_DIR)/builtins/NumberPrototype.js47 46 $(PROJECT_DIR)/builtins/ObjectConstructor.js 48 47 $(PROJECT_DIR)/builtins/PromiseConstructor.js -
trunk/Source/JavaScriptCore/DerivedSources.make
r242019 r242047 106 106 $(JavaScriptCore)/builtins/ModuleLoader.js \ 107 107 $(JavaScriptCore)/builtins/NumberConstructor.js \ 108 $(JavaScriptCore)/builtins/NumberPrototype.js \109 108 $(JavaScriptCore)/builtins/ObjectConstructor.js \ 110 109 $(JavaScriptCore)/builtins/PromiseConstructor.js \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r241929 r242047 2032 2032 dstSubfolderSpec = 16; 2033 2033 files = ( 2034 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */, 2034 2035 52D13091221CE176009C836C /* foo.js in Copy Support Script */, 2035 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */,2036 2036 FECB8B2A1D25CB5A006F2463 /* testapi-function-overrides.js in Copy Support Script */, 2037 2037 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */, … … 4066 4066 A1587D731B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatConstructor.lut.h; sourceTree = "<group>"; }; 4067 4067 A1587D741B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatPrototype.lut.h; sourceTree = "<group>"; }; 4068 A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = NumberPrototype.js; sourceTree = "<group>"; };4069 4068 A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; }; 4070 4069 A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; }; … … 8193 8192 E30677971B8BC6F5003F87F0 /* ModuleLoader.js */, 8194 8193 A52704861D027C8800354C37 /* NumberConstructor.js */, 8195 A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */,8196 8194 7CF9BC5C1B65D9B1009DB1EF /* ObjectConstructor.js */, 8197 8195 7CF9BC5E1B65D9B1009DB1EF /* PromiseConstructor.js */, … … 9260 9258 8BC064891E1ABA6400B2B8CA /* JSAsyncGeneratorFunction.h in Headers */, 9261 9259 BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */, 9260 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */, 9262 9261 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */, 9263 9262 868921C21F9C0CB7001159F6 /* JSBigInt.h in Headers */, … … 9766 9765 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */, 9767 9766 A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */, 9768 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */,9769 9767 A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */, 9770 9768 866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */, -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r241644 r242047 127 127 macro(asyncGeneratorQueueItemPrevious) \ 128 128 macro(generatorResumeMode) \ 129 macro(Collator) \ 130 macro(DateTimeFormat) \ 131 macro(NumberFormat) \ 132 macro(PluralRules) \ 129 macro(dateTimeFormat) \ 133 130 macro(intlSubstituteValue) \ 134 131 macro(thisTimeValue) \ 135 macro(thisNumberValue) \136 132 macro(newTargetLocal) \ 137 133 macro(derivedConstructor) \ -
trunk/Source/JavaScriptCore/builtins/DatePrototype.js
r231460 r242047 78 78 var options = toDateTimeOptionsAnyAll(@argument(1)); 79 79 var locales = @argument(0); 80 81 var dateFormat = new @DateTimeFormat(locales, options); 82 return dateFormat.format(value); 80 return @dateTimeFormat(locales, options, value); 83 81 } 84 82 … … 128 126 var options = toDateTimeOptionsDateDate(@argument(1)); 129 127 var locales = @argument(0); 130 131 var dateFormat = new @DateTimeFormat(locales, options); 132 return dateFormat.format(value); 128 return @dateTimeFormat(locales, options, value); 133 129 } 134 130 … … 177 173 var options = toDateTimeOptionsTimeTime(@argument(1)); 178 174 var locales = @argument(0); 179 180 var dateFormat = new @DateTimeFormat(locales, options); 181 return dateFormat.format(value); 175 return @dateTimeFormat(locales, options, value); 182 176 } -
trunk/Source/JavaScriptCore/builtins/StringPrototype.js
r239761 r242047 238 238 return thisString.@replaceUsingStringSearch(searchString, replace); 239 239 } 240 241 @globalPrivate242 function getDefaultCollator()243 {244 "use strict";245 246 return @getDefaultCollator.collator || (@getDefaultCollator.collator = new @Collator());247 }248 249 function localeCompare(that/*, locales, options */)250 {251 "use strict";252 253 // 13.1.1 String.prototype.localeCompare (that [, locales [, options ]]) (ECMA-402 2.0)254 // http://ecma-international.org/publications/standards/Ecma-402.htm255 256 // 1. Let O be RequireObjectCoercible(this value).257 if (@isUndefinedOrNull(this))258 @throwTypeError("String.prototype.localeCompare requires that |this| not be null or undefined");259 260 // 2. Let S be ToString(O).261 // 3. ReturnIfAbrupt(S).262 var thisString = @toString(this);263 264 // 4. Let That be ToString(that).265 // 5. ReturnIfAbrupt(That).266 var thatString = @toString(that);267 268 // Avoid creating a new collator every time for defaults.269 var locales = @argument(1);270 var options = @argument(2);271 if (locales === @undefined && options === @undefined)272 return @getDefaultCollator().compare(thisString, thatString);273 274 // 6. Let collator be Construct(%Collator%, «locales, options»).275 // 7. ReturnIfAbrupt(collator).276 var collator = new @Collator(locales, options);277 278 // 8. Return CompareStrings(collator, S, That).279 return collator.compare(thisString, thatString);280 }281 240 282 241 function search(regexp) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r241769 r242047 179 179 180 180 #if ENABLE(INTL) 181 #include "IntlCollator.h" 181 182 #include "IntlObject.h" 182 183 #include <unicode/ucol.h> … … 831 832 JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf); 832 833 JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime); 833 JSFunction* privateFuncThisNumberValue = JSFunction::create(vm, this, 0, String(), numberProtoFuncValueOf); 834 #if ENABLE(INTL) 835 JSFunction* privateFuncDateTimeFormat = JSFunction::create(vm, this, 0, String(), globalFuncDateTimeFormat); 836 #endif 834 837 JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor); 835 838 JSFunction* privateFuncIsArraySlow = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArraySlow); … … 921 924 GlobalPropertyInfo(vm.propertyNames->builtinNames().SetPrivateName(), setConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 922 925 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 923 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisNumberValuePrivateName(), privateFuncThisNumberValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),924 926 #if ENABLE(INTL) 925 GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 926 GlobalPropertyInfo(vm.propertyNames->builtinNames().DateTimeFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->DateTimeFormat), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 927 GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->NumberFormat), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 928 GlobalPropertyInfo(vm.propertyNames->builtinNames().PluralRulesPrivateName(), intl->getDirect(vm, vm.propertyNames->PluralRules), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 927 GlobalPropertyInfo(vm.propertyNames->builtinNames().dateTimeFormatPrivateName(), privateFuncDateTimeFormat, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 929 928 #endif // ENABLE(INTL) 930 929 … … 1569 1568 #if ENABLE(INTL) 1570 1569 visitor.append(thisObject->m_intlObject); 1570 visitor.append(thisObject->m_defaultCollator); 1571 1571 #endif 1572 1572 visitor.append(thisObject->m_nullGetterFunction); … … 1866 1866 return m_intlPluralRulesAvailableLocales; 1867 1867 } 1868 1869 IntlCollator* JSGlobalObject::defaultCollator(ExecState* exec) 1870 { 1871 VM& vm = exec->vm(); 1872 auto scope = DECLARE_THROW_SCOPE(vm); 1873 1874 if (m_defaultCollator) 1875 return m_defaultCollator.get(); 1876 1877 IntlCollator* collator = IntlCollator::create(vm, intlObject()->collatorStructure()); 1878 collator->initializeCollator(*exec, jsUndefined(), jsUndefined()); 1879 RETURN_IF_EXCEPTION(scope, nullptr); 1880 m_defaultCollator.set(vm, this, collator); 1881 return collator; 1882 } 1883 1868 1884 #endif // ENABLE(INTL) 1869 1885 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r241741 r242047 84 84 class InputCursor; 85 85 class IntlObject; 86 class IntlCollator; 86 87 class JSArrayBuffer; 87 88 class JSArrayBufferPrototype; … … 277 278 #if ENABLE(INTL) 278 279 WriteBarrier<IntlObject> m_intlObject; 280 WriteBarrier<IntlCollator> m_defaultCollator; 279 281 #endif 280 282 WriteBarrier<NullGetterFunction> m_nullGetterFunction; … … 588 590 #if ENABLE(INTL) 589 591 IntlObject* intlObject() const { return m_intlObject.get(); } 592 IntlCollator* defaultCollator(ExecState*); 590 593 #endif 591 594 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r241256 r242047 32 32 #include "IndirectEvalExecutable.h" 33 33 #include "Interpreter.h" 34 #include "IntlDateTimeFormat.h" 35 #include "IntlObject.h" 34 36 #include "JSCInlines.h" 35 37 #include "JSFunction.h" … … 831 833 } 832 834 835 #if ENABLE(INTL) 836 EncodedJSValue JSC_HOST_CALL globalFuncDateTimeFormat(ExecState* exec) 837 { 838 VM& vm = exec->vm(); 839 auto scope = DECLARE_THROW_SCOPE(vm); 840 841 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); 842 IntlDateTimeFormat* dateTimeFormat = IntlDateTimeFormat::create(vm, globalObject->intlObject()->dateTimeFormatStructure()); 843 dateTimeFormat->initializeDateTimeFormat(*exec, exec->argument(0), exec->argument(1)); 844 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 845 double value = exec->argument(2).toNumber(exec); 846 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 847 RELEASE_AND_RETURN(scope, JSValue::encode(dateTimeFormat->format(*exec, value))); 848 } 849 #endif 850 833 851 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
r233122 r242047 56 56 EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*); 57 57 EncodedJSValue JSC_HOST_CALL globalFuncPropertyIsEnumerable(ExecState*); 58 EncodedJSValue JSC_HOST_CALL globalFuncDateTimeFormat(ExecState*); 58 59 59 60 double jsToNumber(StringView); -
trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp
r241244 r242047 25 25 #include "BigInteger.h" 26 26 #include "Error.h" 27 #include "JSCBuiltins.h" 27 #include "IntlNumberFormat.h" 28 #include "IntlObject.h" 28 29 #include "JSCInlines.h" 29 30 #include "JSFunction.h" … … 81 82 82 83 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, numberProtoFuncToString, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, NumberPrototypeToStringIntrinsic); 83 #if ENABLE(INTL)84 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("toLocaleString", numberPrototypeToLocaleStringCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));85 #endif // ENABLE(INTL)86 87 84 ASSERT(inherits(vm, info())); 88 85 } … … 108 105 109 106 return false; 107 } 108 109 static ALWAYS_INLINE EncodedJSValue throwVMToThisNumberError(ExecState* exec, ThrowScope& scope, JSValue thisValue) 110 { 111 auto typeString = asString(jsTypeStringForValue(exec->vm(), exec->lexicalGlobalObject(), thisValue))->value(exec); 112 scope.assertNoException(); 113 return throwVMTypeError(exec, scope, WTF::makeString("thisNumberValue called on incompatible ", typeString)); 110 114 } 111 115 … … 409 413 double x; 410 414 if (!toThisNumber(vm, exec->thisValue(), x)) 411 return throwVMT ypeError(exec, scope);415 return throwVMToThisNumberError(exec, scope, exec->thisValue()); 412 416 413 417 // Perform ToInteger on the argument before remaining steps. … … 446 450 double x; 447 451 if (!toThisNumber(vm, exec->thisValue(), x)) 448 return throwVMT ypeError(exec, scope);452 return throwVMToThisNumberError(exec, scope, exec->thisValue()); 449 453 450 454 // Get the argument. … … 483 487 double x; 484 488 if (!toThisNumber(vm, exec->thisValue(), x)) 485 return throwVMT ypeError(exec, scope);489 return throwVMToThisNumberError(exec, scope, exec->thisValue()); 486 490 487 491 // Perform ToInteger on the argument before remaining steps. … … 580 584 double doubleValue; 581 585 if (!toThisNumber(vm, state->thisValue(), doubleValue)) 582 return throwVMT ypeError(state, scope);586 return throwVMToThisNumberError(state, scope, state->thisValue()); 583 587 584 588 auto radix = extractToStringRadixArgument(state, state->argument(0), scope); … … 595 599 double x; 596 600 if (!toThisNumber(vm, exec->thisValue(), x)) 597 return throwVMTypeError(exec, scope); 598 601 return throwVMToThisNumberError(exec, scope, exec->thisValue()); 602 603 #if ENABLE(INTL) 604 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); 605 IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, globalObject->intlObject()->numberFormatStructure()); 606 numberFormat->initializeNumberFormat(*exec, exec->argument(0), exec->argument(1)); 607 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 608 RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatNumber(*exec, x))); 609 #else 599 610 return JSValue::encode(jsNumber(x).toString(exec)); 611 #endif 600 612 } 601 613 … … 608 620 JSValue thisValue = exec->thisValue(); 609 621 if (!toThisNumber(vm, thisValue, x)) 610 return throwVMT ypeError(exec, scope, WTF::makeString("thisNumberValue called on incompatible ", asString(jsTypeStringForValue(exec, thisValue))->value(exec)));622 return throwVMToThisNumberError(exec, scope, exec->thisValue()); 611 623 return JSValue::encode(jsNumber(x)); 612 624 } -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r241991 r242047 30 30 #include "FrameTracers.h" 31 31 #include "InterpreterInlines.h" 32 #include "IntlCollator.h" 32 33 #include "IntlObject.h" 33 34 #include "JITCodeInlines.h" … … 144 145 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("toLowerCase", stringProtoFuncToLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0, StringPrototypeToLowerCaseIntrinsic); 145 146 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toUpperCase", stringProtoFuncToUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); 147 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringProtoFuncLocaleCompare, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 146 148 #if ENABLE(INTL) 147 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringPrototypeLocaleCompareCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));148 149 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleLowerCase", stringProtoFuncToLocaleLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); 149 150 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleUpperCase", stringProtoFuncToLocaleUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); 150 151 #else 151 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringProtoFuncLocaleCompare, static_cast<unsigned>(PropertyAttribute::DontEnum), 1);152 152 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleLowerCase", stringProtoFuncToLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); 153 153 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleUpperCase", stringProtoFuncToUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); … … 1487 1487 EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec) 1488 1488 { 1489 VM& vm = exec->vm(); 1490 auto scope = DECLARE_THROW_SCOPE(vm); 1491 1489 // 13.1.1 String.prototype.localeCompare (that [, locales [, options ]]) (ECMA-402 2.0) 1490 // http://ecma-international.org/publications/standards/Ecma-402.htm 1491 1492 VM& vm = exec->vm(); 1493 auto scope = DECLARE_THROW_SCOPE(vm); 1494 1495 // 1. Let O be RequireObjectCoercible(this value). 1492 1496 JSValue thisValue = exec->thisValue(); 1493 1497 if (!checkObjectCoercible(thisValue)) 1494 return throwVMTypeError(exec, scope); 1495 String s = thisValue.toWTFString(exec); 1496 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1497 1498 JSValue a0 = exec->argument(0); 1499 String str = a0.toWTFString(exec); 1500 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1501 return JSValue::encode(jsNumber(Collator().collate(s, str))); 1498 return throwVMTypeError(exec, scope, "String.prototype.localeCompare requires that |this| not be null or undefined"_s); 1499 1500 // 2. Let S be ToString(O). 1501 // 3. ReturnIfAbrupt(S). 1502 String string = thisValue.toWTFString(exec); 1503 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1504 1505 // 4. Let That be ToString(that). 1506 // 5. ReturnIfAbrupt(That). 1507 JSValue thatValue = exec->argument(0); 1508 String that = thatValue.toWTFString(exec); 1509 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1510 1511 #if ENABLE(INTL) 1512 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); 1513 JSValue locales = exec->argument(1); 1514 JSValue options = exec->argument(2); 1515 IntlCollator* collator = nullptr; 1516 if (locales.isUndefined() && options.isUndefined()) { 1517 collator = globalObject->defaultCollator(exec); 1518 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1519 } else { 1520 collator = IntlCollator::create(vm, globalObject->intlObject()->collatorStructure()); 1521 collator->initializeCollator(*exec, locales, options); 1522 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1523 } 1524 RELEASE_AND_RETURN(scope, JSValue::encode(collator->compareStrings(*exec, string, that))); 1525 #else 1526 return JSValue::encode(jsNumber(Collator().collate(string, that))); 1527 #endif 1502 1528 } 1503 1529
Note: See TracChangeset
for help on using the changeset viewer.