summaryrefslogtreecommitdiff
path: root/deps/v8/src/js/intl.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/js/intl.js')
-rw-r--r--deps/v8/src/js/intl.js142
1 files changed, 84 insertions, 58 deletions
diff --git a/deps/v8/src/js/intl.js b/deps/v8/src/js/intl.js
index 2e51459883..82c28f79e0 100644
--- a/deps/v8/src/js/intl.js
+++ b/deps/v8/src/js/intl.js
@@ -29,6 +29,7 @@ var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator;
var GlobalNumber = global.Number;
var GlobalRegExp = global.RegExp;
var GlobalString = global.String;
+var GlobalArray = global.Array;
var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol");
var InternalArray = utils.InternalArray;
var MathMax = global.Math.max;
@@ -38,6 +39,7 @@ var patternSymbol = utils.ImportNow("intl_pattern_symbol");
var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
var StringSubstr = GlobalString.prototype.substr;
var StringSubstring = GlobalString.prototype.substring;
+var ArraySlice = GlobalArray.prototype.slice;
utils.Import(function(from) {
ArrayJoin = from.ArrayJoin;
@@ -67,7 +69,7 @@ endmacro
/**
* Adds bound method to the prototype of the given object.
*/
-function AddBoundMethod(obj, methodName, implementation, length, typename,
+function AddBoundMethod(obj, methodName, implementation, length, type,
compat) {
%CheckIsBootstrapping();
var internalName = %CreatePrivateSymbol(methodName);
@@ -75,7 +77,10 @@ function AddBoundMethod(obj, methodName, implementation, length, typename,
DEFINE_METHOD(
obj.prototype,
get [methodName]() {
- var receiver = Unwrap(this, typename, obj, methodName, compat);
+ if(!IS_RECEIVER(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
+ }
+ var receiver = %IntlUnwrapReceiver(this, type, obj, methodName, compat);
if (IS_UNDEFINED(receiver[internalName])) {
var boundMethod;
if (IS_UNDEFINED(length) || length === 2) {
@@ -120,31 +125,19 @@ function IntlConstruct(receiver, constructor, create, newTarget, args,
-function Unwrap(receiver, typename, constructor, method, compat) {
- if (!%IsInitializedIntlObjectOfType(receiver, typename)) {
- if (compat && receiver instanceof constructor) {
- let fallback = receiver[IntlFallbackSymbol];
- if (%IsInitializedIntlObjectOfType(fallback, typename)) {
- return fallback;
- }
- }
- throw %make_type_error(kIncompatibleMethodReceiver, method, receiver);
- }
- return receiver;
-}
-
-
// -------------------------------------------------------------------
/**
* Caches available locales for each service.
*/
var AVAILABLE_LOCALES = {
+ __proto__ : null,
'collator': UNDEFINED,
'numberformat': UNDEFINED,
'dateformat': UNDEFINED,
'breakiterator': UNDEFINED,
'pluralrules': UNDEFINED,
+ 'relativetimeformat': UNDEFINED,
};
/**
@@ -363,23 +356,29 @@ function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
function getGetOption(options, caller) {
if (IS_UNDEFINED(options)) throw %make_error(kDefaultOptionsMissing, caller);
- var getOption = function getOption(property, type, values, defaultValue) {
- if (!IS_UNDEFINED(options[property])) {
- var value = options[property];
+ // Ecma 402 #sec-getoption
+ var getOption = function (property, type, values, fallback) {
+ // 1. Let value be ? Get(options, property).
+ var value = options[property];
+ // 2. If value is not undefined, then
+ if (!IS_UNDEFINED(value)) {
switch (type) {
+ // If type is "boolean", then let value be ToBoolean(value).
case 'boolean':
value = TO_BOOLEAN(value);
break;
+ // If type is "string", then let value be ToString(value).
case 'string':
value = TO_STRING(value);
break;
- case 'number':
- value = TO_NUMBER(value);
- break;
+ // Assert: type is "boolean" or "string".
default:
throw %make_error(kWrongValueType);
}
+ // d. If values is not undefined, then
+ // If values does not contain an element equal to value, throw a
+ // RangeError exception.
if (!IS_UNDEFINED(values) && %ArrayIndexOf(values, value, 0) === -1) {
throw %make_range_error(kValueOutOfRange, value, caller, property);
}
@@ -387,7 +386,7 @@ function getGetOption(options, caller) {
return value;
}
- return defaultValue;
+ return fallback;
}
return getOption;
@@ -426,6 +425,9 @@ function resolveLocale(service, requestedLocales, options) {
return resolved;
}
+%InstallToContext([
+ "resolve_locale", resolveLocale
+]);
/**
* Look up the longest non-empty prefix of |locale| that is an element of
@@ -463,7 +465,7 @@ function attemptSingleLookup(availableLocales, requestedLocale) {
var extensionMatch = %regexp_internal_match(
GetUnicodeExtensionRE(), requestedLocale);
var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
- return {locale: availableLocale, extension: extension};
+ return {__proto__: null, locale: availableLocale, extension: extension};
}
return UNDEFINED;
}
@@ -498,6 +500,7 @@ function lookupMatcher(service, requestedLocales) {
// Didn't find a match, return default.
return {
+ __proto__: null,
locale: 'und',
extension: ''
};
@@ -1002,8 +1005,9 @@ function CreateCollator(locales, options) {
* for a collator.
*/
var COLLATOR_KEY_MAP = {
- 'kn': {'property': 'numeric', 'type': 'boolean'},
- 'kf': {'property': 'caseFirst', 'type': 'string',
+ __proto__: null,
+ 'kn': { __proto__: null, 'property': 'numeric', 'type': 'boolean'},
+ 'kf': { __proto__: null, 'property': 'caseFirst', 'type': 'string',
'values': ['false', 'lower', 'upper']}
};
@@ -1053,7 +1057,7 @@ function CreateCollator(locales, options) {
var collator = %CreateCollator(requestedLocale, internalOptions, resolved);
- %MarkAsInitializedIntlObjectOfType(collator, 'collator');
+ %MarkAsInitializedIntlObjectOfType(collator, COLLATOR_TYPE);
collator[resolvedSymbol] = resolved;
return collator;
@@ -1079,8 +1083,12 @@ function CollatorConstructor() {
DEFINE_METHOD(
GlobalIntlCollator.prototype,
resolvedOptions() {
- var coll = Unwrap(this, 'collator', GlobalIntlCollator, 'resolvedOptions',
- false);
+ var methodName = 'resolvedOptions';
+ if(!IS_RECEIVER(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
+ }
+ var coll = %IntlUnwrapReceiver(this, COLLATOR_TYPE, GlobalIntlCollator,
+ methodName, false);
return {
locale: coll[resolvedSymbol].locale,
usage: coll[resolvedSymbol].usage,
@@ -1123,7 +1131,7 @@ function compare(collator, x, y) {
};
-AddBoundMethod(GlobalIntlCollator, 'compare', compare, 2, 'collator', false);
+AddBoundMethod(GlobalIntlCollator, 'compare', compare, 2, COLLATOR_TYPE, false);
function PluralRulesConstructor() {
if (IS_UNDEFINED(new.target)) {
@@ -1166,7 +1174,7 @@ function PluralRulesConstructor() {
var pluralRules = %CreatePluralRules(requestedLocale, internalOptions,
resolved);
- %MarkAsInitializedIntlObjectOfType(pluralRules, 'pluralrules');
+ %MarkAsInitializedIntlObjectOfType(pluralRules, PLURAL_RULES_TYPE);
pluralRules[resolvedSymbol] = resolved;
return pluralRules;
@@ -1176,7 +1184,7 @@ function PluralRulesConstructor() {
DEFINE_METHOD(
GlobalIntlPluralRules.prototype,
resolvedOptions() {
- if (!%IsInitializedIntlObjectOfType(this, 'pluralrules')) {
+ if (!%IsInitializedIntlObjectOfType(this, PLURAL_RULES_TYPE)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Intl.PluralRules.prototype.resolvedOptions',
this);
@@ -1201,8 +1209,7 @@ DEFINE_METHOD(
}
defineWECProperty(result, 'pluralCategories',
- this[resolvedSymbol].pluralCategories);
-
+ %_Call(ArraySlice, this[resolvedSymbol].pluralCategories));
return result;
}
);
@@ -1217,7 +1224,7 @@ DEFINE_METHOD(
DEFINE_METHOD(
GlobalIntlPluralRules.prototype,
select(value) {
- if (!%IsInitializedIntlObjectOfType(this, 'pluralrules')) {
+ if (!%IsInitializedIntlObjectOfType(this, PLURAL_RULES_TYPE)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Intl.PluralRules.prototype.select',
this);
@@ -1345,7 +1352,8 @@ function CreateNumberFormat(locales, options) {
* for a number format.
*/
var NUMBER_FORMAT_KEY_MAP = {
- 'nu': {'property': UNDEFINED, 'type': 'string'}
+ __proto__: null,
+ 'nu': {__proto__: null, 'property': UNDEFINED, 'type': 'string'}
};
var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
@@ -1378,7 +1386,7 @@ function CreateNumberFormat(locales, options) {
{value: currencyDisplay, writable: true});
}
- %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat');
+ %MarkAsInitializedIntlObjectOfType(numberFormat, NUMBER_FORMAT_TYPE);
numberFormat[resolvedSymbol] = resolved;
return numberFormat;
@@ -1404,8 +1412,13 @@ function NumberFormatConstructor() {
DEFINE_METHOD(
GlobalIntlNumberFormat.prototype,
resolvedOptions() {
- var format = Unwrap(this, 'numberformat', GlobalIntlNumberFormat,
- 'resolvedOptions', true);
+ var methodName = 'resolvedOptions';
+ if(!IS_RECEIVER(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
+ }
+ var format = %IntlUnwrapReceiver(this, NUMBER_FORMAT_TYPE,
+ GlobalIntlNumberFormat,
+ methodName, true);
var result = {
locale: format[resolvedSymbol].locale,
numberingSystem: format[resolvedSymbol].numberingSystem,
@@ -1463,10 +1476,6 @@ function formatNumber(formatter, value) {
return %InternalNumberFormat(formatter, number);
}
-
-AddBoundMethod(GlobalIntlNumberFormat, 'format', formatNumber, 1,
- 'numberformat', true);
-
/**
* Returns a string that matches LDML representation of the options object.
*/
@@ -1705,8 +1714,9 @@ function CreateDateTimeFormat(locales, options) {
* for a date/time format.
*/
var DATETIME_FORMAT_KEY_MAP = {
- 'ca': {'property': UNDEFINED, 'type': 'string'},
- 'nu': {'property': UNDEFINED, 'type': 'string'}
+ __proto__: null,
+ 'ca': {__proto__: null, 'property': UNDEFINED, 'type': 'string'},
+ 'nu': {__proto__: null, 'property': UNDEFINED, 'type': 'string'}
};
var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP,
@@ -1734,13 +1744,14 @@ function CreateDateTimeFormat(locales, options) {
});
var dateFormat = %CreateDateTimeFormat(
- requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
+ requestedLocale,
+ {__proto__: null, skeleton: ldmlString, timeZone: tz}, resolved);
if (resolved.timeZone === "Etc/Unknown") {
throw %make_range_error(kUnsupportedTimeZone, tz);
}
- %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat');
+ %MarkAsInitializedIntlObjectOfType(dateFormat, DATE_TIME_FORMAT_TYPE);
dateFormat[resolvedSymbol] = resolved;
return dateFormat;
@@ -1766,8 +1777,13 @@ function DateTimeFormatConstructor() {
DEFINE_METHOD(
GlobalIntlDateTimeFormat.prototype,
resolvedOptions() {
- var format = Unwrap(this, 'dateformat', GlobalIntlDateTimeFormat,
- 'resolvedOptions', true);
+ var methodName = 'resolvedOptions';
+ if(!IS_RECEIVER(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
+ }
+ var format = %IntlUnwrapReceiver(this, DATE_TIME_FORMAT_TYPE,
+ GlobalIntlDateTimeFormat,
+ methodName, true);
/**
* Maps ICU calendar names to LDML/BCP47 types for key 'ca'.
@@ -1776,6 +1792,7 @@ DEFINE_METHOD(
* http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
*/
var ICU_CALENDAR_MAP = {
+ __proto__: null,
'gregorian': 'gregory',
'ethiopic-amete-alem': 'ethioaa'
};
@@ -1841,7 +1858,7 @@ function formatDate(formatter, dateValue) {
}
// Length is 1 as specified in ECMA 402 v2+
-AddBoundMethod(GlobalIntlDateTimeFormat, 'format', formatDate, 1, 'dateformat',
+AddBoundMethod(GlobalIntlDateTimeFormat, 'format', formatDate, 1, DATE_TIME_FORMAT_TYPE,
true);
@@ -1911,7 +1928,7 @@ function CreateBreakIterator(locales, options) {
var iterator = %CreateBreakIterator(locale.locale, internalOptions, resolved);
- %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator');
+ %MarkAsInitializedIntlObjectOfType(iterator, BREAK_ITERATOR_TYPE);
iterator[resolvedSymbol] = resolved;
return iterator;
@@ -1941,8 +1958,13 @@ DEFINE_METHOD(
throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
- var segmenter = Unwrap(this, 'breakiterator', GlobalIntlv8BreakIterator,
- 'resolvedOptions', false);
+ var methodName = 'resolvedOptions';
+ if(!IS_RECEIVER(this)) {
+ throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
+ }
+ var segmenter = %IntlUnwrapReceiver(this, BREAK_ITERATOR_TYPE,
+ GlobalIntlv8BreakIterator, methodName,
+ false);
return {
locale: segmenter[resolvedSymbol].locale,
@@ -2012,16 +2034,19 @@ function breakType(iterator) {
AddBoundMethod(GlobalIntlv8BreakIterator, 'adoptText', adoptText, 1,
- 'breakiterator');
-AddBoundMethod(GlobalIntlv8BreakIterator, 'first', first, 0, 'breakiterator');
-AddBoundMethod(GlobalIntlv8BreakIterator, 'next', next, 0, 'breakiterator');
+ BREAK_ITERATOR_TYPE, false);
+AddBoundMethod(GlobalIntlv8BreakIterator, 'first', first, 0,
+ BREAK_ITERATOR_TYPE, false);
+AddBoundMethod(GlobalIntlv8BreakIterator, 'next', next, 0,
+ BREAK_ITERATOR_TYPE, false);
AddBoundMethod(GlobalIntlv8BreakIterator, 'current', current, 0,
- 'breakiterator');
+ BREAK_ITERATOR_TYPE, false);
AddBoundMethod(GlobalIntlv8BreakIterator, 'breakType', breakType, 0,
- 'breakiterator');
+ BREAK_ITERATOR_TYPE, false);
// Save references to Intl objects and methods we use, for added security.
var savedObjects = {
+ __proto__: null,
'collator': GlobalIntlCollator,
'numberformat': GlobalIntlNumberFormat,
'dateformatall': GlobalIntlDateTimeFormat,
@@ -2033,6 +2058,7 @@ var savedObjects = {
// Default (created with undefined locales and options parameters) collator,
// number and date format instances. They'll be created as needed.
var defaultObjects = {
+ __proto__: null,
'collator': UNDEFINED,
'numberformat': UNDEFINED,
'dateformatall': UNDEFINED,