Backed out changeset 357a1c414efa (bug 1365650) for rooting hazard. r=backout

This commit is contained in:
Sebastian Hengst 2017-05-22 19:53:57 +02:00
Родитель a49e848328
Коммит a7aee158a9
4 изменённых файлов: 89 добавлений и 186 удалений

Просмотреть файл

@ -907,6 +907,7 @@ intl_availableLocales(JSContext* cx, CountAvailable countAvailable,
#if ENABLE_INTL_API
RootedAtom a(cx);
uint32_t count = countAvailable();
RootedValue t(cx, BooleanValue(true));
for (uint32_t i = 0; i < count; i++) {
const char* locale = getAvailable(i);
auto lang = DuplicateString(cx, locale);
@ -918,7 +919,7 @@ intl_availableLocales(JSContext* cx, CountAvailable countAvailable,
a = Atomize(cx, lang.get(), strlen(lang.get()));
if (!a)
return false;
if (!DefineProperty(cx, locales, a->asPropertyName(), TrueHandleValue, nullptr, nullptr,
if (!DefineProperty(cx, locales, a->asPropertyName(), t, nullptr, nullptr,
JSPROP_ENUMERATE))
{
return false;
@ -2673,25 +2674,6 @@ js::intl_DateTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp
return true;
}
static JSString*
DefaultCalendar(JSContext* cx, const JSAutoByteString& locale)
{
UErrorCode status = U_ZERO_ERROR;
UCalendar* cal = ucal_open(nullptr, 0, locale.ptr(), UCAL_DEFAULT, &status);
// This correctly handles nullptr |cal| when opening failed.
ScopedICUObject<UCalendar, ucal_close> closeCalendar(cal);
const char* calendar = ucal_getType(cal, &status);
if (U_FAILURE(status)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
return nullptr;
}
// ICU returns old-style keyword values; map them to BCP 47 equivalents
return JS_NewStringCopyZ(cx, uloc_toUnicodeLocaleType("ca", calendar));
}
struct CalendarAlias
{
const char* const calendar;
@ -2720,16 +2702,31 @@ js::intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp)
uint32_t index = 0;
// We need the default calendar for the locale as the first result.
RootedString jscalendar(cx, DefaultCalendar(cx, locale));
if (!jscalendar)
return false;
UErrorCode status = U_ZERO_ERROR;
RootedString jscalendar(cx);
{
UCalendar* cal = ucal_open(nullptr, 0, locale.ptr(), UCAL_DEFAULT, &status);
// This correctly handles nullptr |cal| when opening failed.
ScopedICUObject<UCalendar, ucal_close> closeCalendar(cal);
const char* calendar = ucal_getType(cal, &status);
if (U_FAILURE(status)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
return false;
}
// ICU returns old-style keyword values; map them to BCP 47 equivalents
jscalendar = JS_NewStringCopyZ(cx, uloc_toUnicodeLocaleType("ca", calendar));
if (!jscalendar)
return false;
}
RootedValue element(cx, StringValue(jscalendar));
if (!DefineElement(cx, calendars, index++, element))
return false;
// Now get the calendars that "would make a difference", i.e., not the default.
UErrorCode status = U_ZERO_ERROR;
UEnumeration* values = ucal_getKeywordValuesForLocale("ca", locale.ptr(), false, &status);
if (U_FAILURE(status)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
@ -2777,25 +2774,6 @@ js::intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp)
return true;
}
bool
js::intl_defaultCalendar(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 1);
MOZ_ASSERT(args[0].isString());
JSAutoByteString locale(cx, args[0].toString());
if (!locale)
return false;
JSString* calendar = DefaultCalendar(cx, locale);
if (!calendar)
return false;
args.rval().setString(calendar);
return true;
}
template<typename Char>
static constexpr Char
ToUpperASCII(Char c)

Просмотреть файл

@ -435,16 +435,6 @@ intl_DateTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp);
extern MOZ_MUST_USE bool
intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp);
/**
* Returns the calendar type identifier per Unicode Technical Standard 35,
* Unicode Locale Data Markup Language, for the default calendar for the given
* locale.
*
* Usage: calendar = intl_defaultCalendar(locale)
*/
extern MOZ_MUST_USE bool
intl_defaultCalendar(JSContext* cx, unsigned argc, Value* vp);
/**
* 6.4.1 IsValidTimeZoneName ( timeZone )
*

Просмотреть файл

@ -898,6 +898,7 @@ function BestAvailableLocaleIgnoringDefault(availableLocales, locale) {
return BestAvailableLocaleHelper(availableLocales, locale, false);
}
var noRelevantExtensionKeys = [];
/**
* Compares a BCP 47 language priority list against the set of locales in
@ -1057,17 +1058,26 @@ function ResolveLocale(availableLocales, requestedLocales, options, relevantExte
// Step 8.
var supportedExtension = "-u";
// In this implementation, localeData is a function, not an object.
var localeDataProvider = localeData();
// Steps 9-12.
for (var i = 0; i < relevantExtensionKeys.length; i++) {
var i = 0;
var len = relevantExtensionKeys.length;
var foundLocaleData;
if (len > 0) {
// In this implementation, localeData is a function, not an object.
// Step 12.b.
foundLocaleData = localeData(foundLocale);
}
while (i < len) {
// Step 12.a.
var key = relevantExtensionKeys[i];
// Steps 12.b-d (The locale data is only computed when needed).
var keyLocaleData = undefined;
var value = undefined;
// Step 12.c.
var keyLocaleData = foundLocaleData[key];
// Locale data provides default value.
// Step 12.d.
var value = keyLocaleData[0];
assert(typeof value === "string" || value === null, "unexpected locale data value");
// Locale tag may override.
@ -1086,9 +1096,6 @@ function ResolveLocale(availableLocales, requestedLocales, options, relevantExte
// Step 12.f.ii.
if (requestedValue !== undefined) {
// Steps 12.b-c.
keyLocaleData = callFunction(localeDataProvider[key], null, foundLocale);
// Step 12.f.ii.1.
if (requestedValue !== "") {
// Step 12.f.ii.1.a.
@ -1113,29 +1120,18 @@ function ResolveLocale(availableLocales, requestedLocales, options, relevantExte
var optionsValue = options[key];
// Step 12.g, 12.g.ii.
if (optionsValue !== undefined && optionsValue !== value) {
// Steps 12.b-c.
if (keyLocaleData === undefined)
keyLocaleData = callFunction(localeDataProvider[key], null, foundLocale);
if (callFunction(ArrayIndexOf, keyLocaleData, optionsValue) !== -1) {
value = optionsValue;
supportedExtensionAddition = "";
}
}
// Locale data provides default value.
if (value === undefined) {
// Steps 12.b-d.
value = keyLocaleData === undefined
? callFunction(localeDataProvider.default[key], null, foundLocale)
: keyLocaleData[0];
if (optionsValue !== undefined &&
optionsValue !== value &&
callFunction(ArrayIndexOf, keyLocaleData, optionsValue) !== -1)
{
value = optionsValue;
supportedExtensionAddition = "";
}
// Steps 12.h-j.
assert(typeof value === "string" || value === null, "unexpected locale data value");
result[key] = value;
supportedExtension += supportedExtensionAddition;
i++;
}
// Step 13.
@ -1558,11 +1554,15 @@ function resolveCollatorInternals(lazyCollatorData) {
// Steps 21-22.
var s = lazyCollatorData.rawSensitivity;
if (s === undefined) {
// In theory the default sensitivity for the "search" collator is
// locale dependent; in reality the CLDR/ICU default strength is
// always tertiary. Therefore use "variant" as the default value for
// both collation modes.
s = "variant";
if (collatorIsSorting) {
// Step 21.a.
s = "variant";
} else {
// Step 21.b.
var dataLocale = r.dataLocale;
var dataLocaleData = localeData(dataLocale);
s = dataLocaleData.sensitivity;
}
}
internalProps.sensitivity = s;
@ -1735,97 +1735,49 @@ var collatorInternalProperties = {
/**
* Returns the actual locale used when a collator for |locale| is constructed.
* Returns the default caseFirst values for the given locale and usage. The
* first element in the returned array denotes the default value per ES2017
* Intl, 9.1 Internal slots of Service Constructors.
*/
function collatorActualLocale(locale) {
function collatorCaseFirst(locale, usage) {
assert(typeof locale === "string", "locale should be string");
assert(usage === "sort" || usage === "search", "invalid usage option");
// If |locale| is the default locale (e.g. da-DK), but only supported
// through a fallback (da), we need to get the actual locale before we
// can call intl_isUpperCaseFirst. Also see BestAvailableLocaleHelper.
var availableLocales = callFunction(collatorInternalProperties.availableLocales,
collatorInternalProperties);
return BestAvailableLocaleIgnoringDefault(availableLocales, locale);
}
if (usage === "sort") {
// If |locale| is the default locale (e.g. da-DK), but only supported
// through a fallback (da), we need to get the actual locale before we
// can call intl_isUpperCaseFirst. Also see BestAvailableLocaleHelper.
var availableLocales = callFunction(collatorInternalProperties.availableLocales,
collatorInternalProperties);
var actualLocale = BestAvailableLocaleIgnoringDefault(availableLocales, locale);
/**
* Returns the default caseFirst values for the given locale. The first
* element in the returned array denotes the default value per ES2017 Intl,
* 9.1 Internal slots of Service Constructors.
*/
function collatorSortCaseFirst(locale) {
var actualLocale = collatorActualLocale(locale);
if (intl_isUpperCaseFirst(actualLocale))
return ["upper", "false", "lower"];
if (intl_isUpperCaseFirst(actualLocale))
return ["upper", "false", "lower"];
}
// Default caseFirst values for all other languages.
return ["false", "lower", "upper"];
}
/**
* Returns the default caseFirst value for the given locale.
*/
function collatorSortCaseFirstDefault(locale) {
var actualLocale = collatorActualLocale(locale);
if (intl_isUpperCaseFirst(actualLocale))
return "upper";
// Default caseFirst value for all other languages.
return "false";
function collatorSortLocaleData(locale) {
return {
co: intl_availableCollations(locale),
kn: ["false", "true"],
kf: collatorCaseFirst(locale, "sort"),
};
}
function collatorSortLocaleData() {
/* eslint-disable object-shorthand */
function collatorSearchLocaleData(locale) {
return {
co: intl_availableCollations,
kn: function() {
return ["false", "true"];
},
kf: collatorSortCaseFirst,
default: {
co: function() {
// The first element of the collations array must be |null|
// per ES2017 Intl, 10.2.3 Internal Slots.
return null;
},
kn: function() {
return "false";
},
kf: collatorSortCaseFirstDefault,
}
co: [null],
kn: ["false", "true"],
kf: collatorCaseFirst(locale, "search"),
// In theory the default sensitivity is locale dependent;
// in reality the CLDR/ICU default strength is always tertiary.
sensitivity: "variant"
};
/* eslint-enable object-shorthand */
}
function collatorSearchLocaleData() {
/* eslint-disable object-shorthand */
return {
co: function() {
return [null];
},
kn: function() {
return ["false", "true"];
},
kf: function() {
return ["false", "lower", "upper"];
},
default: {
co: function() {
return null;
},
kn: function() {
return "false";
},
kf: function() {
return "false";
},
}
};
/* eslint-enable object-shorthand */
}
@ -2280,12 +2232,9 @@ function getNumberingSystems(locale) {
}
function numberFormatLocaleData() {
function numberFormatLocaleData(locale) {
return {
nu: getNumberingSystems,
default: {
nu: intl_numberingSystem,
}
nu: getNumberingSystems(locale)
};
}
@ -2977,14 +2926,10 @@ var dateTimeFormatInternalProperties = {
};
function dateTimeFormatLocaleData() {
function dateTimeFormatLocaleData(locale) {
return {
ca: intl_availableCalendars,
nu: getNumberingSystems,
default: {
ca: intl_defaultCalendar,
nu: intl_numberingSystem,
}
ca: intl_availableCalendars(locale),
nu: getNumberingSystems(locale)
};
}
@ -3198,7 +3143,6 @@ function resolveICUPattern(pattern, result) {
* Spec: ECMAScript 402 API, PluralRules, 1.3.3.
*/
var pluralRulesInternalProperties = {
localeData: pluralRulesLocaleData,
_availableLocales: null,
availableLocales: function() // eslint-disable-line object-shorthand
{
@ -3209,17 +3153,9 @@ var pluralRulesInternalProperties = {
locales = intl_PluralRules_availableLocales();
addSpecialMissingLanguageTags(locales);
return (this._availableLocales = locales);
},
relevantExtensionKeys: [],
}
};
function pluralRulesLocaleData() {
// PluralRules don't support any extension keys.
return {};
}
/**
* Compute an internal properties object from |lazyPluralRulesData|.
*/
@ -3234,7 +3170,7 @@ function resolvePluralRulesInternals(lazyPluralRulesData) {
const r = ResolveLocale(callFunction(PluralRules.availableLocales, PluralRules),
lazyPluralRulesData.requestedLocales,
lazyPluralRulesData.opt,
PluralRules.relevantExtensionKeys, PluralRules.localeData);
noRelevantExtensionKeys, undefined);
// Step 14.
internalProps.locale = r.locale;

Просмотреть файл

@ -2553,7 +2553,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("intl_CompareStrings", intl_CompareStrings, 3,0),
JS_FN("intl_DateTimeFormat", intl_DateTimeFormat, 2,0),
JS_FN("intl_DateTimeFormat_availableLocales", intl_DateTimeFormat_availableLocales, 0,0),
JS_FN("intl_defaultCalendar", intl_defaultCalendar, 1,0),
JS_FN("intl_defaultTimeZone", intl_defaultTimeZone, 0,0),
JS_FN("intl_defaultTimeZoneOffset", intl_defaultTimeZoneOffset, 0,0),
JS_FN("intl_FormatDateTime", intl_FormatDateTime, 2,0),