Title: [260411] trunk/Source/_javascript_Core
Revision
260411
Author
ross.kirsl...@sony.com
Date
2020-04-20 21:04:10 -0700 (Mon, 20 Apr 2020)

Log Message

Intl classes shouldn't need an m_initialized* field
https://bugs.webkit.org/show_bug.cgi?id=210764

Reviewed by Darin Adler.

Existing Intl classes each have a field like m_initializedNumberFormat, but this is unnecessary on two levels:
  1. The thing that gets initialized is a unique pointer to an ICU struct, so we can check it directly.
  2. Everywhere we're checking this is redundant since we've already done the same check on the prototype side,
     therefore we can just ASSERT before using said ICU struct.

While we're at it, clean up other stuff like:
  - Move stuff that doesn't need to be part of the class to the CPP file (e.g. UFieldPositionIteratorDeleter).
  - Merge createCollator into initializeCollator (seems like this is probably the oldest code in this space).

* runtime/IntlCollator.cpp:
(JSC::IntlCollator::initializeCollator):
(JSC::IntlCollator::compareStrings):
(JSC::IntlCollator::resolvedOptions):
(JSC::IntlCollator::createCollator): Deleted.
* runtime/IntlCollator.h:
* runtime/IntlDateTimeFormat.cpp:
(JSC::UFieldPositionIteratorDeleter::operator() const):
(JSC::IntlDateTimeFormat::initializeDateTimeFormat):
(JSC::IntlDateTimeFormat::resolvedOptions):
(JSC::IntlDateTimeFormat::format):
(JSC::partTypeString):
(JSC::IntlDateTimeFormat::formatToParts):
(JSC::IntlDateTimeFormat::UFieldPositionIteratorDeleter::operator() const): Deleted.
(JSC::IntlDateTimeFormat::partTypeString): Deleted.
* runtime/IntlDateTimeFormat.h:
* runtime/IntlNumberFormat.cpp:
(JSC::UFieldPositionIteratorDeleter::operator() const):
(JSC::IntlNumberFormatField::IntlNumberFormatField):
(JSC::IntlNumberFormat::initializeNumberFormat):
(JSC::IntlNumberFormat::format):
(JSC::IntlNumberFormat::resolvedOptions):
(JSC::partTypeString):
(JSC::IntlNumberFormat::formatToParts):
(JSC::IntlNumberFormat::UFieldPositionIteratorDeleter::operator() const): Deleted.
(JSC::IntlNumberFormat::partTypeString): Deleted.
* runtime/IntlNumberFormat.h:
* runtime/IntlPluralRules.cpp:
(JSC::localeData):
(JSC::IntlPluralRules::initializePluralRules):
(JSC::IntlPluralRules::resolvedOptions):
(JSC::IntlPluralRules::select):
(JSC::IntlPRInternal::localeData): Deleted.
* runtime/IntlPluralRules.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (260410 => 260411)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-21 04:04:10 UTC (rev 260411)
@@ -1,3 +1,54 @@
+2020-04-20  Ross Kirsling  <ross.kirsl...@sony.com>
+
+        Intl classes shouldn't need an m_initialized* field
+        https://bugs.webkit.org/show_bug.cgi?id=210764
+
+        Reviewed by Darin Adler.
+
+        Existing Intl classes each have a field like m_initializedNumberFormat, but this is unnecessary on two levels:
+          1. The thing that gets initialized is a unique pointer to an ICU struct, so we can check it directly.
+          2. Everywhere we're checking this is redundant since we've already done the same check on the prototype side,
+             therefore we can just ASSERT before using said ICU struct.
+
+        While we're at it, clean up other stuff like:
+          - Move stuff that doesn't need to be part of the class to the CPP file (e.g. UFieldPositionIteratorDeleter).
+          - Merge createCollator into initializeCollator (seems like this is probably the oldest code in this space).
+
+        * runtime/IntlCollator.cpp:
+        (JSC::IntlCollator::initializeCollator):
+        (JSC::IntlCollator::compareStrings):
+        (JSC::IntlCollator::resolvedOptions):
+        (JSC::IntlCollator::createCollator): Deleted.
+        * runtime/IntlCollator.h:
+        * runtime/IntlDateTimeFormat.cpp:
+        (JSC::UFieldPositionIteratorDeleter::operator() const):
+        (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
+        (JSC::IntlDateTimeFormat::resolvedOptions):
+        (JSC::IntlDateTimeFormat::format):
+        (JSC::partTypeString):
+        (JSC::IntlDateTimeFormat::formatToParts):
+        (JSC::IntlDateTimeFormat::UFieldPositionIteratorDeleter::operator() const): Deleted.
+        (JSC::IntlDateTimeFormat::partTypeString): Deleted.
+        * runtime/IntlDateTimeFormat.h:
+        * runtime/IntlNumberFormat.cpp:
+        (JSC::UFieldPositionIteratorDeleter::operator() const):
+        (JSC::IntlNumberFormatField::IntlNumberFormatField):
+        (JSC::IntlNumberFormat::initializeNumberFormat):
+        (JSC::IntlNumberFormat::format):
+        (JSC::IntlNumberFormat::resolvedOptions):
+        (JSC::partTypeString):
+        (JSC::IntlNumberFormat::formatToParts):
+        (JSC::IntlNumberFormat::UFieldPositionIteratorDeleter::operator() const): Deleted.
+        (JSC::IntlNumberFormat::partTypeString): Deleted.
+        * runtime/IntlNumberFormat.h:
+        * runtime/IntlPluralRules.cpp:
+        (JSC::localeData):
+        (JSC::IntlPluralRules::initializePluralRules):
+        (JSC::IntlPluralRules::resolvedOptions):
+        (JSC::IntlPluralRules::select):
+        (JSC::IntlPRInternal::localeData): Deleted.
+        * runtime/IntlPluralRules.h:
+
 2020-04-20  Keith Miller  <keith_mil...@apple.com>
 
         FTL doesn't observe the use kind of CheckIsConstant's child1

Modified: trunk/Source/_javascript_Core/runtime/IntlCollator.cpp (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlCollator.cpp	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlCollator.cpp	2020-04-21 04:04:10 UTC (rev 260411)
@@ -165,14 +165,12 @@
     return keyLocaleData;
 }
 
+// https://tc39.github.io/ecma402/#sec-initializecollator
 void IntlCollator::initializeCollator(JSGlobalObject* globalObject, JSValue locales, JSValue optionsValue)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 10.1.1 InitializeCollator (collator, locales, options) (ECMA-402)
-    // https://tc39.github.io/ecma402/#sec-initializecollator
-
     auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
     RETURN_IF_EXCEPTION(scope, void());
 
@@ -229,10 +227,10 @@
     m_collation = collation.isNull() ? "default"_s : collation;
     m_numeric = result.get("kn"_s) == "true";
 
-    const String& caseFirst = result.get("kf"_s);
-    if (caseFirst == "lower")
+    const String& caseFirstString = result.get("kf"_s);
+    if (caseFirstString == "lower")
         m_caseFirst = CaseFirst::Lower;
-    else if (caseFirst == "upper")
+    else if (caseFirstString == "upper")
         m_caseFirst = CaseFirst::Upper;
     else
         m_caseFirst = CaseFirst::False;
@@ -250,29 +248,17 @@
 
     bool usesFallback;
     bool ignorePunctuation = intlBooleanOption(globalObject, options, vm.propertyNames->ignorePunctuation, usesFallback);
+    RETURN_IF_EXCEPTION(scope, void());
     if (usesFallback)
         ignorePunctuation = false;
-    RETURN_IF_EXCEPTION(scope, void());
     m_ignorePunctuation = ignorePunctuation;
 
-    m_initializedCollator = true;
-}
-
-void IntlCollator::createCollator(JSGlobalObject* globalObject)
-{
-    VM& vm = globalObject->vm();
-    auto scope = DECLARE_CATCH_SCOPE(vm);
-    ASSERT(!m_collator);
-
-    if (!m_initializedCollator) {
-        initializeCollator(globalObject, jsUndefined(), jsUndefined());
-        scope.assertNoException();
-    }
-
     UErrorCode status = U_ZERO_ERROR;
-    auto collator = std::unique_ptr<UCollator, UCollatorDeleter>(ucol_open(m_locale.utf8().data(), &status));
-    if (U_FAILURE(status))
+    m_collator = std::unique_ptr<UCollator, UCollatorDeleter>(ucol_open(m_locale.utf8().data(), &status));
+    if (U_FAILURE(status)) {
+        throwTypeError(globalObject, scope, "failed to initialize Collator"_s);
         return;
+    }
 
     UColAttributeValue strength = UCOL_PRIMARY;
     UColAttributeValue caseLevel = UCOL_OFF;
@@ -301,36 +287,29 @@
         break;
     }
 
-    ucol_setAttribute(collator.get(), UCOL_STRENGTH, strength, &status);
-    ucol_setAttribute(collator.get(), UCOL_CASE_LEVEL, caseLevel, &status);
-    ucol_setAttribute(collator.get(), UCOL_CASE_FIRST, caseFirst, &status);
-    ucol_setAttribute(collator.get(), UCOL_NUMERIC_COLLATION, m_numeric ? UCOL_ON : UCOL_OFF, &status);
+    ucol_setAttribute(m_collator.get(), UCOL_STRENGTH, strength, &status);
+    ucol_setAttribute(m_collator.get(), UCOL_CASE_LEVEL, caseLevel, &status);
+    ucol_setAttribute(m_collator.get(), UCOL_CASE_FIRST, caseFirst, &status);
+    ucol_setAttribute(m_collator.get(), UCOL_NUMERIC_COLLATION, m_numeric ? UCOL_ON : UCOL_OFF, &status);
 
     // FIXME: Setting UCOL_ALTERNATE_HANDLING to UCOL_SHIFTED causes punctuation and whitespace to be
     // ignored. There is currently no way to ignore only punctuation.
-    ucol_setAttribute(collator.get(), UCOL_ALTERNATE_HANDLING, m_ignorePunctuation ? UCOL_SHIFTED : UCOL_DEFAULT, &status);
+    ucol_setAttribute(m_collator.get(), UCOL_ALTERNATE_HANDLING, m_ignorePunctuation ? UCOL_SHIFTED : UCOL_DEFAULT, &status);
 
     // "The method is required to return 0 when comparing Strings that are considered canonically
     // equivalent by the Unicode standard."
-    ucol_setAttribute(collator.get(), UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
-    if (U_FAILURE(status))
-        return;
-
-    m_collator = WTFMove(collator);
+    ucol_setAttribute(m_collator.get(), UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
+    ASSERT(U_SUCCESS(status));
 }
 
+// https://tc39.es/ecma402/#sec-collator-comparestrings
 JSValue IntlCollator::compareStrings(JSGlobalObject* globalObject, StringView x, StringView y)
 {
+    ASSERT(m_collator);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 10.3.4 CompareStrings abstract operation (ECMA-402 2.0)
-    if (!m_collator) {
-        createCollator(globalObject);
-        if (!m_collator)
-            return throwException(globalObject, scope, createError(globalObject, "Failed to compare strings."_s));
-    }
-
     UErrorCode status = U_ZERO_ERROR;
     UCollationResult result = UCOL_EQUAL;
     if (x.is8Bit() && y.is8Bit() && x.isAllASCII() && y.isAllASCII())
@@ -397,25 +376,10 @@
     return ASCIILiteral::null();
 }
 
+// https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions
 JSObject* IntlCollator::resolvedOptions(JSGlobalObject* globalObject)
 {
     VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    // 10.3.5 Intl.Collator.prototype.resolvedOptions() (ECMA-402 2.0)
-    // The function returns a new object whose properties and attributes are set as if
-    // constructed by an object literal assigning to each of the following properties the
-    // value of the corresponding internal slot of this Collator object (see 10.4): locale,
-    // usage, sensitivity, ignorePunctuation, collation, as well as those properties shown
-    // in Table 1 whose keys are included in the %Collator%[[relevantExtensionKeys]]
-    // internal slot of the standard built-in object that is the initial value of
-    // Intl.Collator.
-
-    if (!m_initializedCollator) {
-        initializeCollator(globalObject, jsUndefined(), jsUndefined());
-        scope.assertNoException();
-    }
-
     JSObject* options = constructEmptyObject(globalObject);
     options->putDirect(vm, vm.propertyNames->locale, jsString(vm, m_locale));
     options->putDirect(vm, vm.propertyNames->usage, jsNontrivialString(vm, usageString(m_usage)));

Modified: trunk/Source/_javascript_Core/runtime/IntlCollator.h (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlCollator.h	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlCollator.h	2020-04-21 04:04:10 UTC (rev 260411)
@@ -76,21 +76,20 @@
         void operator()(UCollator*) const;
     };
 
-    void createCollator(JSGlobalObject*);
     static ASCIILiteral usageString(Usage);
     static ASCIILiteral sensitivityString(Sensitivity);
     static ASCIILiteral caseFirstString(CaseFirst);
 
+    WriteBarrier<JSBoundFunction> m_boundCompare;
+    std::unique_ptr<UCollator, UCollatorDeleter> m_collator;
+
     String m_locale;
     String m_collation;
-    WriteBarrier<JSBoundFunction> m_boundCompare;
-    std::unique_ptr<UCollator, UCollatorDeleter> m_collator;
     Usage m_usage;
     Sensitivity m_sensitivity;
     CaseFirst m_caseFirst;
     bool m_numeric;
     bool m_ignorePunctuation;
-    bool m_initializedCollator { false };
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp	2020-04-21 04:04:10 UTC (rev 260411)
@@ -54,6 +54,14 @@
 static const size_t indexOfExtensionKeyNu = 1;
 static const size_t indexOfExtensionKeyHc = 2;
 
+struct UFieldPositionIteratorDeleter {
+    void operator()(UFieldPositionIterator* iterator) const
+    {
+        if (iterator)
+            ufieldpositer_close(iterator);
+    }
+};
+
 void IntlDateTimeFormat::UDateFormatDeleter::operator()(UDateFormat* dateFormat) const
 {
     if (dateFormat)
@@ -60,12 +68,6 @@
         udat_close(dateFormat);
 }
 
-void IntlDateTimeFormat::UFieldPositionIteratorDeleter::operator()(UFieldPositionIterator* iterator) const
-{
-    if (iterator)
-        ufieldpositer_close(iterator);
-}
-
 IntlDateTimeFormat* IntlDateTimeFormat::create(VM& vm, Structure* structure)
 {
     IntlDateTimeFormat* format = new (NotNull, allocateCell<IntlDateTimeFormat>(vm.heap)) IntlDateTimeFormat(vm, structure);
@@ -437,14 +439,12 @@
     }
 }
 
+// https://tc39.github.io/ecma402/#sec-initializedatetimeformat
 void IntlDateTimeFormat::initializeDateTimeFormat(JSGlobalObject* globalObject, JSValue locales, JSValue originalOptions)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 12.1.1 InitializeDateTimeFormat (dateTimeFormat, locales, options) (ECMA-402)
-    // https://tc39.github.io/ecma402/#sec-initializedatetimeformat
-
     Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, locales);
     RETURN_IF_EXCEPTION(scope, void());
 
@@ -701,8 +701,6 @@
     // Failure here means unsupported calendar, and can safely be ignored.
     UCalendar* cal = const_cast<UCalendar*>(udat_getCalendar(m_dateFormat.get()));
     ucal_setGregorianChange(cal, minECMAScriptTime, &status);
-
-    m_initializedDateTimeFormat = true;
 }
 
 ASCIILiteral IntlDateTimeFormat::weekdayString(Weekday weekday)
@@ -850,19 +848,11 @@
     return ASCIILiteral::null();
 }
 
+// https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
 JSObject* IntlDateTimeFormat::resolvedOptions(JSGlobalObject* globalObject)
 {
     VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 12.3.5 Intl.DateTimeFormat.prototype.resolvedOptions() (ECMA-402 2.0)
-    // The function returns a new object whose properties and attributes are set as if constructed by an object literal assigning to each of the following properties the value of the corresponding internal slot of this DateTimeFormat object (see 12.4): locale, calendar, numberingSystem, timeZone, hour12, weekday, era, year, month, day, hour, minute, second, and timeZoneName. Properties whose corresponding internal slots are not present are not assigned.
-    // Note: In this version of the ECMAScript 2015 Internationalization API, the timeZone property will be the name of the default time zone if no timeZone property was provided in the options object provided to the Intl.DateTimeFormat constructor. The previous version left the timeZone property undefined in this case.
-    if (!m_initializedDateTimeFormat) {
-        initializeDateTimeFormat(globalObject, jsUndefined(), jsUndefined());
-        scope.assertNoException();
-    }
-
     JSObject* options = constructEmptyObject(globalObject);
     options->putDirect(vm, vm.propertyNames->locale, jsNontrivialString(vm, m_locale));
     options->putDirect(vm, vm.propertyNames->calendar, jsNontrivialString(vm, m_calendar));
@@ -904,22 +894,17 @@
     return options;
 }
 
+// https://tc39.es/ecma402/#sec-formatdatetime
 JSValue IntlDateTimeFormat::format(JSGlobalObject* globalObject, double value)
 {
+    ASSERT(m_dateFormat);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 12.3.4 FormatDateTime abstract operation (ECMA-402 2.0)
-    if (!m_initializedDateTimeFormat) {
-        initializeDateTimeFormat(globalObject, jsUndefined(), jsUndefined());
-        scope.assertNoException();
-    }
-
-    // 1. If x is not a finite Number, then throw a RangeError exception.
     if (!std::isfinite(value))
         return throwRangeError(globalObject, scope, "date value is not finite in DateTimeFormat format()"_s);
 
-    // Delegate remaining steps to ICU.
     UErrorCode status = U_ZERO_ERROR;
     Vector<UChar, 32> result(32);
     auto resultLength = udat_format(m_dateFormat.get(), value, result.data(), result.size(), nullptr, &status);
@@ -934,7 +919,7 @@
     return jsString(vm, String(result.data(), resultLength));
 }
 
-ASCIILiteral IntlDateTimeFormat::partTypeString(UDateFormatField field)
+static ASCIILiteral partTypeString(UDateFormatField field)
 {
     switch (field) {
     case UDAT_ERA_FIELD:
@@ -996,15 +981,14 @@
     return "unknown"_s;
 }
 
-
+// https://tc39.es/ecma402/#sec-formatdatetimetoparts
 JSValue IntlDateTimeFormat::formatToParts(JSGlobalObject* globalObject, double value)
 {
+    ASSERT(m_dateFormat);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 12.1.8 FormatDateTimeToParts (ECMA-402 4.0)
-    // https://tc39.github.io/ecma402/#sec-formatdatetimetoparts
-
     if (!std::isfinite(value))
         return throwRangeError(globalObject, scope, "date value is not finite in DateTimeFormat formatToParts()"_s);
 

Modified: trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.h (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.h	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.h	2020-04-21 04:04:10 UTC (rev 260411)
@@ -110,13 +110,6 @@
     Minute m_minute { Minute::None };
     Second m_second { Second::None };
     TimeZoneName m_timeZoneName { TimeZoneName::None };
-    bool m_initializedDateTimeFormat { false };
-
-    struct UFieldPositionIteratorDeleter {
-        void operator()(UFieldPositionIterator*) const;
-    };
-
-    static ASCIILiteral partTypeString(UDateFormatField);
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp	2020-04-21 04:04:10 UTC (rev 260411)
@@ -44,6 +44,19 @@
 
 static const char* const relevantNumberExtensionKeys[1] = { "nu" };
 
+struct UFieldPositionIteratorDeleter {
+    void operator()(UFieldPositionIterator* iterator) const
+    {
+        if (iterator)
+            ufieldpositer_close(iterator);
+    }
+};
+
+struct IntlNumberFormatField {
+    int32_t type;
+    size_t size;
+};
+
 void IntlNumberFormat::UNumberFormatDeleter::operator()(UNumberFormat* numberFormat) const
 {
     if (numberFormat)
@@ -150,14 +163,12 @@
     return 2;
 }
 
+// https://tc39.github.io/ecma402/#sec-initializenumberformat
 void IntlNumberFormat::initializeNumberFormat(JSGlobalObject* globalObject, JSValue locales, JSValue optionsValue)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 11.1.2 InitializeNumberFormat (numberFormat, locales, options) (ECMA-402)
-    // https://tc39.github.io/ecma402/#sec-initializenumberformat
-
     auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
     RETURN_IF_EXCEPTION(scope, void());
 
@@ -280,9 +291,9 @@
 
     bool usesFallback;
     bool useGrouping = intlBooleanOption(globalObject, options, Identifier::fromString(vm, "useGrouping"), usesFallback);
+    RETURN_IF_EXCEPTION(scope, void());
     if (usesFallback)
         useGrouping = true;
-    RETURN_IF_EXCEPTION(scope, void());
     m_useGrouping = useGrouping;
 
     UNumberFormatStyle style = UNUM_DEFAULT;
@@ -337,19 +348,16 @@
     }
     unum_setAttribute(m_numberFormat.get(), UNUM_GROUPING_USED, m_useGrouping);
     unum_setAttribute(m_numberFormat.get(), UNUM_ROUNDING_MODE, UNUM_ROUND_HALFUP);
-
-    m_initializedNumberFormat = true;
 }
 
 // https://tc39.es/ecma402/#sec-formatnumber
 JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, double value)
 {
+    ASSERT(m_numberFormat);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!m_initializedNumberFormat)
-        return throwTypeError(globalObject, scope, "Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat"_s);
-
     UErrorCode status = U_ZERO_ERROR;
     Vector<UChar, 32> buffer(32);
     auto length = unum_formatDouble(m_numberFormat.get(), value, buffer.data(), buffer.size(), nullptr, &status);
@@ -364,14 +372,14 @@
     return jsString(vm, String(buffer.data(), length));
 }
 
+// https://tc39.es/ecma402/#sec-formatnumber
 JSValue IntlNumberFormat::format(JSGlobalObject* globalObject, JSBigInt* value)
 {
+    ASSERT(m_numberFormat);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!m_initializedNumberFormat)
-        return throwTypeError(globalObject, scope, "Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat"_s);
-
     auto string = value->toString(globalObject, 10);
     RETURN_IF_EXCEPTION(scope, { });
 
@@ -420,25 +428,10 @@
     return ASCIILiteral::null();
 }
 
+// https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
 JSObject* IntlNumberFormat::resolvedOptions(JSGlobalObject* globalObject)
 {
     VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    // 11.3.5 Intl.NumberFormat.prototype.resolvedOptions() (ECMA-402 2.0)
-    // The function returns a new object whose properties and attributes are set as if
-    // constructed by an object literal assigning to each of the following properties the
-    // value of the corresponding internal slot of this NumberFormat object (see 11.4):
-    // locale, numberingSystem, style, currency, currencyDisplay, minimumIntegerDigits,
-    // minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits,
-    // maximumSignificantDigits, and useGrouping. Properties whose corresponding internal
-    // slots are not present are not assigned.
-
-    if (!m_initializedNumberFormat) {
-        initializeNumberFormat(globalObject, jsUndefined(), jsUndefined());
-        scope.assertNoException();
-    }
-
     JSObject* options = constructEmptyObject(globalObject);
     options->putDirect(vm, vm.propertyNames->locale, jsString(vm, m_locale));
     options->putDirect(vm, vm.propertyNames->numberingSystem, jsString(vm, m_numberingSystem));
@@ -464,14 +457,8 @@
     m_boundFormat.set(vm, this, format);
 }
 
-void IntlNumberFormat::UFieldPositionIteratorDeleter::operator()(UFieldPositionIterator* iterator) const
+static ASCIILiteral partTypeString(UNumberFormatFields field, double value)
 {
-    if (iterator)
-        ufieldpositer_close(iterator);
-}
-
-ASCIILiteral IntlNumberFormat::partTypeString(UNumberFormatFields field, double value)
-{
     switch (field) {
     case UNUM_INTEGER_FIELD:
         if (std::isnan(value))
@@ -512,17 +499,17 @@
     auto stringLength = formatted.length();
 
     int32_t literalFieldType = -1;
-    auto literalField = IntlNumberFormatField(literalFieldType, stringLength);
+    IntlNumberFormatField literalField { literalFieldType, stringLength };
     Vector<IntlNumberFormatField, 32> fields(stringLength, literalField);
     int32_t beginIndex = 0;
     int32_t endIndex = 0;
     auto fieldType = ufieldpositer_next(iterator, &beginIndex, &endIndex);
     while (fieldType >= 0) {
-        auto size = endIndex - beginIndex;
+        size_t size = endIndex - beginIndex;
         for (auto i = beginIndex; i < endIndex; ++i) {
             // Only override previous value if new value is more specific.
             if (fields[i].size >= size)
-                fields[i] = IntlNumberFormatField(fieldType, size);
+                fields[i] = IntlNumberFormatField { fieldType, size };
         }
         fieldType = ufieldpositer_next(iterator, &beginIndex, &endIndex);
     }
@@ -550,18 +537,14 @@
     }
 }
 
+// https://tc39.github.io/ecma402/#sec-formatnumbertoparts
 JSValue IntlNumberFormat::formatToParts(JSGlobalObject* globalObject, double value)
 {
+    ASSERT(m_numberFormat);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // FormatNumberToParts (ECMA-402)
-    // https://tc39.github.io/ecma402/#sec-formatnumbertoparts
-    // https://tc39.github.io/ecma402/#sec-partitionnumberpattern
-
-    if (!m_initializedNumberFormat)
-        return throwTypeError(globalObject, scope, "Intl.NumberFormat.prototype.formatToParts called on value that's not an object initialized as a NumberFormat"_s);
-
     UErrorCode status = U_ZERO_ERROR;
     auto fieldItr = std::unique_ptr<UFieldPositionIterator, UFieldPositionIteratorDeleter>(ufieldpositer_open(&status));
     if (U_FAILURE(status))

Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.h (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.h	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.h	2020-04-21 04:04:10 UTC (rev 260411)
@@ -82,11 +82,12 @@
     static ASCIILiteral styleString(Style);
     static ASCIILiteral currencyDisplayString(CurrencyDisplay);
 
+    WriteBarrier<JSBoundFunction> m_boundFormat;
+    std::unique_ptr<UNumberFormat, UNumberFormatDeleter> m_numberFormat;
+
     String m_locale;
     String m_numberingSystem;
     String m_currency;
-    std::unique_ptr<UNumberFormat, UNumberFormatDeleter> m_numberFormat;
-    WriteBarrier<JSBoundFunction> m_boundFormat;
     unsigned m_minimumIntegerDigits { 1 };
     unsigned m_minimumFractionDigits { 0 };
     unsigned m_maximumFractionDigits { 3 };
@@ -95,22 +96,6 @@
     Style m_style { Style::Decimal };
     CurrencyDisplay m_currencyDisplay;
     bool m_useGrouping { true };
-    bool m_initializedNumberFormat { false };
-
-    struct UFieldPositionIteratorDeleter {
-        void operator()(UFieldPositionIterator*) const;
-    };
-
-    struct IntlNumberFormatField {
-        int32_t type;
-        int32_t size;
-        IntlNumberFormatField(int32_t type, int32_t size)
-            : type(type)
-            , size(size)
-        { }
-    };
-
-    static ASCIILiteral partTypeString(UNumberFormatFields, double);
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlPluralRules.cpp	2020-04-21 04:04:10 UTC (rev 260411)
@@ -88,21 +88,17 @@
     Base::visitChildren(thisObject, visitor);
 }
 
-namespace IntlPRInternal {
 static Vector<String> localeData(const String&, size_t)
 {
-    Vector<String> data;
-    return data;
+    return { };
 }
-}
 
+// https://tc39.github.io/ecma402/#sec-initializepluralrules
 void IntlPluralRules::initializePluralRules(JSGlobalObject* globalObject, JSValue locales, JSValue optionsValue)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 13.1.1 InitializePluralRules (pluralRules, locales, options)
-    // https://tc39.github.io/ecma402/#sec-initializepluralrules
     Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, locales);
     RETURN_IF_EXCEPTION(scope, void());
 
@@ -120,7 +116,7 @@
     localeOpt.add(vm.propertyNames->localeMatcher.string(), localeMatcher);
 
     const HashSet<String>& availableLocales = intlPluralRulesAvailableLocales();
-    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeOpt, nullptr, 0, IntlPRInternal::localeData);
+    HashMap<String, String> resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeOpt, nullptr, 0, localeData);
     m_locale = resolved.get(vm.propertyNames->locale.string());
     if (m_locale.isEmpty()) {
         throwTypeError(globalObject, scope, "failed to initialize PluralRules due to invalid locale"_s);
@@ -183,22 +179,16 @@
         throwTypeError(globalObject, scope, "failed to initialize PluralRules"_s);
         return;
     }
-
-    m_initializedPluralRules = true;
 }
 
+// https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
 JSObject* IntlPluralRules::resolvedOptions(JSGlobalObject* globalObject)
 {
+    ASSERT(m_pluralRules);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 13.4.4 Intl.PluralRules.prototype.resolvedOptions ()
-    // https://tc39.github.io/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
-    if (UNLIKELY(!m_initializedPluralRules)) {
-        throwTypeError(globalObject, scope, "Intl.PluralRules.prototype.resolvedOptions called on value that's not an object initialized as a PluralRules"_s);
-        return nullptr;
-    }
-
     JSObject* options = constructEmptyObject(globalObject);
     options->putDirect(vm, vm.propertyNames->locale, jsNontrivialString(vm, m_locale));
     options->putDirect(vm, vm.propertyNames->type, jsNontrivialString(vm, m_type == UPLURAL_TYPE_ORDINAL ? "ordinal"_s : "cardinal"_s));
@@ -233,16 +223,14 @@
     RELEASE_AND_RETURN(scope, options);
 }
 
+// https://tc39.es/ecma402/#sec-resolveplural
 JSValue IntlPluralRules::select(JSGlobalObject* globalObject, double value)
 {
+    ASSERT(m_pluralRules);
+
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // 13.1.4 ResolvePlural (pluralRules, n)
-    // https://tc39.github.io/ecma402/#sec-resolveplural
-    if (!m_initializedPluralRules)
-        return throwTypeError(globalObject, scope, "Intl.PluralRules.prototype.select called on value that's not an object initialized as a PluralRules"_s);
-
     if (!std::isfinite(value))
         return jsNontrivialString(vm, "other"_s);
 

Modified: trunk/Source/_javascript_Core/runtime/IntlPluralRules.h (260410 => 260411)


--- trunk/Source/_javascript_Core/runtime/IntlPluralRules.h	2020-04-21 03:23:53 UTC (rev 260410)
+++ trunk/Source/_javascript_Core/runtime/IntlPluralRules.h	2020-04-21 04:04:10 UTC (rev 260411)
@@ -70,7 +70,6 @@
         void operator()(UNumberFormat*) const;
     };
 
-    bool m_initializedPluralRules { false };
     std::unique_ptr<UPluralRules, UPluralRulesDeleter> m_pluralRules;
     std::unique_ptr<UNumberFormat, UNumberFormatDeleter> m_numberFormat;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to