WebKit Bugzilla
Attachment 362821 Details for
Bug 194976
: [JSC] Drop direct references to Intl constructors by rewriting Intl JS builtins in C++
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194976-20190223024506.patch (text/plain), 28.80 KB, created by
Yusuke Suzuki
on 2019-02-23 02:45:07 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2019-02-23 02:45:07 PST
Size:
28.80 KB
patch
obsolete
>Subversion Revision: 241988 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 27ba48124e85c295fc7cf9b787511d7d1a4e6c9f..eeedeed3f192767e421c5b6e621d252250649b83 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,51 @@ >+2019-02-23 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Drop direct references to Intl constructors by rewriting Intl JS builtins in C++ >+ https://bugs.webkit.org/show_bug.cgi?id=194976 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch paves the way to making IntlObject allocation lazy by removing direct references >+ to Intl constructors (Intl.Collator etc.) from builtin JS. To achieve that, >+ >+ 1. We implement String.prototype.toLocaleCompare and Number.prototype.toLocaleString in C++ >+ instead of JS builtins. Since these functions end up calling ICU C++ runtime, writing them in >+ JS does not offer performance improvement. >+ >+ 2. We remove @DateTimeFormat constructor reference, and instead, exposing @dateTimeFormat function, >+ which returns formatted string directly. We still have JS builtins for DateTimeFormat things >+ because the initialization of its "options" JSObject involves many get_by_id / put_by_id things, >+ which are efficient in JS. But we avoid exposing @DateTimeFormat directly, so that Intl constructors >+ can be lazily allocated. >+ >+ * CMakeLists.txt: >+ * DerivedSources-input.xcfilelist: >+ * DerivedSources.make: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * builtins/BuiltinNames.h: >+ * builtins/DatePrototype.js: >+ (toLocaleString): >+ (toLocaleDateString): >+ (toLocaleTimeString): >+ * builtins/NumberPrototype.js: Removed. >+ * builtins/StringPrototype.js: >+ (intrinsic.StringPrototypeReplaceIntrinsic.replace): >+ (globalPrivate.getDefaultCollator): Deleted. >+ * runtime/JSGlobalObject.cpp: >+ (JSC::JSGlobalObject::init): >+ (JSC::JSGlobalObject::visitChildren): >+ (JSC::JSGlobalObject::defaultCollator): >+ * runtime/JSGlobalObject.h: >+ * runtime/JSGlobalObjectFunctions.cpp: >+ (JSC::globalFuncDateTimeFormat): >+ * runtime/JSGlobalObjectFunctions.h: >+ * runtime/NumberPrototype.cpp: >+ (JSC::NumberPrototype::finishCreation): >+ (JSC::numberProtoFuncToLocaleString): >+ * runtime/StringPrototype.cpp: >+ (JSC::StringPrototype::finishCreation): >+ (JSC::stringProtoFuncLocaleCompare): >+ > 2019-02-22 Robin Morisset <rmorisset@apple.com> > > DFGBytecodeParser should not declare that a node won't clobberExit if DFGFixupPhase can later declare it does clobberExit >diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt >index 6afab27736b1c154ac49979f8b164cfd2cd9b139..b308978980dc8fb00fd5a37382215dd30776a1e3 100644 >--- a/Source/JavaScriptCore/CMakeLists.txt >+++ b/Source/JavaScriptCore/CMakeLists.txt >@@ -1189,7 +1189,6 @@ set(JavaScriptCore_BUILTINS_SOURCES > ${JAVASCRIPTCORE_DIR}/builtins/MapPrototype.js > ${JAVASCRIPTCORE_DIR}/builtins/ModuleLoader.js > ${JAVASCRIPTCORE_DIR}/builtins/NumberConstructor.js >- ${JAVASCRIPTCORE_DIR}/builtins/NumberPrototype.js > ${JAVASCRIPTCORE_DIR}/builtins/ObjectConstructor.js > ${JAVASCRIPTCORE_DIR}/builtins/PromiseConstructor.js > ${JAVASCRIPTCORE_DIR}/builtins/PromiseOperations.js >diff --git a/Source/JavaScriptCore/DerivedSources-input.xcfilelist b/Source/JavaScriptCore/DerivedSources-input.xcfilelist >index 59ac1c44b925475030a7e5cf31d421928b0fcb5f..6777a5be1e1057a5370dd8d6d3dd035794103051 100644 >--- a/Source/JavaScriptCore/DerivedSources-input.xcfilelist >+++ b/Source/JavaScriptCore/DerivedSources-input.xcfilelist >@@ -43,7 +43,6 @@ $(PROJECT_DIR)/builtins/MapIteratorPrototype.js > $(PROJECT_DIR)/builtins/MapPrototype.js > $(PROJECT_DIR)/builtins/ModuleLoader.js > $(PROJECT_DIR)/builtins/NumberConstructor.js >-$(PROJECT_DIR)/builtins/NumberPrototype.js > $(PROJECT_DIR)/builtins/ObjectConstructor.js > $(PROJECT_DIR)/builtins/PromiseConstructor.js > $(PROJECT_DIR)/builtins/PromiseOperations.js >diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make >index 3b5e10540bbbdb22c3bbd704e17bbe49b2866e40..7fd3bdf0d535d8ffdd3911a04945edefbf64d92f 100644 >--- a/Source/JavaScriptCore/DerivedSources.make >+++ b/Source/JavaScriptCore/DerivedSources.make >@@ -105,7 +105,6 @@ JavaScriptCore_BUILTINS_SOURCES = \ > $(JavaScriptCore)/builtins/MapPrototype.js \ > $(JavaScriptCore)/builtins/ModuleLoader.js \ > $(JavaScriptCore)/builtins/NumberConstructor.js \ >- $(JavaScriptCore)/builtins/NumberPrototype.js \ > $(JavaScriptCore)/builtins/ObjectConstructor.js \ > $(JavaScriptCore)/builtins/PromiseConstructor.js \ > $(JavaScriptCore)/builtins/PromiseOperations.js \ >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 71362904cf888f56318e48990e30119b3937454e..10843304cfc12cbe386fd789077c5e1fde8ad8ab 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -2031,8 +2031,8 @@ > dstPath = testapiScripts; > dstSubfolderSpec = 16; > files = ( >- 52D13091221CE176009C836C /* foo.js in Copy Support Script */, > 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */, >+ 52D13091221CE176009C836C /* foo.js in Copy Support Script */, > FECB8B2A1D25CB5A006F2463 /* testapi-function-overrides.js in Copy Support Script */, > 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */, > ); >@@ -4065,7 +4065,6 @@ > A1587D6C1B4DC14100D69849 /* IntlDateTimeFormatPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatPrototype.h; sourceTree = "<group>"; }; > A1587D731B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatConstructor.lut.h; sourceTree = "<group>"; }; > A1587D741B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatPrototype.lut.h; sourceTree = "<group>"; }; >- A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = NumberPrototype.js; sourceTree = "<group>"; }; > A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; }; > A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; }; > A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; }; >@@ -8192,7 +8191,6 @@ > 7035587C1C418419004BD7BF /* MapPrototype.js */, > E30677971B8BC6F5003F87F0 /* ModuleLoader.js */, > A52704861D027C8800354C37 /* NumberConstructor.js */, >- A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */, > 7CF9BC5C1B65D9B1009DB1EF /* ObjectConstructor.js */, > 7CF9BC5E1B65D9B1009DB1EF /* PromiseConstructor.js */, > 7CF9BC5D1B65D9B1009DB1EF /* PromiseOperations.js */, >@@ -9259,6 +9257,7 @@ > 5B70CFDE1DB69E6600EC23F9 /* JSAsyncFunction.h in Headers */, > 8BC064891E1ABA6400B2B8CA /* JSAsyncGeneratorFunction.h in Headers */, > BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */, >+ 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */, > 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */, > 868921C21F9C0CB7001159F6 /* JSBigInt.h in Headers */, > 86FA9E92142BBB2E001773B7 /* JSBoundFunction.h in Headers */, >@@ -9765,7 +9764,6 @@ > 0FF42748158EBE91004CB9FF /* udis86_syn.h in Headers */, > 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */, > A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */, >- 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */, > A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */, > 866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */, > A7A8AF4217ADB5F3005AB174 /* Uint32Array.h in Headers */, >diff --git a/Source/JavaScriptCore/builtins/BuiltinNames.h b/Source/JavaScriptCore/builtins/BuiltinNames.h >index 39b704d88625423278c1679a9ac7fe4fbc5a4283..1f8260b0fbe72b8d5c7d01f58656961b35c5ce91 100644 >--- a/Source/JavaScriptCore/builtins/BuiltinNames.h >+++ b/Source/JavaScriptCore/builtins/BuiltinNames.h >@@ -126,13 +126,9 @@ namespace JSC { > macro(asyncGeneratorQueueItemNext) \ > macro(asyncGeneratorQueueItemPrevious) \ > macro(generatorResumeMode) \ >- macro(Collator) \ >- macro(DateTimeFormat) \ >- macro(NumberFormat) \ >- macro(PluralRules) \ >+ macro(dateTimeFormat) \ > macro(intlSubstituteValue) \ > macro(thisTimeValue) \ >- macro(thisNumberValue) \ > macro(newTargetLocal) \ > macro(derivedConstructor) \ > macro(isTypedArrayView) \ >diff --git a/Source/JavaScriptCore/builtins/DatePrototype.js b/Source/JavaScriptCore/builtins/DatePrototype.js >index 800ce6c66cbb8478dd9ce1f8bbfd78fbbd7946b3..3be204d59d0af9ab1b9ead1da3190d48961ed142 100644 >--- a/Source/JavaScriptCore/builtins/DatePrototype.js >+++ b/Source/JavaScriptCore/builtins/DatePrototype.js >@@ -77,9 +77,7 @@ else if (opts === null) > > var options = toDateTimeOptionsAnyAll(@argument(1)); > var locales = @argument(0); >- >- var dateFormat = new @DateTimeFormat(locales, options); >- return dateFormat.format(value); >+ return @dateTimeFormat(locales, options, value); > } > > function toLocaleDateString(/* locales, options */) >@@ -127,9 +125,7 @@ else if (opts === null) > > var options = toDateTimeOptionsDateDate(@argument(1)); > var locales = @argument(0); >- >- var dateFormat = new @DateTimeFormat(locales, options); >- return dateFormat.format(value); >+ return @dateTimeFormat(locales, options, value); > } > > function toLocaleTimeString(/* locales, options */) >@@ -176,7 +172,5 @@ else if (opts === null) > > var options = toDateTimeOptionsTimeTime(@argument(1)); > var locales = @argument(0); >- >- var dateFormat = new @DateTimeFormat(locales, options); >- return dateFormat.format(value); >+ return @dateTimeFormat(locales, options, value); > } >diff --git a/Source/JavaScriptCore/builtins/NumberPrototype.js b/Source/JavaScriptCore/builtins/NumberPrototype.js >deleted file mode 100644 >index c560a9be053bd172722f9505cf056eb903bdb566..0000000000000000000000000000000000000000 >--- a/Source/JavaScriptCore/builtins/NumberPrototype.js >+++ /dev/null >@@ -1,45 +0,0 @@ >-/* >- * Copyright (C) 2015 Andy VanWagoner <andy@vanwagoner.family>. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-// @conditional=ENABLE(INTL) >- >-function toLocaleString(/* locales, options */) >-{ >- "use strict"; >- >- // 13.2.1 Number.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0) >- // http://ecma-international.org/publications/standards/Ecma-402.htm >- >- // 1. Let x be thisNumberValue(this value). >- // 2. ReturnIfAbrupt(x). >- var number = @thisNumberValue.@call(this); >- >- // 3. Let numberFormat be Construct(%NumberFormat%, «locales, options»). >- // 4. ReturnIfAbrupt(numberFormat). >- var numberFormat = new @NumberFormat(@argument(0), @argument(1)); >- >- // 5. Return FormatNumber(numberFormat, x). >- return numberFormat.format(number); >-} >diff --git a/Source/JavaScriptCore/builtins/StringPrototype.js b/Source/JavaScriptCore/builtins/StringPrototype.js >index 80fc826318949a02a0657803be64cf82369e5888..1ca93c5bff7d61bcd2e62b06457f4e00df9d4141 100644 >--- a/Source/JavaScriptCore/builtins/StringPrototype.js >+++ b/Source/JavaScriptCore/builtins/StringPrototype.js >@@ -237,47 +237,6 @@ function replace(search, replace) > let searchString = @toString(search); > return thisString.@replaceUsingStringSearch(searchString, replace); > } >- >-@globalPrivate >-function getDefaultCollator() >-{ >- "use strict"; >- >- return @getDefaultCollator.collator || (@getDefaultCollator.collator = new @Collator()); >-} >- >-function localeCompare(that/*, locales, options */) >-{ >- "use strict"; >- >- // 13.1.1 String.prototype.localeCompare (that [, locales [, options ]]) (ECMA-402 2.0) >- // http://ecma-international.org/publications/standards/Ecma-402.htm >- >- // 1. Let O be RequireObjectCoercible(this value). >- if (@isUndefinedOrNull(this)) >- @throwTypeError("String.prototype.localeCompare requires that |this| not be null or undefined"); >- >- // 2. Let S be ToString(O). >- // 3. ReturnIfAbrupt(S). >- var thisString = @toString(this); >- >- // 4. Let That be ToString(that). >- // 5. ReturnIfAbrupt(That). >- var thatString = @toString(that); >- >- // Avoid creating a new collator every time for defaults. >- var locales = @argument(1); >- var options = @argument(2); >- if (locales === @undefined && options === @undefined) >- return @getDefaultCollator().compare(thisString, thatString); >- >- // 6. Let collator be Construct(%Collator%, «locales, options»). >- // 7. ReturnIfAbrupt(collator). >- var collator = new @Collator(locales, options); >- >- // 8. Return CompareStrings(collator, S, That). >- return collator.compare(thisString, thatString); >-} > > function search(regexp) > { >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >index a91abd7bc36a6f3a894cb2f357d4d4a8c77bedbb..6386604ebe48ef37b6ba26d10feada39c5149ab6 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -178,6 +178,7 @@ > #include <wtf/RandomNumber.h> > > #if ENABLE(INTL) >+#include "IntlCollator.h" > #include "IntlObject.h" > #include <unicode/ucol.h> > #include <unicode/udat.h> >@@ -830,7 +831,9 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct > JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction); > JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf); > JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime); >- JSFunction* privateFuncThisNumberValue = JSFunction::create(vm, this, 0, String(), numberProtoFuncValueOf); >+#if ENABLE(INTL) >+ JSFunction* privateFuncDateTimeFormat = JSFunction::create(vm, this, 0, String(), globalFuncDateTimeFormat); >+#endif > JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor); > JSFunction* privateFuncIsArraySlow = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArraySlow); > JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy); >@@ -920,12 +923,8 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct > GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), > GlobalPropertyInfo(vm.propertyNames->builtinNames().SetPrivateName(), setConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), > GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >- GlobalPropertyInfo(vm.propertyNames->builtinNames().thisNumberValuePrivateName(), privateFuncThisNumberValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), > #if ENABLE(INTL) >- GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >- GlobalPropertyInfo(vm.propertyNames->builtinNames().DateTimeFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->DateTimeFormat), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >- GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->NumberFormat), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >- GlobalPropertyInfo(vm.propertyNames->builtinNames().PluralRulesPrivateName(), intl->getDirect(vm, vm.propertyNames->PluralRules), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >+ GlobalPropertyInfo(vm.propertyNames->builtinNames().dateTimeFormatPrivateName(), privateFuncDateTimeFormat, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), > #endif // ENABLE(INTL) > > GlobalPropertyInfo(vm.propertyNames->builtinNames().isConstructorPrivateName(), JSFunction::create(vm, this, 1, String(), esSpecIsConstructor, NoIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), >@@ -1568,6 +1567,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) > > #if ENABLE(INTL) > visitor.append(thisObject->m_intlObject); >+ visitor.append(thisObject->m_defaultCollator); > #endif > visitor.append(thisObject->m_nullGetterFunction); > visitor.append(thisObject->m_nullSetterFunction); >@@ -1865,6 +1865,22 @@ const HashSet<String>& JSGlobalObject::intlPluralRulesAvailableLocales() > } > return m_intlPluralRulesAvailableLocales; > } >+ >+IntlCollator* JSGlobalObject::defaultCollator(ExecState* exec) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ if (m_defaultCollator) >+ return m_defaultCollator.get(); >+ >+ IntlCollator* collator = IntlCollator::create(vm, intlObject()->collatorStructure()); >+ collator->initializeCollator(*exec, jsUndefined(), jsUndefined()); >+ RETURN_IF_EXCEPTION(scope, nullptr); >+ m_defaultCollator.set(vm, this, collator); >+ return collator; >+} >+ > #endif // ENABLE(INTL) > > void JSGlobalObject::bumpGlobalLexicalBindingEpoch(VM& vm) >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h >index befbd227a99513ddd57989998a6575ee53444275..561272396bba4bea99aa29f5ed7a20fde116fb4d 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h >@@ -83,6 +83,7 @@ class GlobalCodeBlock; > class IndirectEvalExecutable; > class InputCursor; > class IntlObject; >+class IntlCollator; > class JSArrayBuffer; > class JSArrayBufferPrototype; > class JSCallee; >@@ -276,6 +277,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > > #if ENABLE(INTL) > WriteBarrier<IntlObject> m_intlObject; >+ WriteBarrier<IntlCollator> m_defaultCollator; > #endif > WriteBarrier<NullGetterFunction> m_nullGetterFunction; > WriteBarrier<NullSetterFunction> m_nullSetterFunction; >@@ -587,6 +589,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > > #if ENABLE(INTL) > IntlObject* intlObject() const { return m_intlObject.get(); } >+ IntlCollator* defaultCollator(ExecState*); > #endif > > NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); } >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >index 17ee33f049f28ff0cdc9ad669d76f3e1c6e83855..4a6d81932cdc8329863d57c02b3ba21b6a1d86bd 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >@@ -31,6 +31,8 @@ > #include "Exception.h" > #include "IndirectEvalExecutable.h" > #include "Interpreter.h" >+#include "IntlDateTimeFormat.h" >+#include "IntlObject.h" > #include "JSCInlines.h" > #include "JSFunction.h" > #include "JSGlobalObject.h" >@@ -830,4 +832,20 @@ EncodedJSValue JSC_HOST_CALL globalFuncPropertyIsEnumerable(ExecState* exec) > return JSValue::encode(jsBoolean(enumerable)); > } > >+#if ENABLE(INTL) >+EncodedJSValue JSC_HOST_CALL globalFuncDateTimeFormat(ExecState* exec) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ JSGlobalObject* globalObject = exec->lexicalGlobalObject(); >+ IntlDateTimeFormat* dateTimeFormat = IntlDateTimeFormat::create(vm, globalObject->intlObject()->dateTimeFormatStructure()); >+ dateTimeFormat->initializeDateTimeFormat(*exec, exec->argument(0), exec->argument(1)); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ double value = exec->argument(2).toNumber(exec); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ RELEASE_AND_RETURN(scope, JSValue::encode(dateTimeFormat->format(*exec, value))); >+} >+#endif >+ > } // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h >index c23eb9be47c6819b78b5cb09a1ba5414737fc7c1..e77552407815df7478117cbc9d008a1e05906cd0 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h >@@ -55,6 +55,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*); > EncodedJSValue JSC_HOST_CALL globalFuncBuiltinDescribe(ExecState*); > EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*); > EncodedJSValue JSC_HOST_CALL globalFuncPropertyIsEnumerable(ExecState*); >+EncodedJSValue JSC_HOST_CALL globalFuncDateTimeFormat(ExecState*); > > double jsToNumber(StringView); > >diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp >index c83783a0d532ecf315c7129c556b023241bd0897..0106d20c6dd9428571c55b32498953637bff7cc8 100644 >--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp >@@ -24,7 +24,8 @@ > > #include "BigInteger.h" > #include "Error.h" >-#include "JSCBuiltins.h" >+#include "IntlNumberFormat.h" >+#include "IntlObject.h" > #include "JSCInlines.h" > #include "JSFunction.h" > #include "JSGlobalObject.h" >@@ -80,10 +81,6 @@ void NumberPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) > setInternalValue(vm, jsNumber(0)); > > JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, numberProtoFuncToString, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, NumberPrototypeToStringIntrinsic); >-#if ENABLE(INTL) >- JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("toLocaleString", numberPrototypeToLocaleStringCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum)); >-#endif // ENABLE(INTL) >- > ASSERT(inherits(vm, info())); > } > >@@ -596,7 +593,15 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec) > if (!toThisNumber(vm, exec->thisValue(), x)) > return throwVMTypeError(exec, scope); > >+#if ENABLE(INTL) >+ JSGlobalObject* globalObject = exec->lexicalGlobalObject(); >+ IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, globalObject->intlObject()->numberFormatStructure()); >+ numberFormat->initializeNumberFormat(*exec, exec->argument(0), exec->argument(1)); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ RELEASE_AND_RETURN(scope, JSValue::encode(numberFormat->formatNumber(*exec, x))); >+#else > return JSValue::encode(jsNumber(x).toString(exec)); >+#endif > } > > EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec) >diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp >index 28b862d52138bba90a65c5011ecedef91f148696..48efa74e9246c4d29b4146bb1bda390f0a387a68 100644 >--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp >@@ -29,6 +29,7 @@ > #include "Error.h" > #include "FrameTracers.h" > #include "InterpreterInlines.h" >+#include "IntlCollator.h" > #include "IntlObject.h" > #include "JITCodeInlines.h" > #include "JSArray.h" >@@ -143,12 +144,11 @@ void StringPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject, JSStr > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("substring", stringProtoFuncSubstring, static_cast<unsigned>(PropertyAttribute::DontEnum), 2); > JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("toLowerCase", stringProtoFuncToLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0, StringPrototypeToLowerCaseIntrinsic); > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toUpperCase", stringProtoFuncToUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); >+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringProtoFuncLocaleCompare, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); > #if ENABLE(INTL) >- JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringPrototypeLocaleCompareCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum)); > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleLowerCase", stringProtoFuncToLocaleLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleUpperCase", stringProtoFuncToLocaleUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); > #else >- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("localeCompare", stringProtoFuncLocaleCompare, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleLowerCase", stringProtoFuncToLowerCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("toLocaleUpperCase", stringProtoFuncToUpperCase, static_cast<unsigned>(PropertyAttribute::DontEnum), 0); > #endif >@@ -1479,19 +1479,45 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) > > EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec) > { >+ // 13.1.1 String.prototype.localeCompare (that [, locales [, options ]]) (ECMA-402 2.0) >+ // http://ecma-international.org/publications/standards/Ecma-402.htm >+ > VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >+ // 1. Let O be RequireObjectCoercible(this value). > JSValue thisValue = exec->thisValue(); > if (!checkObjectCoercible(thisValue)) > return throwVMTypeError(exec, scope); >- String s = thisValue.toWTFString(exec); >+ >+ // 2. Let S be ToString(O). >+ // 3. ReturnIfAbrupt(S). >+ String string = thisValue.toWTFString(exec); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > >- JSValue a0 = exec->argument(0); >- String str = a0.toWTFString(exec); >+ // 4. Let That be ToString(that). >+ // 5. ReturnIfAbrupt(That). >+ JSValue thatValue = exec->argument(0); >+ String that = thatValue.toWTFString(exec); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- return JSValue::encode(jsNumber(Collator().collate(s, str))); >+ >+#if ENABLE(INTL) >+ JSGlobalObject* globalObject = exec->lexicalGlobalObject(); >+ JSValue locales = exec->argument(1); >+ JSValue options = exec->argument(2); >+ IntlCollator* collator = nullptr; >+ if (locales.isUndefined() && options.isUndefined()) { >+ collator = globalObject->defaultCollator(exec); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ } else { >+ collator = IntlCollator::create(vm, globalObject->intlObject()->collatorStructure()); >+ collator->initializeCollator(*exec, locales, options); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ } >+ RELEASE_AND_RETURN(scope, JSValue::encode(collator->compareStrings(*exec, string, that))); >+#else >+ return JSValue::encode(jsNumber(Collator().collate(string, that))); >+#endif > } > > #if ENABLE(INTL)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194976
:
362821
|
362822
|
362823
|
362825
|
362826
|
362837