WebKit Bugzilla
Attachment 340246 Details for
Bug 185578
: [INTL] Improve spec & test262 compliance for Intl APIs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185578-20180511232625.patch (text/plain), 55.52 KB, created by
Andy VanWagoner
on 2018-05-11 22:26:26 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Andy VanWagoner
Created:
2018-05-11 22:26:26 PDT
Size:
55.52 KB
patch
obsolete
>Subversion Revision: 231723 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 9455e15dff20834fa5b301dbfe730092b79b88c4..4f1781060b2ca63f13211ef7ef531cf5f574c23a 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,43 @@ >+2018-05-11 Andy VanWagoner <andy@vanwagoner.family> >+ >+ [INTL] Improve spec & test262 compliance for Intl APIs >+ https://bugs.webkit.org/show_bug.cgi?id=185578 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Use putDirectIndex over push for lists to arrays. >+ Update default options to construct with a null prototype. >+ Define constructor and toStringTag on prototypes. >+ Add proper time trimming. >+ Remove some outdated comment spec text, use url instead. >+ >+ * runtime/IntlCollator.cpp: >+ (JSC::IntlCollator::initializeCollator): >+ * runtime/IntlCollatorConstructor.cpp: >+ (JSC::IntlCollatorConstructor::finishCreation): >+ * runtime/IntlCollatorPrototype.cpp: >+ (JSC::IntlCollatorPrototype::finishCreation): >+ * runtime/IntlDateTimeFormatConstructor.cpp: >+ (JSC::IntlDateTimeFormatConstructor::finishCreation): >+ * runtime/IntlDateTimeFormatPrototype.cpp: >+ (JSC::IntlDateTimeFormatPrototype::finishCreation): >+ (JSC::IntlDateTimeFormatFuncFormatDateTime): >+ (JSC::IntlDateTimeFormatPrototypeFuncFormatToParts): >+ * runtime/IntlNumberFormat.cpp: >+ (JSC::IntlNumberFormat::initializeNumberFormat): >+ * runtime/IntlNumberFormatConstructor.cpp: >+ (JSC::IntlNumberFormatConstructor::finishCreation): >+ * runtime/IntlNumberFormatPrototype.cpp: >+ (JSC::IntlNumberFormatPrototype::finishCreation): >+ * runtime/IntlObject.cpp: >+ (JSC::lookupSupportedLocales): >+ (JSC::supportedLocales): >+ (JSC::intlObjectFuncGetCanonicalLocales): >+ * runtime/IntlPluralRules.cpp: >+ (JSC::IntlPluralRules::resolvedOptions): >+ * runtime/IntlPluralRulesConstructor.cpp: >+ (JSC::IntlPluralRulesConstructor::finishCreation): >+ > 2018-05-11 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r231316 and r231332. >diff --git a/Source/JavaScriptCore/runtime/IntlCollator.cpp b/Source/JavaScriptCore/runtime/IntlCollator.cpp >index 7208b2d6888aceb05c4959900bb910abe87a9fcb..f7350862fbf7bebecac38e2294499bdbabdf7124 100644 >--- a/Source/JavaScriptCore/runtime/IntlCollator.cpp >+++ b/Source/JavaScriptCore/runtime/IntlCollator.cpp >@@ -178,32 +178,22 @@ void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue > VM& vm = state.vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >- // 10.1.1 InitializeCollator (collator, locales, options) (ECMA-402 2.0) >- // 1. If collator has an [[initializedIntlObject]] internal slot with value true, throw a TypeError exception. >- // 2. Set collator.[[initializedIntlObject]] to true. >+ // 10.1.1 InitializeCollator (collator, locales, options) (ECMA-402) >+ // https://tc39.github.io/ecma402/#sec-initializecollator > >- // 3. Let requestedLocales be CanonicalizeLocaleList(locales). > auto requestedLocales = canonicalizeLocaleList(state, locales); >- // 4. ReturnIfAbrupt(requestedLocales). > RETURN_IF_EXCEPTION(scope, void()); > >- // 5. If options is undefined, then > JSObject* options; >- if (optionsValue.isUndefined()) { >- // a. Let options be ObjectCreate(%ObjectPrototype%). >- options = constructEmptyObject(&state); >- } else { // 6. Else >- // a. Let options be ToObject(options). >+ if (optionsValue.isUndefined()) >+ options = constructEmptyObject(&state, state.lexicalGlobalObject()->nullPrototypeObjectStructure()); >+ else { > options = optionsValue.toObject(&state); >- // b. ReturnIfAbrupt(options). > RETURN_IF_EXCEPTION(scope, void()); > } > >- // 7. Let u be GetOption(options, "usage", "string", «"sort", "search"», "sort"). > String usageString = intlStringOption(state, options, vm.propertyNames->usage, { "sort", "search" }, "usage must be either \"sort\" or \"search\"", "sort"); >- // 8. ReturnIfAbrupt(u). > RETURN_IF_EXCEPTION(scope, void()); >- // 9. Set collator.[[usage]] to u. > if (usageString == "sort") > m_usage = Usage::Sort; > else if (usageString == "search") >@@ -211,37 +201,14 @@ void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue > else > ASSERT_NOT_REACHED(); > >- // 10. If u is "sort", then >- // a. Let localeData be the value of %Collator%.[[sortLocaleData]]; >- // 11. Else >- // a. Let localeData be the value of %Collator%.[[searchLocaleData]]. >- Vector<String> (*localeData)(const String&, size_t); >- if (m_usage == Usage::Sort) >- localeData = sortLocaleData; >- else >- localeData = searchLocaleData; >+ auto localeData = (m_usage == Usage::Sort) ? sortLocaleData : searchLocaleData; > >- // 12. Let opt be a new Record. > HashMap<String, String> opt; > >- // 13. Let matcher be GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit"). > String matcher = intlStringOption(state, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit"); >- // 14. ReturnIfAbrupt(matcher). > RETURN_IF_EXCEPTION(scope, void()); >- // 15. Set opt.[[localeMatcher]] to matcher. > opt.add(ASCIILiteral("localeMatcher"), matcher); > >- // 16. For each row in Table 1, except the header row, do: >- // a. Let key be the name given in the Key column of the row. >- // b. Let prop be the name given in the Property column of the row. >- // c. Let type be the string given in the Type column of the row. >- // d. Let list be a List containing the Strings given in the Values column of the row, or undefined if no strings are given. >- // e. Let value be GetOption(options, prop, type, list, undefined). >- // f. ReturnIfAbrupt(value). >- // g. If the string given in the Type column of the row is "boolean" and value is not undefined, then >- // i. Let value be ToString(value). >- // ii. ReturnIfAbrupt(value). >- // h. Set opt.[[<key>]] to value. > { > String numericString; > bool usesFallback; >@@ -257,35 +224,15 @@ void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue > opt.add(ASCIILiteral("kf"), caseFirst); > } > >- // 17. Let relevantExtensionKeys be the value of %Collator%.[[relevantExtensionKeys]]. >- // 18. Let r be ResolveLocale(%Collator%.[[availableLocales]], requestedLocales, opt, relevantExtensionKeys, localeData). > auto& availableLocales = state.jsCallee()->globalObject()->intlCollatorAvailableLocales(); > auto result = resolveLocale(state, availableLocales, requestedLocales, opt, relevantCollatorExtensionKeys, WTF_ARRAY_LENGTH(relevantCollatorExtensionKeys), localeData); > >- // 19. Set collator.[[locale]] to the value of r.[[locale]]. > m_locale = result.get(ASCIILiteral("locale")); > if (m_locale.isEmpty()) { > throwTypeError(&state, scope, ASCIILiteral("failed to initialize Collator due to invalid locale")); > return; > } > >- // 20. Let k be 0. >- // 21. Let lenValue be Get(relevantExtensionKeys, "length"). >- // 22. Let len be ToLength(lenValue). >- // 23. Repeat while k < len: >- // a. Let Pk be ToString(k). >- // b. Let key be Get(relevantExtensionKeys, Pk). >- // c. ReturnIfAbrupt(key). >- // d. If key is "co", then >- // i. Let property be "collation". >- // ii. Let value be the value of r.[[co]]. >- // iii. If value is null, let value be "default". >- // e. Else use the row of Table 1 that contains the value of key in the Key column: >- // i. Let property be the name given in the Property column of the row. >- // ii. Let value be the value of r.[[<key>]]. >- // iii. If the name given in the Type column of the row is "boolean", let value be the result of comparing value with "true". >- // f. Set collator.[[<property>]] to value. >- // g. Increase k by 1. > const String& collation = result.get(ASCIILiteral("co")); > m_collation = collation.isNull() ? ASCIILiteral("default") : collation; > m_numeric = result.get(ASCIILiteral("kn")) == "true"; >@@ -298,18 +245,8 @@ void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue > else > m_caseFirst = CaseFirst::False; > >- // 24. Let s be GetOption(options, "sensitivity", "string", «"base", "accent", "case", "variant"», undefined). > String sensitivityString = intlStringOption(state, options, vm.propertyNames->sensitivity, { "base", "accent", "case", "variant" }, "sensitivity must be either \"base\", \"accent\", \"case\", or \"variant\"", nullptr); >- // 25. ReturnIfAbrupt(s). > RETURN_IF_EXCEPTION(scope, void()); >- // 26. If s is undefined, then >- // a. If u is "sort", then let s be "variant". >- // b. Else >- // i. Let dataLocale be the value of r.[[dataLocale]]. >- // ii. Let dataLocaleData be Get(localeData, dataLocale). >- // iii. Let s be Get(dataLocaleData, "sensitivity"). >- // 10.2.3 "[[searchLocaleData]][locale] must have a sensitivity property with a String value equal to "base", "accent", "case", or "variant" for all locale values." >- // 27. Set collator.[[sensitivity]] to s. > if (sensitivityString == "base") > m_sensitivity = Sensitivity::Base; > else if (sensitivityString == "accent") >@@ -319,21 +256,14 @@ void IntlCollator::initializeCollator(ExecState& state, JSValue locales, JSValue > else > m_sensitivity = Sensitivity::Variant; > >- // 28. Let ip be GetOption(options, "ignorePunctuation", "boolean", undefined, false). > bool usesFallback; > bool ignorePunctuation = intlBooleanOption(state, options, vm.propertyNames->ignorePunctuation, usesFallback); > if (usesFallback) > ignorePunctuation = false; >- // 29. ReturnIfAbrupt(ip). > RETURN_IF_EXCEPTION(scope, void()); >- // 30. Set collator.[[ignorePunctuation]] to ip. > m_ignorePunctuation = ignorePunctuation; > >- // 31. Set collator.[[boundCompare]] to undefined. >- // 32. Set collator.[[initializedCollator]] to true. > m_initializedCollator = true; >- >- // 33. Return collator. > } > > void IntlCollator::createCollator(ExecState& state) >diff --git a/Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp b/Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp >index 78f189f98b49d9a2fe51ce27b2255951dd09460f..86ae3f0908fca8eac0862e4c71b9ba040a93e31d 100644 >--- a/Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp >+++ b/Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp >@@ -82,6 +82,7 @@ void IntlCollatorConstructor::finishCreation(VM& vm, IntlCollatorPrototype* coll > Base::finishCreation(vm, ASCIILiteral("Collator")); > putDirectWithoutTransition(vm, vm.propertyNames->prototype, collatorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); > putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete); >+ collatorPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum)); > m_collatorStructure.set(vm, this, collatorStructure); > } > >diff --git a/Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp b/Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp >index ad59c8e4f20baa129c70a494185c6f4f55383e7b..bf47529d8a8b7ca3be49d03bb222ae56c2dcee63 100644 >--- a/Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp >@@ -74,6 +74,8 @@ IntlCollatorPrototype::IntlCollatorPrototype(VM& vm, Structure* structure) > void IntlCollatorPrototype::finishCreation(VM& vm) > { > Base::finishCreation(vm); >+ >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > static EncodedJSValue JSC_HOST_CALL IntlCollatorFuncCompare(ExecState* state) >diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp >index 2919ece15c511e09781b1d1062f0385bd6e1f818..5351e43dcdadde2b5cfac5d29f7c6627405cf2c1 100644 >--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp >+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp >@@ -82,6 +82,7 @@ void IntlDateTimeFormatConstructor::finishCreation(VM& vm, IntlDateTimeFormatPro > Base::finishCreation(vm, ASCIILiteral("DateTimeFormat")); > putDirectWithoutTransition(vm, vm.propertyNames->prototype, dateTimeFormatPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); > putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete); >+ dateTimeFormatPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum)); > m_dateTimeFormatStructure.set(vm, this, dateTimeFormatStructure); > } > >diff --git a/Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp b/Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp >index 4724b2be192b02852f883483e2d349be96752101..7565676d1b005f0dfce042b2f686648e8a55f892 100644 >--- a/Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp >@@ -87,33 +87,35 @@ void IntlDateTimeFormatPrototype::finishCreation(VM& vm, JSGlobalObject* globalO > #else > UNUSED_PARAM(globalObject); > #endif >+ >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > >+static const double maxECMAScriptTime = 8.64E15; >+ > static EncodedJSValue JSC_HOST_CALL IntlDateTimeFormatFuncFormatDateTime(ExecState* state) > { > VM& vm = state->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- // 12.3.4 DateTime Format Functions (ECMA-402 2.0) >- // 1. Let dtf be the this value. >- // 2. Assert: Type(dtf) is Object and dtf has an [[initializedDateTimeFormat]] internal slot whose value is true. >+ // 12.1.7 DateTime Format Functions (ECMA-402) >+ // https://tc39.github.io/ecma402/#sec-formatdatetime >+ > IntlDateTimeFormat* format = jsCast<IntlDateTimeFormat*>(state->thisValue()); > > JSValue date = state->argument(0); > double value; > >- // 3. If date is not provided or is undefined, then >- if (date.isUndefined()) { >- // a. Let x be %Date_now%(). >+ if (date.isUndefined()) > value = JSValue::decode(dateNow(state)).toNumber(state); >- } else { >- // 4. Else >- // a. Let x be ToNumber(date). >+ else { > value = date.toNumber(state); >- // b. ReturnIfAbrupt(x). >+ if (!std::isfinite(value) || abs(value) > maxECMAScriptTime) >+ value = PNaN; >+ else >+ value = trunc(value); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > } > >- // 5. Return FormatDateTime(dtf, x). > scope.release(); > return JSValue::encode(format->format(*state, value)); > } >@@ -176,6 +178,10 @@ EncodedJSValue JSC_HOST_CALL IntlDateTimeFormatPrototypeFuncFormatToParts(ExecSt > value = JSValue::decode(dateNow(state)).toNumber(state); > else { > value = date.toNumber(state); >+ if (!std::isfinite(value) || abs(value) > maxECMAScriptTime) >+ value = PNaN; >+ else >+ value = trunc(value); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > } > >diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp >index 185ac368d17330fffa587c6612dfbdd219ffcba0..b18fd0ff26631ede344bcaed21d4fea1e37b7127 100644 >--- a/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp >+++ b/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp >@@ -157,62 +157,42 @@ static unsigned computeCurrencyDigits(const String& currency) > > void IntlNumberFormat::initializeNumberFormat(ExecState& state, JSValue locales, JSValue optionsValue) > { >- // 11.1.1 InitializeNumberFormat (numberFormat, locales, options) (ECMA-402 2.0) > VM& vm = state.vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >- // 1. If numberFormat has an [[initializedIntlObject]] internal slot with value true, throw a TypeError exception. >- // 2. Set numberFormat.[[initializedIntlObject]] to true. >+ // 11.1.2 InitializeNumberFormat (numberFormat, locales, options) (ECMA-402) >+ // https://tc39.github.io/ecma402/#sec-initializenumberformat > >- // 3. Let requestedLocales be CanonicalizeLocaleList(locales). > auto requestedLocales = canonicalizeLocaleList(state, locales); >- // 4. ReturnIfAbrupt(requestedLocales). > RETURN_IF_EXCEPTION(scope, void()); > >- // 5. If options is undefined, then > JSObject* options; >- if (optionsValue.isUndefined()) { >- // a. Let options be ObjectCreate(%ObjectPrototype%). >- options = constructEmptyObject(&state); >- } else { // 6. Else >- // a. Let options be ToObject(options). >+ if (optionsValue.isUndefined()) >+ options = constructEmptyObject(&state, state.lexicalGlobalObject()->nullPrototypeObjectStructure()); >+ else { > options = optionsValue.toObject(&state); >- // b. ReturnIfAbrupt(options). > RETURN_IF_EXCEPTION(scope, void()); > } > >- // 7. Let opt be a new Record. > HashMap<String, String> opt; > >- // 8. Let matcher be GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit"). > String matcher = intlStringOption(state, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit"); >- // 9. ReturnIfAbrupt(matcher). > RETURN_IF_EXCEPTION(scope, void()); >- // 10. Set opt.[[localeMatcher]] to matcher. > opt.add(ASCIILiteral("localeMatcher"), matcher); > >- // 11. Let localeData be %NumberFormat%.[[localeData]]. >- // 12. Let r be ResolveLocale(%NumberFormat%.[[availableLocales]], requestedLocales, opt, %NumberFormat%.[[relevantExtensionKeys]], localeData). > auto& availableLocales = state.jsCallee()->globalObject()->intlNumberFormatAvailableLocales(); > auto result = resolveLocale(state, availableLocales, requestedLocales, opt, relevantNumberExtensionKeys, WTF_ARRAY_LENGTH(relevantNumberExtensionKeys), IntlNFInternal::localeData); > >- // 13. Set numberFormat.[[locale]] to the value of r.[[locale]]. > m_locale = result.get(ASCIILiteral("locale")); > if (m_locale.isEmpty()) { > throwTypeError(&state, scope, ASCIILiteral("failed to initialize NumberFormat due to invalid locale")); > return; > } > >- // 14. Set numberFormat.[[numberingSystem]] to the value of r.[[nu]]. > m_numberingSystem = result.get(ASCIILiteral("nu")); > >- // 15. Let dataLocale be r.[[dataLocale]]. >- >- // 16. Let s be GetOption(options, "style", "string", « "decimal", "percent", "currency"», "decimal"). > String styleString = intlStringOption(state, options, Identifier::fromString(&vm, "style"), { "decimal", "percent", "currency" }, "style must be either \"decimal\", \"percent\", or \"currency\"", "decimal"); >- // 17. ReturnIfAbrupt(s). > RETURN_IF_EXCEPTION(scope, void()); >- // 18. Set numberFormat.[[style]] to s. > if (styleString == "decimal") > m_style = Style::Decimal; > else if (styleString == "percent") >@@ -222,13 +202,9 @@ void IntlNumberFormat::initializeNumberFormat(ExecState& state, JSValue locales, > else > ASSERT_NOT_REACHED(); > >- // 19. Let c be GetOption(options, "currency", "string", undefined, undefined). > String currency = intlStringOption(state, options, Identifier::fromString(&vm, "currency"), { }, nullptr, nullptr); >- // 20. ReturnIfAbrupt(c). > RETURN_IF_EXCEPTION(scope, void()); >- // 21. If c is not undefined, then > if (!currency.isNull()) { >- // a. If the result of IsWellFormedCurrencyCode(c), is false, then throw a RangeError exception. > if (currency.length() != 3 || !currency.isAllSpecialCharacters<isASCIIAlpha>()) { > throwException(&state, scope, createRangeError(&state, ASCIILiteral("currency is not a well-formed currency code"))); > return; >@@ -237,26 +213,18 @@ void IntlNumberFormat::initializeNumberFormat(ExecState& state, JSValue locales, > > unsigned currencyDigits = 0; > if (m_style == Style::Currency) { >- // 22. If s is "currency" and c is undefined, throw a TypeError exception. > if (currency.isNull()) { > throwTypeError(&state, scope, ASCIILiteral("currency must be a string")); > return; > } > >- // 23. If s is "currency", then >- // a. Let c be converting c to upper case as specified in 6.1. > currency = currency.convertToASCIIUppercase(); >- // b. Set numberFormat.[[currency]] to c. > m_currency = currency; >- // c. Let cDigits be CurrencyDigits(c) > currencyDigits = computeCurrencyDigits(currency); > } > >- // 24. Let cd be GetOption(options, "currencyDisplay", "string", «"code", "symbol", "name"», "symbol"). > String currencyDisplayString = intlStringOption(state, options, Identifier::fromString(&vm, "currencyDisplay"), { "code", "symbol", "name" }, "currencyDisplay must be either \"code\", \"symbol\", or \"name\"", "symbol"); >- // 25. ReturnIfAbrupt(cd). > RETURN_IF_EXCEPTION(scope, void()); >- // 26. If s is "currency", set numberFormat.[[currencyDisplay]] to cd. > if (m_style == Style::Currency) { > if (currencyDisplayString == "code") > m_currencyDisplay = CurrencyDisplay::Code; >@@ -268,88 +236,51 @@ void IntlNumberFormat::initializeNumberFormat(ExecState& state, JSValue locales, > ASSERT_NOT_REACHED(); > } > >- // 27. Let mnid be GetNumberOption(options, "minimumIntegerDigits", 1, 21, 1). >- // 28. ReturnIfAbrupt(mnid). >- // 29. Set numberFormat.[[minimumIntegerDigits]] to mnid. > unsigned minimumIntegerDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "minimumIntegerDigits"), 1, 21, 1); > RETURN_IF_EXCEPTION(scope, void()); > m_minimumIntegerDigits = minimumIntegerDigits; > >- // 30. If s is "currency", let mnfdDefault be cDigits; else let mnfdDefault be 0. > unsigned minimumFractionDigitsDefault = (m_style == Style::Currency) ? currencyDigits : 0; > >- // 31. Let mnfd be GetNumberOption(options, "minimumFractionDigits", 0, 20, mnfdDefault). >- // 32. ReturnIfAbrupt(mnfd). >- // 33. Set numberFormat.[[minimumFractionDigits]] to mnfd. > unsigned minimumFractionDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "minimumFractionDigits"), 0, 20, minimumFractionDigitsDefault); > RETURN_IF_EXCEPTION(scope, void()); > m_minimumFractionDigits = minimumFractionDigits; > >- // 34. If s is "currency", let mxfdDefault be max(mnfd, cDigits); > unsigned maximumFractionDigitsDefault; > if (m_style == Style::Currency) > maximumFractionDigitsDefault = std::max(minimumFractionDigits, currencyDigits); >- else if (m_style == Style::Percent) // else if s is "percent", let mxfdDefault be max(mnfd, 0); >+ else if (m_style == Style::Percent) > maximumFractionDigitsDefault = minimumFractionDigits; >- else // else let mxfdDefault be max(mnfd, 3). >+ else > maximumFractionDigitsDefault = std::max(minimumFractionDigits, 3u); > >- // 35. Let mxfd be GetNumberOption(options, "maximumFractionDigits", mnfd, 20, mxfdDefault). >- // 36. ReturnIfAbrupt(mxfd). >- // 37. Set numberFormat.[[maximumFractionDigits]] to mxfd. > unsigned maximumFractionDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "maximumFractionDigits"), minimumFractionDigits, 20, maximumFractionDigitsDefault); > RETURN_IF_EXCEPTION(scope, void()); > m_maximumFractionDigits = maximumFractionDigits; > >- // 38. Let mnsd be Get(options, "minimumSignificantDigits"). > JSValue minimumSignificantDigitsValue = options->get(&state, Identifier::fromString(&vm, "minimumSignificantDigits")); >- // 39. ReturnIfAbrupt(mnsd). > RETURN_IF_EXCEPTION(scope, void()); > >- // 40. Let mxsd be Get(options, "maximumSignificantDigits"). > JSValue maximumSignificantDigitsValue = options->get(&state, Identifier::fromString(&vm, "maximumSignificantDigits")); >- // 41. ReturnIfAbrupt(mxsd). > RETURN_IF_EXCEPTION(scope, void()); > >- // 42. If mnsd is not undefined or mxsd is not undefined, then > if (!minimumSignificantDigitsValue.isUndefined() || !maximumSignificantDigitsValue.isUndefined()) { >- // a. Let mnsd be GetNumberOption(options, "minimumSignificantDigits", 1, 21, 1). > unsigned minimumSignificantDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "minimumSignificantDigits"), 1, 21, 1); >- // b. ReturnIfAbrupt(mnsd). > RETURN_IF_EXCEPTION(scope, void()); >- // c. Let mxsd be GetNumberOption(options, "maximumSignificantDigits", mnsd, 21, 21). > unsigned maximumSignificantDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "maximumSignificantDigits"), minimumSignificantDigits, 21, 21); >- // d. ReturnIfAbrupt(mxsd). > RETURN_IF_EXCEPTION(scope, void()); >- // e. Set numberFormat.[[minimumSignificantDigits]] to mnsd. > m_minimumSignificantDigits = minimumSignificantDigits; >- // f. Set numberFormat.[[maximumSignificantDigits]] to mxsd. > m_maximumSignificantDigits = maximumSignificantDigits; > } > >- // 43. Let g be GetOption(options, "useGrouping", "boolean", undefined, true). > bool usesFallback; > bool useGrouping = intlBooleanOption(state, options, Identifier::fromString(&vm, "useGrouping"), usesFallback); > if (usesFallback) > useGrouping = true; >- // 44. ReturnIfAbrupt(g). > RETURN_IF_EXCEPTION(scope, void()); >- // 45. Set numberFormat.[[useGrouping]] to g. > m_useGrouping = useGrouping; > >- // Steps 46 - 51 are not necessary to our implementation. >- // 46. Let dataLocaleData be Get(localeData, dataLocale). >- // 47. Let patterns be Get(dataLocaleData, "patterns"). >- // 48. Assert: patterns is an object (see 11.2.3). >- // 49. Let stylePatterns be Get(patterns, s). >- // 50. Set numberFormat.[[positivePattern]] to Get(stylePatterns, "positivePattern"). >- // 51. Set numberFormat.[[negativePattern]] to Get(stylePatterns, "negativePattern"). >- >- // 52. Set numberFormat.[[boundFormat]] to undefined. >- // 53. Set numberFormat.[[initializedNumberFormat]] to true. > m_initializedNumberFormat = true; >- >- // 54. Return numberFormat. > } > > void IntlNumberFormat::createNumberFormat(ExecState& state) >diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp >index 2b30503be36493dda8e7a70a12418dee4ad78d8b..274703c25b8584f9118171763fd5f68ef606ecca 100644 >--- a/Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp >+++ b/Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp >@@ -82,6 +82,7 @@ void IntlNumberFormatConstructor::finishCreation(VM& vm, IntlNumberFormatPrototy > Base::finishCreation(vm, ASCIILiteral("NumberFormat")); > putDirectWithoutTransition(vm, vm.propertyNames->prototype, numberFormatPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); > putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete); >+ numberFormatPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum)); > m_numberFormatStructure.set(vm, this, numberFormatStructure); > } > >diff --git a/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp b/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp >index 5cf177d647f850141d7c1b9373292a09089633b5..f8be6bca66f3d281897b44e14cf26cd2d1e61539 100644 >--- a/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp >@@ -76,6 +76,8 @@ IntlNumberFormatPrototype::IntlNumberFormatPrototype(VM& vm, Structure* structur > void IntlNumberFormatPrototype::finishCreation(VM& vm, Structure*) > { > Base::finishCreation(vm); >+ >+ putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Object"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } > > static EncodedJSValue JSC_HOST_CALL IntlNumberFormatFuncFormatNumber(ExecState* state) >diff --git a/Source/JavaScriptCore/runtime/IntlObject.cpp b/Source/JavaScriptCore/runtime/IntlObject.cpp >index 86f938a2be4e3fde121dc985423d1331103988b8..ac74d7a561cad0b935e5b7d076ab9fa5b4dea120 100644 >--- a/Source/JavaScriptCore/runtime/IntlObject.cpp >+++ b/Source/JavaScriptCore/runtime/IntlObject.cpp >@@ -799,12 +799,13 @@ static JSArray* lookupSupportedLocales(ExecState& state, const HashSet<String>& > return nullptr; > } > >+ unsigned index = 0; > for (size_t k = 0; k < len; ++k) { > const String& locale = requestedLocales[k]; > String noExtensionsLocale = removeUnicodeLocaleExtension(locale); > String availableLocale = bestAvailableLocale(availableLocales, noExtensionsLocale); > if (!availableLocale.isNull()) { >- subset->push(&state, jsString(&state, locale)); >+ subset->putDirectIndex(&state, index++, jsString(&state, locale)); > RETURN_IF_EXCEPTION(scope, nullptr); > } > } >@@ -854,6 +855,7 @@ JSValue supportedLocales(ExecState& state, const HashSet<String>& availableLocal > supportedLocales->defineOwnProperty(supportedLocales, &state, keys[i], desc, true); > RETURN_IF_EXCEPTION(scope, JSValue()); > } >+ supportedLocales->defineOwnProperty(supportedLocales, &state, vm.propertyNames->length, desc, true); > > return supportedLocales; > } >@@ -902,17 +904,17 @@ EncodedJSValue JSC_HOST_CALL intlObjectFuncGetCanonicalLocales(ExecState* state) > > Vector<String> localeList = canonicalizeLocaleList(*state, state->argument(0)); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ auto length = localeList.size(); > > JSGlobalObject* globalObject = state->jsCallee()->globalObject(); >- JSArray* localeArray = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous)); >+ JSArray* localeArray = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), length); > if (!localeArray) { > throwOutOfMemoryError(state, scope); > return encodedJSValue(); > } > >- auto length = localeList.size(); > for (size_t i = 0; i < length; ++i) { >- localeArray->push(state, jsString(state, localeList[i])); >+ localeArray->putDirectIndex(state, i, jsString(state, localeList[i])); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); > } > return JSValue::encode(localeArray); >diff --git a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp >index 7b838f6812e00d89a7edd4379072fc68edf9fc68..01650b74dbef1102067dc6999374e819e3271c5d 100644 >--- a/Source/JavaScriptCore/runtime/IntlPluralRules.cpp >+++ b/Source/JavaScriptCore/runtime/IntlPluralRules.cpp >@@ -219,6 +219,7 @@ JSObject* IntlPluralRules::resolvedOptions(ExecState& exec) > JSArray* categories = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0); > if (!categories) > return throwOutOfMemoryError(&exec, scope); >+ unsigned index = 0; > > UErrorCode status = U_ZERO_ERROR; > auto keywords = std::unique_ptr<UEnumeration, UEnumerationDeleter>(uplrules_getKeywords(m_pluralRules.get(), &status)); >@@ -228,7 +229,7 @@ JSObject* IntlPluralRules::resolvedOptions(ExecState& exec) > // Category names are always ASCII, so use char[]. > while (const char* result = uenum_next(keywords.get(), &resultLength, &status)) { > ASSERT(U_SUCCESS(status)); >- categories->push(&exec, jsNontrivialString(&exec, String(result, resultLength))); >+ categories->putDirectIndex(&exec, index++, jsNontrivialString(&exec, String(result, resultLength))); > RETURN_IF_EXCEPTION(scope, { }); > } > options->putDirect(vm, Identifier::fromString(&vm, "pluralCategories"), categories); >diff --git a/Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.cpp b/Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.cpp >index 4a9e76971e03f81fac8ccd6c0f66db5190ffc12d..9e50a9badcc71c03ec0d0ea017b7db3443b6bad4 100644 >--- a/Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.cpp >+++ b/Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.cpp >@@ -80,7 +80,7 @@ void IntlPluralRulesConstructor::finishCreation(VM& vm, IntlPluralRulesPrototype > Base::finishCreation(vm, ASCIILiteral("PluralRules")); > putDirectWithoutTransition(vm, vm.propertyNames->prototype, pluralRulesPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); > putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete); >- pluralRulesPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete); >+ pluralRulesPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum)); > m_pluralRulesStructure.set(vm, this, pluralRulesStructure); > } > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 749bac8317659afcc4fc39fae2716d27ead3e629..b65c8351db64c85c6ab0808a65c10d17f5a8c9db 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2018-05-11 Andy VanWagoner <andy@vanwagoner.family> >+ >+ [INTL] Improve spec & test262 compliance for Intl APIs >+ https://bugs.webkit.org/show_bug.cgi?id=185578 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update Intl tests for prototype changes. >+ >+ * js/intl-collator-expected.txt: >+ * js/intl-datetimeformat-expected.txt: >+ * js/intl-numberformat-expected.txt: >+ * js/script-tests/intl-collator.js: >+ * js/script-tests/intl-datetimeformat.js: >+ * js/script-tests/intl-numberformat.js: >+ > 2018-05-11 Nan Wang <n_wang@apple.com> > > AX: In role=dialog elements with aria-modal=true VoiceOver iOS/macOS can't manually focus or read dialog paragraph description text inside the modal. >diff --git a/LayoutTests/js/intl-collator-expected.txt b/LayoutTests/js/intl-collator-expected.txt >index 63743526aefba48479b11c1111ac451d82dbe949..c483dad120a7d3f18a4ebbaaefec586a42c60d15 100644 >--- a/LayoutTests/js/intl-collator-expected.txt >+++ b/LayoutTests/js/intl-collator-expected.txt >@@ -130,9 +130,13 @@ PASS Intl.Collator.supportedLocalesOf('x-12345-12345-en-US') did not throw excep > PASS Intl.Collator.supportedLocalesOf('x-en-US-12345-12345') did not throw exception. > PASS Intl.Collator.supportedLocalesOf('x-en-u-foo') did not throw exception. > PASS Intl.Collator.supportedLocalesOf('x-en-u-foo-u-bar') did not throw exception. >-PASS Intl.Collator.prototype.constructor is Object > PASS Object.getPrototypeOf(Intl.Collator.prototype) is Object.prototype >+PASS Intl.Collator.prototype.constructor is Intl.Collator >+PASS Intl.Collator.prototype[Symbol.toStringTag] is 'Object' > PASS Object.prototype.toString.call(Intl.Collator.prototype) is '[object Object]' >+PASS Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).writable is false >+PASS Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).enumerable is false >+PASS Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).configurable is true > PASS defaultCollator.compare is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.Collator.prototype, 'compare').get is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.Collator.prototype, 'compare').set is undefined >diff --git a/LayoutTests/js/intl-datetimeformat-expected.txt b/LayoutTests/js/intl-datetimeformat-expected.txt >index 9afa11d28fc7ce8153c1a6a4f5bd0bc87de0d164..7c857cce8f3a9fd4f0676e7925afe598f700d9aa 100644 >--- a/LayoutTests/js/intl-datetimeformat-expected.txt >+++ b/LayoutTests/js/intl-datetimeformat-expected.txt >@@ -62,9 +62,13 @@ PASS Intl.DateTimeFormat.supportedLocalesOf('x-12345-12345-en-US') did not throw > PASS Intl.DateTimeFormat.supportedLocalesOf('x-en-US-12345-12345') did not throw exception. > PASS Intl.DateTimeFormat.supportedLocalesOf('x-en-u-foo') did not throw exception. > PASS Intl.DateTimeFormat.supportedLocalesOf('x-en-u-foo-u-bar') did not throw exception. >-PASS Intl.DateTimeFormat.prototype.constructor is Object > PASS Object.getPrototypeOf(Intl.DateTimeFormat.prototype) is Object.prototype >+PASS Intl.DateTimeFormat.prototype.constructor is Intl.DateTimeFormat >+PASS Intl.DateTimeFormat.prototype[Symbol.toStringTag] is 'Object' > PASS Object.prototype.toString.call(Intl.DateTimeFormat.prototype) is '[object Object]' >+PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).writable is false >+PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).enumerable is false >+PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).configurable is true > PASS defaultDTFormat.format is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').get is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').set is undefined >diff --git a/LayoutTests/js/intl-numberformat-expected.txt b/LayoutTests/js/intl-numberformat-expected.txt >index ca3587d41a7389c339795360fa7c3a7045c67364..54460e83646f0032d578c4fb7ea37776d8d3f62f 100644 >--- a/LayoutTests/js/intl-numberformat-expected.txt >+++ b/LayoutTests/js/intl-numberformat-expected.txt >@@ -130,9 +130,13 @@ PASS Intl.NumberFormat.supportedLocalesOf('x-12345-12345-en-US') did not throw e > PASS Intl.NumberFormat.supportedLocalesOf('x-en-US-12345-12345') did not throw exception. > PASS Intl.NumberFormat.supportedLocalesOf('x-en-u-foo') did not throw exception. > PASS Intl.NumberFormat.supportedLocalesOf('x-en-u-foo-u-bar') did not throw exception. >-PASS Intl.NumberFormat.prototype.constructor is Object > PASS Object.getPrototypeOf(Intl.NumberFormat.prototype) is Object.prototype >+PASS Intl.NumberFormat.prototype.constructor is Intl.NumberFormat >+PASS Intl.NumberFormat.prototype[Symbol.toStringTag] is 'Object' > PASS Object.prototype.toString.call(Intl.NumberFormat.prototype) is '[object Object]' >+PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).writable is false >+PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).enumerable is false >+PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).configurable is true > PASS defaultNFormat.format is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, 'format').get is an instance of Function > PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, 'format').set is undefined >diff --git a/LayoutTests/js/script-tests/intl-collator.js b/LayoutTests/js/script-tests/intl-collator.js >index 3782b2ef83ad503e46aeccf6684f6c89de8a955e..cb3ccf36a6ccff5744fc4468e6f9a5caa7cd40a0 100644 >--- a/LayoutTests/js/script-tests/intl-collator.js >+++ b/LayoutTests/js/script-tests/intl-collator.js >@@ -215,10 +215,21 @@ for (var validLanguageTag of validLanguageTags) { > > // 10.3 Properties of the Intl.Collator Prototype Object > >-// is a plain object >-shouldBe("Intl.Collator.prototype.constructor", "Object"); >+// The Intl.Collator prototype object is itself an ordinary object. > shouldBe("Object.getPrototypeOf(Intl.Collator.prototype)", "Object.prototype"); >+ >+// 10.3.1 Intl.Collator.prototype.constructor >+// The initial value of Intl.Collator.prototype.constructor is the intrinsic object %Collator%. >+shouldBe("Intl.Collator.prototype.constructor", "Intl.Collator"); >+ >+// 10.3.2 Intl.Collator.prototype [ @@toStringTag ] >+// The initial value of the @@toStringTag property is the string value "Object". >+shouldBe("Intl.Collator.prototype[Symbol.toStringTag]", "'Object'"); > shouldBe("Object.prototype.toString.call(Intl.Collator.prototype)", "'[object Object]'"); >+// This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).writable"); >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).enumerable"); >+shouldBeTrue("Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag).configurable"); > > // 10.3.3 Intl.Collator.prototype.compare > >diff --git a/LayoutTests/js/script-tests/intl-datetimeformat.js b/LayoutTests/js/script-tests/intl-datetimeformat.js >index cbeec6cacfaad37980b283609655dc4205f10cb7..a006993ab71081ad413807a65b99cf53cbb2f141 100644 >--- a/LayoutTests/js/script-tests/intl-datetimeformat.js >+++ b/LayoutTests/js/script-tests/intl-datetimeformat.js >@@ -99,14 +99,25 @@ for (var validLanguageTag of validLanguageTags) { > shouldNotThrow("Intl.DateTimeFormat.supportedLocalesOf('" + validLanguageTag + "')"); > } > >-// 12.3 Properties of the Intl.DateTimeFormat Prototype Object >+// 12.4 Properties of the Intl.DateTimeFormat Prototype Object > >-// is a plain object >-shouldBe("Intl.DateTimeFormat.prototype.constructor", "Object"); >+// The Intl.DateTimeFormat prototype object is itself an ordinary object. > shouldBe("Object.getPrototypeOf(Intl.DateTimeFormat.prototype)", "Object.prototype"); >+ >+// 12.4.1 Intl.DateTimeFormat.prototype.constructor >+// The initial value of Intl.DateTimeFormat.prototype.constructor is the intrinsic object %DateTimeFormat%. >+shouldBe("Intl.DateTimeFormat.prototype.constructor", "Intl.DateTimeFormat"); >+ >+// 12.4.2 Intl.DateTimeFormat.prototype [ @@toStringTag ] >+// The initial value of the @@toStringTag property is the string value "Object". >+shouldBe("Intl.DateTimeFormat.prototype[Symbol.toStringTag]", "'Object'"); > shouldBe("Object.prototype.toString.call(Intl.DateTimeFormat.prototype)", "'[object Object]'"); >+// This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).writable"); >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).enumerable"); >+shouldBeTrue("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, Symbol.toStringTag).configurable"); > >-// 12.3.3 Intl.DateTimeFormat.prototype.format >+// 12.4.3 Intl.DateTimeFormat.prototype.format > > // This named accessor property returns a function that formats a date according to the effective locale and the formatting options of this DateTimeFormat object. > var defaultDTFormat = Intl.DateTimeFormat(); >@@ -601,4 +612,3 @@ shouldBe(`JSON.stringify( > {"type":"literal","value":" "}, > {"type":"timeZoneName","value":"Pacific Standard Time"} > ])`) >- >diff --git a/LayoutTests/js/script-tests/intl-numberformat.js b/LayoutTests/js/script-tests/intl-numberformat.js >index dd15e732260db058637d64bfd903f45b37331a5d..aa2af9ff168e5073ec78923998fe6f7453202c97 100644 >--- a/LayoutTests/js/script-tests/intl-numberformat.js >+++ b/LayoutTests/js/script-tests/intl-numberformat.js >@@ -215,14 +215,25 @@ for (var validLanguageTag of validLanguageTags) { > shouldNotThrow("Intl.NumberFormat.supportedLocalesOf('" + validLanguageTag + "')"); > } > >-// 11.3 Properties of the Intl.NumberFormat Prototype Object >+// 11.4 Properties of the Intl.NumberFormat Prototype Object > >-// is a plain object >-shouldBe("Intl.NumberFormat.prototype.constructor", "Object"); >+// The Intl.NumberFormat prototype object is itself an ordinary object. > shouldBe("Object.getPrototypeOf(Intl.NumberFormat.prototype)", "Object.prototype"); >+ >+// 11.4.1 Intl.NumberFormat.prototype.constructor >+// The initial value of Intl.NumberFormat.prototype.constructor is the intrinsic object %NumberFormat%. >+shouldBe("Intl.NumberFormat.prototype.constructor", "Intl.NumberFormat"); >+ >+// 11.4.2 Intl.NumberFormat.prototype [ @@toStringTag ] >+// The initial value of the @@toStringTag property is the string value "Object". >+shouldBe("Intl.NumberFormat.prototype[Symbol.toStringTag]", "'Object'"); > shouldBe("Object.prototype.toString.call(Intl.NumberFormat.prototype)", "'[object Object]'"); >+// This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).writable"); >+shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).enumerable"); >+shouldBeTrue("Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype, Symbol.toStringTag).configurable"); > >-// 11.3.3 Intl.NumberFormat.prototype.format >+// 11.4.3 Intl.NumberFormat.prototype.format > > // This named accessor property returns a function that formats a number according to the effective locale and the formatting options of this NumberFormat object. > var defaultNFormat = Intl.NumberFormat(); >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 407ef6a2912bbde2bfb0ee8543e652093c858576..9fa2eca98f3b11484c4408722814f54074323f16 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-05-11 Andy VanWagoner <andy@vanwagoner.family> >+ >+ [INTL] Improve spec & test262 compliance for Intl APIs >+ https://bugs.webkit.org/show_bug.cgi?id=185578 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Remove intl402 failures that have been fixed. >+ >+ * test262/expectations.yaml: >+ > 2018-05-11 Michael Saboff <msaboff@apple.com> > > [DFG] Compiler uses incorrect output register for NumberIsInteger operation >diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml >index 997821996c7020a3b6cad911730ccb16db9e5a2e..ff3bd3862614a21aed5e9f7790a39ce8bf086ac6 100644 >--- a/JSTests/test262/expectations.yaml >+++ b/JSTests/test262/expectations.yaml >@@ -1853,54 +1853,27 @@ test/built-ins/parseInt/S15.1.2.2_A2_T10_U180E.js: > test/harness/assert-throws-early-referenceerror.js: > default: 'Test262Error: Function: 1 = 1; Expected a ReferenceError to be thrown but no exception was thrown at all' > strict mode: 'Test262Error: Function: 1 = 1; Expected a ReferenceError to be thrown but no exception was thrown at all' >-test/intl402/Collator/default-options-object-prototype.js: >- default: 'Test262Error: Expected SameValue(ëbaseû, ëvariantû) to be true' >- strict mode: 'Test262Error: Expected SameValue(ëbaseû, ëvariantû) to be true' > test/intl402/Collator/length.js: > default: 'Test262Error: Expected obj[length] to have configurable:true.' > strict mode: 'Test262Error: Expected obj[length] to have configurable:true.' > test/intl402/Collator/prototype/compare/compare-function-name.js: > default: 'Test262Error: Expected SameValue(ëtrueû, ëfalseû) to be true' > strict mode: 'Test262Error: Expected SameValue(ëtrueû, ëfalseû) to be true' >-test/intl402/Collator/prototype/constructor/prop-desc.js: >- default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >- strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >-test/intl402/Collator/prototype/constructor/value.js: >- default: 'Test262Error: Intl.Collator.prototype.constructor is not the same as Intl.Collator Expected SameValue(ëfunction Object() {' >- strict mode: 'Test262Error: Intl.Collator.prototype.constructor is not the same as Intl.Collator Expected SameValue(ëfunction Object() {' > test/intl402/Collator/unicode-ext-seq-in-private-tag.js: > default: 'Test262Error: Expected SameValue(ëphonebkû, ëdefaultû) to be true' > strict mode: 'Test262Error: Expected SameValue(ëphonebkû, ëdefaultû) to be true' > test/intl402/DateTimeFormat/length.js: > default: 'Test262Error: Expected obj[length] to have configurable:true.' > strict mode: 'Test262Error: Expected obj[length] to have configurable:true.' >-test/intl402/DateTimeFormat/prototype/constructor/prop-desc.js: >- default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >- strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >-test/intl402/DateTimeFormat/prototype/constructor/value.js: >- default: 'Test262Error: Intl.DateTimeFormat.prototype.constructor is not the same as Intl.DateTimeFormat Expected SameValue(ëfunction Object() {' >- strict mode: 'Test262Error: Intl.DateTimeFormat.prototype.constructor is not the same as Intl.DateTimeFormat Expected SameValue(ëfunction Object() {' > test/intl402/DateTimeFormat/prototype/format/format-function-name.js: > default: 'Test262Error: Expected SameValue(ëtrueû, ëfalseû) to be true' > strict mode: 'Test262Error: Expected SameValue(ëtrueû, ëfalseû) to be true' > test/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js: > default: "Test262Error: Internal error: Didn't find Gregorian calendar Expected SameValue(ëgregorianû, ëgregoryû) to be true" > strict mode: "Test262Error: Internal error: Didn't find Gregorian calendar Expected SameValue(ëgregorianû, ëgregoryû) to be true" >-test/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js: >- default: 'Test262Error: format(-0.9) Expected SameValue(ë8:59:59 PMû, ë9:00:00 PMû) to be true' >- strict mode: 'Test262Error: format(-0.9) Expected SameValue(ë8:59:59 PMû, ë9:00:00 PMû) to be true' > test/intl402/DateTimeFormat/prototype/formatToParts/length.js: > default: 'Test262Error: Expected SameValue(ë0û, ë1û) to be true' > strict mode: 'Test262Error: Expected SameValue(ë0û, ë1û) to be true' >-test/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js: >- default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >- strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all' >-test/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js: >- default: 'Test262Error: formatToParts(-0.9) Expected SameValue(ë8:59:59 PMû, ë9:00:00 PMû) to be true' >- strict mode: 'Test262Error: formatToParts(-0.9) Expected SameValue(ë8:59:59 PMû, ë9:00:00 PMû) to be true' > test/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js: > default: 'Test262Error: Invalid calendar: gregorian Expected SameValue(ë-1û, ë-1û) to be false' > strict mode: 'Test262Error: Invalid calendar: gregorian Expected SameValue(ë-1û, ë-1û) to be false' >@@ -1985,24 +1958,12 @@ test/intl402/Locale/prototype/prop-desc.js: > test/intl402/Locale/prototype/toStringTag.js: > default: "TypeError: undefined is not an object (evaluating 'Intl.Locale.prototype')" > strict mode: "TypeError: undefined is not an object (evaluating 'Intl.Locale.prototype')" >-test/intl402/Number/prototype/toLocaleString/default-options-object-prototype.js: >- default: 'Test262Error: Expected SameValue(ë1.2û, ë1.23û) to be true' >- strict mode: 'Test262Error: Expected SameValue(ë1.2û, ë1.23û) to be true' > test/intl402/Number/prototype/toLocaleString/returns-same-results-as-NumberFormat.js: > default: 'Error: Failed to format a number.' > strict mode: 'Error: Failed to format a number.' >-test/intl402/NumberFormat/default-options-object-prototype.js: >- default: 'Test262Error: Expected SameValue(ë1û, ë3û) to be true' >- strict mode: 'Test262Error: Expected SameValue(ë1û, ë3û) to be true' > test/intl402/NumberFormat/length.js: > default: 'Test262Error: Expected obj[length] to have configurable:true.' > strict mode: 'Test262Error: Expected obj[length] to have configurable:true.' >-test/intl402/NumberFormat/prototype/constructor/prop-desc.js: >- default: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >- strict mode: "TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(obj, name).enumerable')" >-test/intl402/NumberFormat/prototype/constructor/value.js: >- default: 'Test262Error: Intl.NumberFormat.prototype.constructor is not the same as Intl.NumberFormat Expected SameValue(ëfunction Object() {' >- strict mode: 'Test262Error: Intl.NumberFormat.prototype.constructor is not the same as Intl.NumberFormat Expected SameValue(ëfunction Object() {' > test/intl402/NumberFormat/prototype/format/bound-to-numberformat-instance.js: > default: 'Error: Failed to format a number.' > strict mode: 'Error: Failed to format a number.' >@@ -2042,12 +2003,6 @@ test/intl402/PluralRules/default-options-object-prototype.js: > test/intl402/PluralRules/length.js: > default: 'Test262Error: Expected obj[length] to have configurable:true.' > strict mode: 'Test262Error: Expected obj[length] to have configurable:true.' >-test/intl402/PluralRules/prototype/constructor/prop-desc.js: >- default: 'Test262Error: Expected obj[constructor] to have configurable:true.' >- strict mode: 'Test262Error: Expected obj[constructor] to have configurable:true.' >-test/intl402/String/prototype/localeCompare/default-options-object-prototype.js: >- default: 'Test262Error: Expected SameValue(ë0û, ë-1û) to be true' >- strict mode: 'Test262Error: Expected SameValue(ë0û, ë-1û) to be true' > test/intl402/TypedArray/prototype/toLocaleString/calls-toLocaleString-number-elements.js: > default: 'Test262Error: Expected SameValue(ë0û, Ã«à ¹Â.à ¹Âà ¹Âà ¹Âû) to be true (Testing with Float64Array.)' > strict mode: 'Test262Error: Expected SameValue(ë0û, Ã«à ¹Â.à ¹Âà ¹Âà ¹Âû) to be true (Testing with Float64Array.)' >@@ -2057,15 +2012,6 @@ test/intl402/fallback-locales-are-supported.js: > test/intl402/language-tags-canonicalized.js: > default: 'Test262Error: For de-DD got de-DD; expected de-DE. (Testing with Collator.)' > strict mode: 'Test262Error: For de-DD got de-DD; expected de-DE. (Testing with Collator.)' >-test/intl402/supportedLocalesOf-returned-array-elements-are-frozen.js: >- default: 'Test262Error: Property length of object returned by SupportedLocales is writable. Expected SameValue(ëtrueû, ëfalseû) to be true (Testing with Collator.)' >- strict mode: 'Test262Error: Property length of object returned by SupportedLocales is writable. Expected SameValue(ëtrueû, ëfalseû) to be true (Testing with Collator.)' >-test/intl402/supportedLocalesOf-taint-Array-2.js: >- default: 'Test262Error: Client code can adversely affect behavior: setter for 0. (Testing with Collator.)' >- strict mode: 'Test262Error: Client code can adversely affect behavior: setter for 0. (Testing with Collator.)' >-test/intl402/supportedLocalesOf-taint-Array.js: >- default: 'Test262Error: Client code can adversely affect behavior: setter for 0. (Testing with Collator.)' >- strict mode: 'Test262Error: Client code can adversely affect behavior: setter for 0. (Testing with Collator.)' > test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-arguments.js: > default: 'Test262Error: Expected obj[0] to have enumerable:false.' > test/language/arguments-object/mapped/nonconfigurable-nonenumerable-nonwritable-descriptors-set-by-param.js:
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 185578
:
340246
|
340250
|
340252