Title: [264275] trunk
Revision
264275
Author
[email protected]
Date
2020-07-11 21:49:00 -0700 (Sat, 11 Jul 2020)

Log Message

Intl.Locale maximize, minimize should return Intl.Locale instead of String
https://bugs.webkit.org/show_bug.cgi?id=214223
<rdar://problem/65413620>

Reviewed by Ross Kirsling.

JSTests:

* stress/intl-locale.js:
(minimize.toString):
(shouldBe):

Source/_javascript_Core:

Intl.Locale#{maximize,minimize} should return Intl.Locale object instead of generated locale string.

We also add some protection and use jsString instead of jsNontrivialString because it would be still
possible that ICU's locale recognition and our locale interpretation do not agree each other and ICU
failed to produce locale, and then the string becomes empty. Since this is a boundary between third-party
library and JSC, and we are not ensuring our invariant inside third-party library, taking safer path makes
it better.

We also change IntlLocale#{maximize,minimize} C++ function names to maximal and minimal to align them
to the sepc's definitions.

* runtime/IntlLocale.cpp:
(JSC::IntlLocale::maximal):
(JSC::IntlLocale::minimal):
(JSC::IntlLocale::maximize): Deleted.
(JSC::IntlLocale::minimize): Deleted.
* runtime/IntlLocale.h:
* runtime/IntlLocalePrototype.cpp:
(JSC::IntlLocalePrototypeFuncMaximize):
(JSC::IntlLocalePrototypeFuncMinimize):
(JSC::IntlLocalePrototypeFuncToString):
(JSC::IntlLocalePrototypeGetterBaseName):
(JSC::IntlLocalePrototypeGetterCalendar):
(JSC::IntlLocalePrototypeGetterCaseFirst):
(JSC::IntlLocalePrototypeGetterCollation):
(JSC::IntlLocalePrototypeGetterHourCycle):
(JSC::IntlLocalePrototypeGetterNumberingSystem):
(JSC::IntlLocalePrototypeGetterLanguage):
(JSC::IntlLocalePrototypeGetterScript):
(JSC::IntlLocalePrototypeGetterRegion):

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (264274 => 264275)


--- trunk/JSTests/ChangeLog	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/JSTests/ChangeLog	2020-07-12 04:49:00 UTC (rev 264275)
@@ -1,3 +1,15 @@
+2020-07-11  Yusuke Suzuki  <[email protected]>
+
+        Intl.Locale maximize, minimize should return Intl.Locale instead of String
+        https://bugs.webkit.org/show_bug.cgi?id=214223
+        <rdar://problem/65413620>
+
+        Reviewed by Ross Kirsling.
+
+        * stress/intl-locale.js:
+        (minimize.toString):
+        (shouldBe):
+
 2020-07-09  Caio Lima  <[email protected]>
 
         [JSC][32-bits] Test gardening July 9th

Modified: trunk/JSTests/stress/intl-locale.js (264274 => 264275)


--- trunk/JSTests/stress/intl-locale.js	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/JSTests/stress/intl-locale.js	2020-07-12 04:49:00 UTC (rev 264275)
@@ -112,22 +112,38 @@
 shouldThrow(() => Intl.Locale.prototype.script, TypeError);
 shouldThrow(() => Intl.Locale.prototype.region, TypeError);
 
-shouldBe(new Intl.Locale('en').maximize(), 'en-Latn-US');
-shouldBe(new Intl.Locale('en-Latn-US').maximize(), 'en-Latn-US');
-shouldBe(new Intl.Locale('en-u-nu-thai-x-foo').maximize(), 'en-Latn-US-u-nu-thai-x-foo');
-shouldBe(new Intl.Locale('ja').maximize(), 'ja-Jpan-JP');
-shouldBe(new Intl.Locale('zh').maximize(), 'zh-Hans-CN');
-shouldBe(new Intl.Locale('zh-Hant').maximize(), 'zh-Hant-TW');
-shouldBe(new Intl.Locale('zh', { script: 'Hant' }).maximize(), 'zh-Hant-TW');
+shouldBe(new Intl.Locale('en').maximize().toString(), 'en-Latn-US');
+shouldBe(new Intl.Locale('en-Latn-US').maximize().toString(), 'en-Latn-US');
+shouldBe(new Intl.Locale('en-u-nu-thai-x-foo').maximize().toString(), 'en-Latn-US-u-nu-thai-x-foo');
+shouldBe(new Intl.Locale('ja').maximize().toString(), 'ja-Jpan-JP');
+shouldBe(new Intl.Locale('zh').maximize().toString(), 'zh-Hans-CN');
+shouldBe(new Intl.Locale('zh-Hant').maximize().toString(), 'zh-Hant-TW');
+shouldBe(new Intl.Locale('zh', { script: 'Hant' }).maximize().toString(), 'zh-Hant-TW');
 
-shouldBe(new Intl.Locale('en').minimize(), 'en');
-shouldBe(new Intl.Locale('en-Latn-US').minimize(), 'en');
-shouldBe(new Intl.Locale('en-Latn-US-u-nu-thai-x-foo').minimize(), 'en-u-nu-thai-x-foo');
-shouldBe(new Intl.Locale('ja-Jpan-JP').minimize(), 'ja');
-shouldBe(new Intl.Locale('zh-Hans-CN').minimize(), 'zh');
-shouldBe(new Intl.Locale('zh-Hant-TW').minimize(), 'zh-TW');
-shouldBe(new Intl.Locale('zh', { script: 'Hant', region: 'TW' }).minimize(), 'zh-TW');
+shouldBe(new Intl.Locale('en').minimize().toString(), 'en');
+shouldBe(new Intl.Locale('en-Latn-US').minimize().toString(), 'en');
+shouldBe(new Intl.Locale('en-Latn-US-u-nu-thai-x-foo').minimize().toString(), 'en-u-nu-thai-x-foo');
+shouldBe(new Intl.Locale('ja-Jpan-JP').minimize().toString(), 'ja');
+shouldBe(new Intl.Locale('zh-Hans-CN').minimize().toString(), 'zh');
+shouldBe(new Intl.Locale('zh-Hant-TW').minimize().toString(), 'zh-TW');
+shouldBe(new Intl.Locale('zh', { script: 'Hant', region: 'TW' }).minimize().toString(), 'zh-TW');
 
+{
+    let locale = new Intl.Locale('en')
+    shouldBe(typeof locale.maximize(), 'object');
+    shouldBe(typeof locale.minimize(), 'object');
+    shouldBe(Object.prototype.toString.call(locale.maximize()), '[object Intl.Locale]');
+    shouldBe(Object.prototype.toString.call(locale.minimize()), '[object Intl.Locale]');
+    shouldBe(locale.maximize().baseName, 'en-Latn-US');
+    shouldBe(locale.minimize().baseName, 'en');
+}
+
+{
+    let locale = new Intl.Locale('ja-Jpan-JP-u-ca-japanese-hc-h23-kf-lower-co-emoji-nu-jpan')
+    shouldBe(locale.maximize().toString(), 'ja-Jpan-JP-u-ca-japanese-co-emoji-hc-h23-kf-lower-nu-jpan');
+    shouldBe(locale.maximize().baseName, 'ja-Jpan-JP');
+}
+
 shouldBe(new Intl.Locale('en').toString(), 'en');
 shouldBe(
     new Intl.Locale('En-laTn-us-variAnt-fOObar-1abc-U-kn-tRue-A-aa-aaa-x-RESERVED').toString(),

Modified: trunk/Source/_javascript_Core/ChangeLog (264274 => 264275)


--- trunk/Source/_javascript_Core/ChangeLog	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-07-12 04:49:00 UTC (rev 264275)
@@ -1,3 +1,42 @@
+2020-07-11  Yusuke Suzuki  <[email protected]>
+
+        Intl.Locale maximize, minimize should return Intl.Locale instead of String
+        https://bugs.webkit.org/show_bug.cgi?id=214223
+        <rdar://problem/65413620>
+
+        Reviewed by Ross Kirsling.
+
+        Intl.Locale#{maximize,minimize} should return Intl.Locale object instead of generated locale string.
+
+        We also add some protection and use jsString instead of jsNontrivialString because it would be still
+        possible that ICU's locale recognition and our locale interpretation do not agree each other and ICU
+        failed to produce locale, and then the string becomes empty. Since this is a boundary between third-party
+        library and JSC, and we are not ensuring our invariant inside third-party library, taking safer path makes
+        it better.
+
+        We also change IntlLocale#{maximize,minimize} C++ function names to maximal and minimal to align them
+        to the sepc's definitions.
+
+        * runtime/IntlLocale.cpp:
+        (JSC::IntlLocale::maximal):
+        (JSC::IntlLocale::minimal):
+        (JSC::IntlLocale::maximize): Deleted.
+        (JSC::IntlLocale::minimize): Deleted.
+        * runtime/IntlLocale.h:
+        * runtime/IntlLocalePrototype.cpp:
+        (JSC::IntlLocalePrototypeFuncMaximize):
+        (JSC::IntlLocalePrototypeFuncMinimize):
+        (JSC::IntlLocalePrototypeFuncToString):
+        (JSC::IntlLocalePrototypeGetterBaseName):
+        (JSC::IntlLocalePrototypeGetterCalendar):
+        (JSC::IntlLocalePrototypeGetterCaseFirst):
+        (JSC::IntlLocalePrototypeGetterCollation):
+        (JSC::IntlLocalePrototypeGetterHourCycle):
+        (JSC::IntlLocalePrototypeGetterNumberingSystem):
+        (JSC::IntlLocalePrototypeGetterLanguage):
+        (JSC::IntlLocalePrototypeGetterScript):
+        (JSC::IntlLocalePrototypeGetterRegion):
+
 2020-07-10  Chris Dumez  <[email protected]>
 
         Unreviewed, reverting r264242.

Modified: trunk/Source/_javascript_Core/runtime/IntlLocale.cpp (264274 => 264275)


--- trunk/Source/_javascript_Core/runtime/IntlLocale.cpp	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/Source/_javascript_Core/runtime/IntlLocale.cpp	2020-07-12 04:49:00 UTC (rev 264275)
@@ -310,9 +310,9 @@
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
-const String& IntlLocale::maximize()
+const String& IntlLocale::maximal()
 {
-    if (m_maximized.isNull()) {
+    if (m_maximal.isNull()) {
         UErrorCode status = U_ZERO_ERROR;
         Vector<char, 32> buffer(32);
         auto bufferLength = uloc_addLikelySubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
@@ -323,15 +323,15 @@
         }
         ASSERT(U_SUCCESS(status));
 
-        m_maximized = languageTagForLocaleID(buffer.data());
+        m_maximal = languageTagForLocaleID(buffer.data());
     }
-    return m_maximized;
+    return m_maximal;
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
-const String& IntlLocale::minimize()
+const String& IntlLocale::minimal()
 {
-    if (m_minimized.isNull()) {
+    if (m_minimal.isNull()) {
         UErrorCode status = U_ZERO_ERROR;
         Vector<char, 32> buffer(32);
         auto bufferLength = uloc_minimizeSubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
@@ -342,9 +342,9 @@
         }
         ASSERT(U_SUCCESS(status));
 
-        m_minimized = languageTagForLocaleID(buffer.data());
+        m_minimal = languageTagForLocaleID(buffer.data());
     }
-    return m_minimized;
+    return m_minimal;
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString

Modified: trunk/Source/_javascript_Core/runtime/IntlLocale.h (264274 => 264275)


--- trunk/Source/_javascript_Core/runtime/IntlLocale.h	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/Source/_javascript_Core/runtime/IntlLocale.h	2020-07-12 04:49:00 UTC (rev 264275)
@@ -52,8 +52,8 @@
     DECLARE_INFO;
 
     void initializeLocale(JSGlobalObject*, JSValue tagValue, JSValue optionsValue);
-    const String& maximize();
-    const String& minimize();
+    const String& maximal();
+    const String& minimal();
     const String& toString();
     const String& baseName();
     const String& language();
@@ -75,8 +75,8 @@
 
     CString m_localeID;
 
-    String m_maximized;
-    String m_minimized;
+    String m_maximal;
+    String m_minimal;
     String m_fullString;
     String m_baseName;
     String m_language;

Modified: trunk/Source/_javascript_Core/runtime/IntlLocalePrototype.cpp (264274 => 264275)


--- trunk/Source/_javascript_Core/runtime/IntlLocalePrototype.cpp	2020-07-12 04:39:31 UTC (rev 264274)
+++ trunk/Source/_javascript_Core/runtime/IntlLocalePrototype.cpp	2020-07-12 04:49:00 UTC (rev 264275)
@@ -105,7 +105,10 @@
     if (!locale)
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.maximize called on value that's not an object initialized as a Locale"_s);
 
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, locale->maximize())));
+    IntlLocale* newLocale = IntlLocale::create(vm, globalObject->localeStructure());
+    scope.release();
+    newLocale->initializeLocale(globalObject, jsString(vm, locale->maximal()), jsUndefined());
+    return JSValue::encode(newLocale);
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
@@ -118,7 +121,10 @@
     if (!locale)
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.minimize called on value that's not an object initialized as a Locale"_s);
 
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, locale->minimize())));
+    IntlLocale* newLocale = IntlLocale::create(vm, globalObject->localeStructure());
+    scope.release();
+    newLocale->initializeLocale(globalObject, jsString(vm, locale->minimal()), jsUndefined());
+    return JSValue::encode(newLocale);
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
@@ -131,7 +137,8 @@
     if (!locale)
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.toString called on value that's not an object initialized as a Locale"_s);
 
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsNontrivialString(vm, locale->toString())));
+    const String& fullString = locale->toString();
+    RELEASE_AND_RETURN(scope, JSValue::encode(fullString.isEmpty() ? jsUndefined() : jsString(vm, fullString)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName
@@ -144,7 +151,8 @@
     if (!locale)
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.baseName called on value that's not an object initialized as a Locale"_s);
 
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsNontrivialString(vm, locale->baseName())));
+    const String& baseName = locale->baseName();
+    RELEASE_AND_RETURN(scope, JSValue::encode(baseName.isEmpty() ? jsUndefined() : jsString(vm, baseName)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
@@ -158,7 +166,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.calendar called on value that's not an object initialized as a Locale"_s);
 
     const String& calendar = locale->calendar();
-    RELEASE_AND_RETURN(scope, JSValue::encode(calendar.isEmpty() ? jsUndefined() : jsNontrivialString(vm, calendar)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(calendar.isEmpty() ? jsUndefined() : jsString(vm, calendar)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
@@ -172,7 +180,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.caseFirst called on value that's not an object initialized as a Locale"_s);
 
     const String& caseFirst = locale->caseFirst();
-    RELEASE_AND_RETURN(scope, JSValue::encode(caseFirst.isEmpty() ? jsUndefined() : jsNontrivialString(vm, caseFirst)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(caseFirst.isEmpty() ? jsUndefined() : jsString(vm, caseFirst)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
@@ -186,7 +194,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.collation called on value that's not an object initialized as a Locale"_s);
 
     const String& collation = locale->collation();
-    RELEASE_AND_RETURN(scope, JSValue::encode(collation.isEmpty() ? jsUndefined() : jsNontrivialString(vm, collation)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(collation.isEmpty() ? jsUndefined() : jsString(vm, collation)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
@@ -200,7 +208,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.hourCycle called on value that's not an object initialized as a Locale"_s);
 
     const String& hourCycle = locale->hourCycle();
-    RELEASE_AND_RETURN(scope, JSValue::encode(hourCycle.isEmpty() ? jsUndefined() : jsNontrivialString(vm, hourCycle)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(hourCycle.isEmpty() ? jsUndefined() : jsString(vm, hourCycle)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
@@ -227,7 +235,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.numberingSystem called on value that's not an object initialized as a Locale"_s);
 
     const String& numberingSystem = locale->numberingSystem();
-    RELEASE_AND_RETURN(scope, JSValue::encode(numberingSystem.isEmpty() ? jsUndefined() : jsNontrivialString(vm, numberingSystem)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(numberingSystem.isEmpty() ? jsUndefined() : jsString(vm, numberingSystem)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language
@@ -240,7 +248,8 @@
     if (!locale)
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.language called on value that's not an object initialized as a Locale"_s);
 
-    RELEASE_AND_RETURN(scope, JSValue::encode(jsNontrivialString(vm, locale->language())));
+    const String& language = locale->language();
+    RELEASE_AND_RETURN(scope, JSValue::encode(language.isEmpty() ? jsUndefined() : jsString(vm, language)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
@@ -254,7 +263,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.script called on value that's not an object initialized as a Locale"_s);
 
     const String& script = locale->script();
-    RELEASE_AND_RETURN(scope, JSValue::encode(script.isEmpty() ? jsUndefined() : jsNontrivialString(vm, script)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(script.isEmpty() ? jsUndefined() : jsString(vm, script)));
 }
 
 // https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
@@ -268,7 +277,7 @@
         return throwVMTypeError(globalObject, scope, "Intl.Locale.prototype.region called on value that's not an object initialized as a Locale"_s);
 
     const String& region = locale->region();
-    RELEASE_AND_RETURN(scope, JSValue::encode(region.isEmpty() ? jsUndefined() : jsNontrivialString(vm, region)));
+    RELEASE_AND_RETURN(scope, JSValue::encode(region.isEmpty() ? jsUndefined() : jsString(vm, region)));
 }
 
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to