Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: cherry-pick 6989b3f6d7 from V8 upstream #20826

Merged
merged 1 commit into from
May 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.8',
'v8_embedder_string': '-node.9',

# Enable disassembler for `--print-code` v8 options
'v8_enable_disassembler': 1,
Expand Down
89 changes: 59 additions & 30 deletions deps/v8/src/js/intl.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,11 @@ var AVAILABLE_LOCALES = {
*/
var DEFAULT_ICU_LOCALE = UNDEFINED;

function GetDefaultICULocaleJS(service) {
function GetDefaultICULocaleJS() {
if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
}
// Check that this is a valid default for this service,
// otherwise fall back to "und"
// TODO(littledan,jshin): AvailableLocalesOf sometimes excludes locales
// which don't require tailoring, but work fine with root data. Look into
// exposing this fact in ICU or the way Chrome bundles data.
return (IS_UNDEFINED(service) ||
HAS_OWN_PROPERTY(getAvailableLocalesOf(service), DEFAULT_ICU_LOCALE))
? DEFAULT_ICU_LOCALE : "und";
return DEFAULT_ICU_LOCALE;
}

/**
Expand Down Expand Up @@ -434,6 +427,48 @@ function resolveLocale(service, requestedLocales, options) {
}


/**
* Look up the longest non-empty prefix of |locale| that is an element of
* |availableLocales|. Returns undefined when the |locale| is completely
* unsupported by |availableLocales|.
*/
function bestAvailableLocale(availableLocales, locale) {
do {
if (!IS_UNDEFINED(availableLocales[locale])) {
return locale;
}
// Truncate locale if possible.
var pos = %StringLastIndexOf(locale, '-');
if (pos === -1) {
break;
}
locale = %_Call(StringSubstring, locale, 0, pos);
} while (true);

return UNDEFINED;
}


/**
* Try to match any mutation of |requestedLocale| against |availableLocales|.
*/
function attemptSingleLookup(availableLocales, requestedLocale) {
// Remove all extensions.
var noExtensionsLocale = %RegExpInternalReplace(
GetAnyExtensionRE(), requestedLocale, '');
var availableLocale = bestAvailableLocale(
availableLocales, requestedLocale);
if (!IS_UNDEFINED(availableLocale)) {
// Return the resolved locale and extension.
var extensionMatch = %regexp_internal_match(
GetUnicodeExtensionRE(), requestedLocale);
var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
return {locale: availableLocale, extension: extension};
}
return UNDEFINED;
}


/**
* Returns best matched supported locale and extension info using basic
* lookup algorithm.
Expand All @@ -446,31 +481,25 @@ function lookupMatcher(service, requestedLocales) {
var availableLocales = getAvailableLocalesOf(service);

for (var i = 0; i < requestedLocales.length; ++i) {
// Remove all extensions.
var locale = %RegExpInternalReplace(
GetAnyExtensionRE(), requestedLocales[i], '');
do {
if (!IS_UNDEFINED(availableLocales[locale])) {
// Return the resolved locale and extension.
var extensionMatch = %regexp_internal_match(
GetUnicodeExtensionRE(), requestedLocales[i]);
var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
return {locale: locale, extension: extension, position: i};
}
// Truncate locale if possible.
var pos = %StringLastIndexOf(locale, '-');
if (pos === -1) {
break;
}
locale = %_Call(StringSubstring, locale, 0, pos);
} while (true);
var result = attemptSingleLookup(availableLocales, requestedLocales[i]);
if (!IS_UNDEFINED(result)) {
return result;
}
}

var defLocale = GetDefaultICULocaleJS();

// While ECMA-402 returns defLocale directly, we have to check if it is
// supported, as such support is not guaranteed.
var result = attemptSingleLookup(availableLocales, defLocale);
if (!IS_UNDEFINED(result)) {
return result;
}

// Didn't find a match, return default.
return {
locale: GetDefaultICULocaleJS(service),
extension: '',
position: -1
locale: 'und',
extension: ''
};
}

Expand Down
41 changes: 41 additions & 0 deletions deps/v8/test/intl/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ function assertFalse(value, user_message = '') {
}


/**
* Throws if value is null.
*/
function assertNotNull(value, user_message = '') {
if (value === null) {
fail("not null", value, user_message);
}
}


/**
* Runs code() and asserts that it throws the specified exception.
*/
Expand Down Expand Up @@ -189,3 +199,34 @@ function assertInstanceof(obj, type) {
(actualTypeName ? ' but of < ' + actualTypeName + '>' : ''));
}
}


/**
* Split a BCP 47 language tag into locale and extension.
*/
function splitLanguageTag(tag) {
var extRe = /(-[0-9A-Za-z](-[0-9A-Za-z]{2,8})+)+$/;
var match = %regexp_internal_match(extRe, tag);
if (match) {
return { locale: tag.slice(0, match.index), extension: match[0] };
}

return { locale: tag, extension: '' };
}


/**
* Throw if |parent| is not a more general language tag of |child|, nor |child|
* itself, per BCP 47 rules.
*/
function assertLanguageTag(child, parent) {
var childSplit = splitLanguageTag(child);
var parentSplit = splitLanguageTag(parent);

// Do not compare extensions at this moment, as %GetDefaultICULocale()
// doesn't always output something we support.
if (childSplit.locale !== parentSplit.locale &&
!childSplit.locale.startsWith(parentSplit.locale + '-')) {
fail(child, parent, 'language tag comparison');
}
}
4 changes: 2 additions & 2 deletions deps/v8/test/intl/break-iterator/default-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);

// Then check for equality.
assertEquals(options.locale, %GetDefaultICULocale());
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);

var iteratorNone = new Intl.v8BreakIterator();
assertEquals(options.locale, iteratorNone.resolvedOptions().locale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@

var iterator = Intl.v8BreakIterator(['xx']);

assertEquals(iterator.resolvedOptions().locale, %GetDefaultICULocale());
assertLanguageTag(%GetDefaultICULocale(), iterator.resolvedOptions().locale);
11 changes: 7 additions & 4 deletions deps/v8/test/intl/collator/default-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);

// Then check for equality.
assertEquals(options.locale, %GetDefaultICULocale());
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);

var collatorNone = new Intl.Collator();
assertEquals(options.locale, collatorNone.resolvedOptions().locale);
Expand All @@ -48,5 +48,8 @@ var collatorBraket = new Intl.Collator({});
assertEquals(options.locale, collatorBraket.resolvedOptions().locale);

var collatorWithOptions = new Intl.Collator(undefined, {usage: 'search'});
assertEquals(%GetDefaultICULocale() + '-u-co-search',
collatorWithOptions.resolvedOptions().locale);
assertLanguageTag(%GetDefaultICULocale(),
collatorWithOptions.resolvedOptions().locale);
assertNotNull(
%regexp_internal_match(/-u(-[a-zA-Z]+-[a-zA-Z]+)*-co-search/,
collatorWithOptions.resolvedOptions().locale));
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@

var collator = Intl.Collator(['xx']);

assertEquals(collator.resolvedOptions().locale, %GetDefaultICULocale());
assertLanguageTag(%GetDefaultICULocale(), collator.resolvedOptions().locale);
4 changes: 2 additions & 2 deletions deps/v8/test/intl/date-format/default-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);

// Then check for equality.
assertEquals(options.locale, %GetDefaultICULocale());
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);

var dtfNone = new Intl.DateTimeFormat();
assertEquals(options.locale, dtfNone.resolvedOptions().locale);
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@

var dtf = Intl.DateTimeFormat(['xx']);

assertEquals(dtf.resolvedOptions().locale, %GetDefaultICULocale());
assertLanguageTag(%GetDefaultICULocale(), dtf.resolvedOptions().locale);
4 changes: 2 additions & 2 deletions deps/v8/test/intl/number-format/default-locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);

// Then check for equality.
assertEquals(options.locale, %GetDefaultICULocale());
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);

var nfNone = new Intl.NumberFormat();
assertEquals(options.locale, nfNone.resolvedOptions().locale);
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@

var nf = Intl.NumberFormat(['xx']);

assertEquals(nf.resolvedOptions().locale, %GetDefaultICULocale());
assertLanguageTag(%GetDefaultICULocale(), nf.resolvedOptions().locale);
2 changes: 1 addition & 1 deletion deps/v8/test/mjsunit/regress/regress-6288.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
// DateTimeFormat but not Collation

if (this.Intl) {
assertEquals('und', Intl.Collator().resolvedOptions().locale);
assertEquals('pt', Intl.Collator().resolvedOptions().locale);
assertEquals('pt-BR', Intl.DateTimeFormat().resolvedOptions().locale);
}