summaryrefslogtreecommitdiff
path: root/deps/v8/src/js/i18n.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/js/i18n.js')
-rw-r--r--deps/v8/src/js/i18n.js579
1 files changed, 369 insertions, 210 deletions
diff --git a/deps/v8/src/js/i18n.js b/deps/v8/src/js/i18n.js
index 845289a91f..6046a6f2f9 100644
--- a/deps/v8/src/js/i18n.js
+++ b/deps/v8/src/js/i18n.js
@@ -17,26 +17,19 @@
// -------------------------------------------------------------------
// Imports
-var ArrayIndexOf;
var ArrayJoin;
var ArrayPush;
-var GlobalBoolean = global.Boolean;
+var FLAG_intl_extra;
var GlobalDate = global.Date;
var GlobalNumber = global.Number;
var GlobalRegExp = global.RegExp;
var GlobalString = global.String;
var InstallFunctions = utils.InstallFunctions;
var InstallGetter = utils.InstallGetter;
-var InternalPackedArray = utils.InternalPackedArray;
+var InternalArray = utils.InternalArray;
var InternalRegExpMatch;
var InternalRegExpReplace
-var IsFinite;
var IsNaN;
-var MakeError;
-var MakeRangeError;
-var MakeTypeError;
-var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties");
-var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty");
var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
var OverrideFunction = utils.OverrideFunction;
var patternSymbol = utils.ImportNow("intl_pattern_symbol");
@@ -44,28 +37,25 @@ var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
var SetFunctionName = utils.SetFunctionName;
var StringIndexOf;
var StringLastIndexOf;
-var StringSplit;
var StringSubstr;
var StringSubstring;
utils.Import(function(from) {
- ArrayIndexOf = from.ArrayIndexOf;
ArrayJoin = from.ArrayJoin;
ArrayPush = from.ArrayPush;
- IsFinite = from.IsFinite;
IsNaN = from.IsNaN;
- MakeError = from.MakeError;
- MakeRangeError = from.MakeRangeError;
- MakeTypeError = from.MakeTypeError;
InternalRegExpMatch = from.InternalRegExpMatch;
InternalRegExpReplace = from.InternalRegExpReplace;
StringIndexOf = from.StringIndexOf;
StringLastIndexOf = from.StringLastIndexOf;
- StringSplit = from.StringSplit;
StringSubstr = from.StringSubstr;
StringSubstring = from.StringSubstring;
});
+utils.ImportFromExperimental(function(from) {
+ FLAG_intl_extra = from.FLAG_intl_extra;
+});
+
// Utilities for definitions
function InstallFunction(object, name, func) {
@@ -84,43 +74,45 @@ function InstallConstructor(object, name, func) {
/**
* Adds bound method to the prototype of the given object.
*/
-function AddBoundMethod(obj, methodName, implementation, length) {
+function AddBoundMethod(obj, methodName, implementation, length, type) {
%CheckIsBootstrapping();
var internalName = %CreatePrivateSymbol(methodName);
- var getter = function() {
- if (!%IsInitializedIntlObject(this)) {
- throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
+ // Making getter an anonymous function will cause
+ // %DefineGetterPropertyUnchecked to properly set the "name"
+ // property on each JSFunction instance created here, rather
+ // than (as utils.InstallGetter would) on the SharedFunctionInfo
+ // associated with all functions returned from AddBoundMethod.
+ var getter = ANONYMOUS_FUNCTION(function() {
+ if (!%IsInitializedIntlObjectOfType(this, type)) {
+ throw %make_type_error(kMethodCalledOnWrongObject, methodName);
}
if (IS_UNDEFINED(this[internalName])) {
var boundMethod;
if (IS_UNDEFINED(length) || length === 2) {
- boundMethod = (x, y) => implementation(this, x, y);
+ boundMethod = ANONYMOUS_FUNCTION((x, y) => implementation(this, x, y));
} else if (length === 1) {
- boundMethod = x => implementation(this, x);
+ boundMethod = ANONYMOUS_FUNCTION(x => implementation(this, x));
} else {
- boundMethod = (...args) => {
- // DateTimeFormat.format needs to be 0 arg method, but can stil
- // receive optional dateValue param. If one was provided, pass it
+ boundMethod = ANONYMOUS_FUNCTION((...args) => {
+ // DateTimeFormat.format needs to be 0 arg method, but can still
+ // receive an optional dateValue param. If one was provided, pass it
// along.
if (args.length > 0) {
return implementation(this, args[0]);
} else {
return implementation(this);
}
- }
+ });
}
- // TODO(littledan): Once function name reform is shipped, remove the
- // following line and wrap the boundMethod definition in an anonymous
- // function macro.
- %FunctionSetName(boundMethod, '__bound' + methodName + '__');
- %FunctionRemovePrototype(boundMethod);
%SetNativeFlag(boundMethod);
this[internalName] = boundMethod;
}
return this[internalName];
- };
+ });
- InstallGetter(obj.prototype, methodName, getter, DONT_ENUM);
+ %FunctionRemovePrototype(getter);
+ %DefineGetterPropertyUnchecked(obj.prototype, methodName, getter, DONT_ENUM);
+ %SetNativeFlag(getter);
}
// -------------------------------------------------------------------
@@ -144,6 +136,13 @@ var AVAILABLE_LOCALES = {
*/
var DEFAULT_ICU_LOCALE = UNDEFINED;
+function GetDefaultICULocaleJS() {
+ if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
+ DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+ }
+ return DEFAULT_ICU_LOCALE;
+}
+
/**
* Unicode extension regular expression.
*/
@@ -263,7 +262,7 @@ function GetTimezoneNameLocationPartRE() {
*/
function supportedLocalesOf(service, locales, options) {
if (IS_NULL(InternalRegExpMatch(GetServiceRE(), service))) {
- throw MakeError(kWrongServiceType, service);
+ throw %make_error(kWrongServiceType, service);
}
// Provide defaults if matcher was not specified.
@@ -275,9 +274,9 @@ function supportedLocalesOf(service, locales, options) {
var matcher = options.localeMatcher;
if (!IS_UNDEFINED(matcher)) {
- matcher = GlobalString(matcher);
+ matcher = TO_STRING(matcher);
if (matcher !== 'lookup' && matcher !== 'best fit') {
- throw MakeRangeError(kLocaleMatcher, matcher);
+ throw %make_range_error(kLocaleMatcher, matcher);
}
} else {
matcher = 'best fit';
@@ -307,7 +306,7 @@ function supportedLocalesOf(service, locales, options) {
* Locales appear in the same order in the returned list as in the input list.
*/
function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
- var matchedLocales = [];
+ var matchedLocales = new InternalArray();
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove -u- extension.
var locale = InternalRegExpReplace(
@@ -349,27 +348,27 @@ function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
* is out of range for that property it throws RangeError.
*/
function getGetOption(options, caller) {
- if (IS_UNDEFINED(options)) throw MakeError(kDefaultOptionsMissing, 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];
switch (type) {
case 'boolean':
- value = GlobalBoolean(value);
+ value = TO_BOOLEAN(value);
break;
case 'string':
- value = GlobalString(value);
+ value = TO_STRING(value);
break;
case 'number':
- value = GlobalNumber(value);
+ value = TO_NUMBER(value);
break;
default:
- throw MakeError(kWrongValueType);
+ throw %make_error(kWrongValueType);
}
- if (!IS_UNDEFINED(values) && %_Call(ArrayIndexOf, values, value) === -1) {
- throw MakeRangeError(kValueOutOfRange, value, caller, property);
+ if (!IS_UNDEFINED(values) && %ArrayIndexOf(values, value, 0) === -1) {
+ throw %make_range_error(kValueOutOfRange, value, caller, property);
}
return value;
@@ -383,6 +382,9 @@ function getGetOption(options, caller) {
/**
+ * Ecma 402 9.2.5
+ * TODO(jshin): relevantExtensionKeys and localeData need to be taken into
+ * account per spec.
* Compares a BCP 47 language priority list requestedLocales against the locales
* in availableLocales and determines the best available language to meet the
* request. Two algorithms are available to match the locales: the Lookup
@@ -418,7 +420,7 @@ function resolveLocale(service, requestedLocales, options) {
*/
function lookupMatcher(service, requestedLocales) {
if (IS_NULL(InternalRegExpMatch(GetServiceRE(), service))) {
- throw MakeError(kWrongServiceType, service);
+ throw %make_error(kWrongServiceType, service);
}
// Cache these, they don't ever change per service.
@@ -448,11 +450,7 @@ function lookupMatcher(service, requestedLocales) {
}
// Didn't find a match, return default.
- if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
- DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
- }
-
- return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+ return {'locale': GetDefaultICULocaleJS(), 'extension': '', 'position': -1};
}
@@ -470,9 +468,14 @@ function bestFitMatcher(service, requestedLocales) {
* Parses Unicode extension into key - value map.
* Returns empty object if the extension string is invalid.
* We are not concerned with the validity of the values at this point.
+ * 'attribute' in RFC 6047 is not supported. Keys without explicit
+ * values are assigned UNDEFINED.
+ * TODO(jshin): Fix the handling of 'attribute' (in RFC 6047, but none
+ * has been defined so that it's not used) and boolean keys without
+ * an explicit value.
*/
function parseExtension(extension) {
- var extensionSplit = %_Call(StringSplit, extension, '-');
+ var extensionSplit = %StringSplit(extension, '-', kMaxUint32);
// Assume ['', 'u', ...] input, but don't throw.
if (extensionSplit.length <= 2 ||
@@ -483,21 +486,33 @@ function parseExtension(extension) {
// Key is {2}alphanum, value is {3,8}alphanum.
// Some keys may not have explicit values (booleans).
var extensionMap = {};
- var previousKey = UNDEFINED;
+ var key = UNDEFINED;
+ var value = UNDEFINED;
for (var i = 2; i < extensionSplit.length; ++i) {
var length = extensionSplit[i].length;
var element = extensionSplit[i];
if (length === 2) {
- extensionMap[element] = UNDEFINED;
- previousKey = element;
- } else if (length >= 3 && length <=8 && !IS_UNDEFINED(previousKey)) {
- extensionMap[previousKey] = element;
- previousKey = UNDEFINED;
+ if (!IS_UNDEFINED(key)) {
+ if (!(key in extensionMap)) {
+ extensionMap[key] = value;
+ }
+ value = UNDEFINED;
+ }
+ key = element;
+ } else if (length >= 3 && length <= 8 && !IS_UNDEFINED(key)) {
+ if (IS_UNDEFINED(value)) {
+ value = element;
+ } else {
+ value = value + "-" + element;
+ }
} else {
// There is a value that's too long, or that doesn't have a key.
return {};
}
}
+ if (!IS_UNDEFINED(key) && !(key in extensionMap)) {
+ extensionMap[key] = value;
+ }
return extensionMap;
}
@@ -517,7 +532,7 @@ function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
var extension = '';
var updateExtension = function updateExtension(key, value) {
- return '-' + key + '-' + GlobalString(value);
+ return '-' + key + '-' + TO_STRING(value);
}
var updateProperty = function updateProperty(property, type, value) {
@@ -567,24 +582,33 @@ function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
/**
- * Converts all OwnProperties into
+ * Given an array-like, outputs an Array with the numbered
+ * properties copied over and defined
* configurable: false, writable: false, enumerable: true.
+ * When |expandable| is true, the result array can be expanded.
*/
-function freezeArray(array) {
- var l = array.length;
+function freezeArray(input) {
+ var array = [];
+ var l = input.length;
for (var i = 0; i < l; i++) {
- if (i in array) {
- ObjectDefineProperty(array, i, {value: array[i],
- configurable: false,
- writable: false,
- enumerable: true});
+ if (i in input) {
+ %object_define_property(array, i, {value: input[i],
+ configurable: false,
+ writable: false,
+ enumerable: true});
}
}
- ObjectDefineProperty(array, 'length', {value: l, writable: false});
+ %object_define_property(array, 'length', {value: l, writable: false});
return array;
}
+/* Make JS array[] out of InternalArray */
+function makeArray(input) {
+ var array = [];
+ %MoveArrayContents(input, array);
+ return array;
+}
/**
* It's sometimes desireable to leave user requested locale instead of ICU
@@ -643,8 +667,8 @@ function getAvailableLocalesOf(service) {
* Configurable is false by default.
*/
function defineWEProperty(object, property, value) {
- ObjectDefineProperty(object, property,
- {value: value, writable: true, enumerable: true});
+ %object_define_property(object, property,
+ {value: value, writable: true, enumerable: true});
}
@@ -663,10 +687,10 @@ function addWEPropertyIfDefined(object, property, value) {
* Defines a property and sets writable, enumerable and configurable to true.
*/
function defineWECProperty(object, property, value) {
- ObjectDefineProperty(object, property, {value: value,
- writable: true,
- enumerable: true,
- configurable: true});
+ %object_define_property(object, property, {value: value,
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
@@ -697,14 +721,14 @@ function toTitleCaseWord(word) {
*/
function toTitleCaseTimezoneLocation(location) {
var match = InternalRegExpMatch(GetTimezoneNameLocationPartRE(), location)
- if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, location);
+ if (IS_NULL(match)) throw %make_range_error(kExpectedLocation, location);
var result = toTitleCaseWord(match[1]);
if (!IS_UNDEFINED(match[2]) && 2 < match.length) {
// The first character is a separator, '_' or '-'.
// None of IANA zone names has both '_' and '-'.
var separator = %_Call(StringSubstring, match[2], 0, 1);
- var parts = %_Call(StringSplit, match[2], separator);
+ var parts = %StringSplit(match[2], separator, kMaxUint32);
for (var i = 1; i < parts.length; i++) {
var part = parts[i]
var lowercasedPart = %StringToLowerCase(part);
@@ -719,27 +743,34 @@ function toTitleCaseTimezoneLocation(location) {
/**
* Canonicalizes the language tag, or throws in case the tag is invalid.
+ * ECMA 402 9.2.1 steps 7.c ii ~ v.
*/
function canonicalizeLanguageTag(localeID) {
// null is typeof 'object' so we have to do extra check.
- if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+ if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) ||
IS_NULL(localeID)) {
- throw MakeTypeError(kLanguageID);
+ throw %make_type_error(kLanguageID);
+ }
+
+ // Optimize for the most common case; a language code alone in
+ // the canonical form/lowercase (e.g. "en", "fil").
+ if (IS_STRING(localeID) &&
+ !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) {
+ return localeID;
}
- var localeString = GlobalString(localeID);
+ var localeString = TO_STRING(localeID);
- if (isValidLanguageTag(localeString) === false) {
- throw MakeRangeError(kInvalidLanguageTag, localeString);
+ if (isStructuallyValidLanguageTag(localeString) === false) {
+ throw %make_range_error(kInvalidLanguageTag, localeString);
}
- // This call will strip -kn but not -kn-true extensions.
- // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
- // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
- // upgrade to ICU 4.9.
+ // ECMA 402 6.2.3
var tag = %CanonicalizeLanguageTag(localeString);
+ // TODO(jshin): This should not happen because the structual validity
+ // is already checked. If that's the case, remove this.
if (tag === 'invalid-tag') {
- throw MakeRangeError(kInvalidLanguageTag, localeString);
+ throw %make_range_error(kInvalidLanguageTag, localeString);
}
return tag;
@@ -747,23 +778,22 @@ function canonicalizeLanguageTag(localeID) {
/**
- * Returns an array where all locales are canonicalized and duplicates removed.
+ * Returns an InternalArray where all locales are canonicalized and duplicates
+ * removed.
* Throws on locales that are not well formed BCP47 tags.
+ * ECMA 402 8.2.1 steps 1 (ECMA 402 9.2.1) and 2.
*/
-function initializeLocaleList(locales) {
- var seen = [];
- if (IS_UNDEFINED(locales)) {
- // Constructor is called without arguments.
- seen = [];
- } else {
+function canonicalizeLocaleList(locales) {
+ var seen = new InternalArray();
+ if (!IS_UNDEFINED(locales)) {
// We allow single string localeID.
if (typeof locales === 'string') {
%_Call(ArrayPush, seen, canonicalizeLanguageTag(locales));
- return freezeArray(seen);
+ return seen;
}
var o = TO_OBJECT(locales);
- var len = TO_UINT32(o.length);
+ var len = TO_LENGTH(o.length);
for (var k = 0; k < len; k++) {
if (k in o) {
@@ -771,27 +801,37 @@ function initializeLocaleList(locales) {
var tag = canonicalizeLanguageTag(value);
- if (%_Call(ArrayIndexOf, seen, tag) === -1) {
+ if (%ArrayIndexOf(seen, tag, 0) === -1) {
%_Call(ArrayPush, seen, tag);
}
}
}
}
- return freezeArray(seen);
+ return seen;
}
+function initializeLocaleList(locales) {
+ return freezeArray(canonicalizeLocaleList(locales));
+}
/**
- * Validates the language tag. Section 2.2.9 of the bcp47 spec
- * defines a valid tag.
+ * Check the structual Validity of the language tag per ECMA 402 6.2.2:
+ * - Well-formed per RFC 5646 2.1
+ * - There are no duplicate variant subtags
+ * - There are no duplicate singletion (extension) subtags
+ *
+ * One extra-check is done (from RFC 5646 2.2.9): the tag is compared
+ * against the list of grandfathered tags. However, subtags for
+ * primary/extended language, script, region, variant are not checked
+ * against the IANA language subtag registry.
*
* ICU is too permissible and lets invalid tags, like
* hant-cmn-cn, through.
*
* Returns false if the language tag is invalid.
*/
-function isValidLanguageTag(locale) {
+function isStructuallyValidLanguageTag(locale) {
// Check if it's well-formed, including grandfadered tags.
if (IS_NULL(InternalRegExpMatch(GetLanguageTagRE(), locale))) {
return false;
@@ -805,19 +845,19 @@ function isValidLanguageTag(locale) {
// Check if there are any duplicate variants or singletons (extensions).
// Remove private use section.
- locale = %_Call(StringSplit, locale, '-x-')[0];
+ locale = %StringSplit(locale, '-x-', kMaxUint32)[0];
// Skip language since it can match variant regex, so we start from 1.
// We are matching i-klingon here, but that's ok, since i-klingon-klingon
// is not valid and would fail LANGUAGE_TAG_RE test.
- var variants = [];
- var extensions = [];
- var parts = %_Call(StringSplit, locale, '-');
+ var variants = new InternalArray();
+ var extensions = new InternalArray();
+ var parts = %StringSplit(locale, '-', kMaxUint32);
for (var i = 1; i < parts.length; i++) {
var value = parts[i];
if (!IS_NULL(InternalRegExpMatch(GetLanguageVariantRE(), value)) &&
extensions.length === 0) {
- if (%_Call(ArrayIndexOf, variants, value) === -1) {
+ if (%ArrayIndexOf(variants, value, 0) === -1) {
%_Call(ArrayPush, variants, value);
} else {
return false;
@@ -825,7 +865,7 @@ function isValidLanguageTag(locale) {
}
if (!IS_NULL(InternalRegExpMatch(GetLanguageSingletonRE(), value))) {
- if (%_Call(ArrayIndexOf, extensions, value) === -1) {
+ if (%ArrayIndexOf(extensions, value, 0) === -1) {
%_Call(ArrayPush, extensions, value);
} else {
return false;
@@ -886,13 +926,23 @@ var resolvedAccessor = {
}
};
+// ECMA 402 section 8.2.1
+InstallFunction(Intl, 'getCanonicalLocales', function(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
+ }
+
+ return makeArray(canonicalizeLocaleList(locales));
+ }
+);
+
/**
* Initializes the given object so it's a valid Collator instance.
* Useful for subclassing.
*/
function initializeCollator(collator, locales, options) {
if (%IsInitializedIntlObject(collator)) {
- throw MakeTypeError(kReinitializeIntl, "Collator");
+ throw %make_type_error(kReinitializeIntl, "Collator");
}
if (IS_UNDEFINED(options)) {
@@ -918,6 +968,9 @@ function initializeCollator(collator, locales, options) {
var locale = resolveLocale('collator', locales, options);
+ // TODO(jshin): ICU now can take kb, kc, etc. Switch over to using ICU
+ // directly. See Collator::InitializeCollator and
+ // Collator::CreateICUCollator in src/i18n.cc
// ICU can't take kb, kc... parameters through localeID, so we need to pass
// them as options.
// One exception is -co- which has to be part of the extension, but only for
@@ -950,7 +1003,7 @@ function initializeCollator(collator, locales, options) {
'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin'
];
- if (%_Call(ArrayIndexOf, ALLOWED_CO_VALUES, extensionMap.co) !== -1) {
+ if (%ArrayIndexOf(ALLOWED_CO_VALUES, extensionMap.co, 0) !== -1) {
extension = '-u-co-' + extensionMap.co;
// ICU can't tell us what the collation is, so save user's input.
collation = extensionMap.co;
@@ -965,8 +1018,8 @@ function initializeCollator(collator, locales, options) {
// We define all properties C++ code may produce, to prevent security
// problems. If malicious user decides to redefine Object.prototype.locale
// we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
- // ObjectDefineProperties will either succeed defining or throw an error.
- var resolved = ObjectDefineProperties({}, {
+ // %object_define_properties will either succeed defining or throw an error.
+ var resolved = %object_define_properties({}, {
caseFirst: {writable: true},
collation: {value: internalOptions.collation, writable: true},
ignorePunctuation: {writable: true},
@@ -985,7 +1038,9 @@ function initializeCollator(collator, locales, options) {
// Writable, configurable and enumerable are set to false by default.
%MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
collator[resolvedSymbol] = resolved;
- ObjectDefineProperty(collator, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(collator, 'resolved', resolvedAccessor);
+ }
return collator;
}
@@ -1016,11 +1071,11 @@ InstallConstructor(Intl, 'Collator', function() {
*/
InstallFunction(Intl.Collator.prototype, 'resolvedOptions', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (!%IsInitializedIntlObjectOfType(this, 'collator')) {
- throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "Collator");
+ throw %make_type_error(kResolvedOptionsCalledOnNonObject, "Collator");
}
var coll = this;
@@ -1048,7 +1103,7 @@ InstallFunction(Intl.Collator.prototype, 'resolvedOptions', function() {
*/
InstallFunction(Intl.Collator, 'supportedLocalesOf', function(locales) {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
return supportedLocalesOf('collator', locales, arguments[1]);
@@ -1068,11 +1123,11 @@ InstallFunction(Intl.Collator, 'supportedLocalesOf', function(locales) {
*/
function compare(collator, x, y) {
return %InternalCompare(%GetImplFromInitializedIntlObject(collator),
- GlobalString(x), GlobalString(y));
+ TO_STRING(x), TO_STRING(y));
};
-AddBoundMethod(Intl.Collator, 'compare', compare, 2);
+AddBoundMethod(Intl.Collator, 'compare', compare, 2, 'collator');
/**
* Verifies that the input is a well-formed ISO 4217 currency code.
@@ -1092,9 +1147,9 @@ function isWellFormedCurrencyCode(currency) {
function getNumberOption(options, property, min, max, fallback) {
var value = options[property];
if (!IS_UNDEFINED(value)) {
- value = GlobalNumber(value);
- if (IsNaN(value) || value < min || value > max) {
- throw MakeRangeError(kPropertyValueOutOfRange, property);
+ value = TO_NUMBER(value);
+ if (NUMBER_IS_NAN(value) || value < min || value > max) {
+ throw %make_range_error(kPropertyValueOutOfRange, property);
}
return %math_floor(value);
}
@@ -1118,7 +1173,7 @@ var patternAccessor = {
*/
function initializeNumberFormat(numberFormat, locales, options) {
if (%IsInitializedIntlObject(numberFormat)) {
- throw MakeTypeError(kReinitializeIntl, "NumberFormat");
+ throw %make_type_error(kReinitializeIntl, "NumberFormat");
}
if (IS_UNDEFINED(options)) {
@@ -1135,11 +1190,11 @@ function initializeNumberFormat(numberFormat, locales, options) {
var currency = getOption('currency', 'string');
if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) {
- throw MakeRangeError(kInvalidCurrencyCode, currency);
+ throw %make_range_error(kInvalidCurrencyCode, currency);
}
if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) {
- throw MakeTypeError(kCurrencyCode);
+ throw %make_type_error(kCurrencyCode);
}
var currencyDisplay = getOption(
@@ -1198,7 +1253,7 @@ function initializeNumberFormat(numberFormat, locales, options) {
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
currency: {writable: true},
currencyDisplay: {writable: true},
locale: {writable: true},
@@ -1206,7 +1261,6 @@ function initializeNumberFormat(numberFormat, locales, options) {
minimumFractionDigits: {writable: true},
minimumIntegerDigits: {writable: true},
numberingSystem: {writable: true},
- pattern: patternAccessor,
requestedLocale: {value: requestedLocale, writable: true},
style: {value: internalOptions.style, writable: true},
useGrouping: {writable: true}
@@ -1222,13 +1276,16 @@ function initializeNumberFormat(numberFormat, locales, options) {
resolved);
if (internalOptions.style === 'currency') {
- ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
- writable: true});
+ %object_define_property(resolved, 'currencyDisplay',
+ {value: currencyDisplay, writable: true});
}
%MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
numberFormat[resolvedSymbol] = resolved;
- ObjectDefineProperty(numberFormat, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(resolved, 'pattern', patternAccessor);
+ %object_define_property(numberFormat, 'resolved', resolvedAccessor);
+ }
return numberFormat;
}
@@ -1259,11 +1316,11 @@ InstallConstructor(Intl, 'NumberFormat', function() {
*/
InstallFunction(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (!%IsInitializedIntlObjectOfType(this, 'numberformat')) {
- throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "NumberFormat");
+ throw %make_type_error(kResolvedOptionsCalledOnNonObject, "NumberFormat");
}
var format = this;
@@ -1309,7 +1366,7 @@ InstallFunction(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
*/
InstallFunction(Intl.NumberFormat, 'supportedLocalesOf', function(locales) {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
return supportedLocalesOf('numberformat', locales, arguments[1]);
@@ -1334,14 +1391,12 @@ function formatNumber(formatter, value) {
/**
* Returns a Number that represents string value that was passed in.
*/
-function parseNumber(formatter, value) {
+function IntlParseNumber(formatter, value) {
return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
- GlobalString(value));
+ TO_STRING(value));
}
-
-AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
-AddBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
+AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1, 'numberformat');
/**
* Returns a string that matches LDML representation of the options object.
@@ -1508,35 +1563,35 @@ function toDateTimeOptions(options, required, defaults) {
}
if (needsDefault && (defaults === 'date' || defaults === 'all')) {
- ObjectDefineProperty(options, 'year', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'month', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'day', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- }
-
- if (needsDefault && (defaults === 'time' || defaults === 'all')) {
- ObjectDefineProperty(options, 'hour', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'minute', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'second', {value: 'numeric',
+ %object_define_property(options, 'year', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'month', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'day', {value: 'numeric',
writable: true,
enumerable: true,
configurable: true});
}
+ if (needsDefault && (defaults === 'time' || defaults === 'all')) {
+ %object_define_property(options, 'hour', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'minute', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'second', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ }
+
return options;
}
@@ -1548,7 +1603,7 @@ function toDateTimeOptions(options, required, defaults) {
function initializeDateTimeFormat(dateFormat, locales, options) {
if (%IsInitializedIntlObject(dateFormat)) {
- throw MakeTypeError(kReinitializeIntl, "DateTimeFormat");
+ throw %make_type_error(kReinitializeIntl, "DateTimeFormat");
}
if (IS_UNDEFINED(options)) {
@@ -1592,7 +1647,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
calendar: {writable: true},
day: {writable: true},
era: {writable: true},
@@ -1603,7 +1658,6 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
month: {writable: true},
numberingSystem: {writable: true},
[patternSymbol]: {writable: true},
- pattern: patternAccessor,
requestedLocale: {value: requestedLocale, writable: true},
second: {writable: true},
timeZone: {writable: true},
@@ -1617,12 +1671,15 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
if (resolved.timeZone === "Etc/Unknown") {
- throw MakeRangeError(kUnsupportedTimeZone, tz);
+ throw %make_range_error(kUnsupportedTimeZone, tz);
}
%MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
dateFormat[resolvedSymbol] = resolved;
- ObjectDefineProperty(dateFormat, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(resolved, 'pattern', patternAccessor);
+ %object_define_property(dateFormat, 'resolved', resolvedAccessor);
+ }
return dateFormat;
}
@@ -1653,29 +1710,21 @@ InstallConstructor(Intl, 'DateTimeFormat', function() {
*/
InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (!%IsInitializedIntlObjectOfType(this, 'dateformat')) {
- throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "DateTimeFormat");
+ throw %make_type_error(kResolvedOptionsCalledOnNonObject, "DateTimeFormat");
}
/**
- * Maps ICU calendar names into LDML type.
+ * Maps ICU calendar names to LDML/BCP47 types for key 'ca'.
+ * See typeMap section in third_party/icu/source/data/misc/keyTypeData.txt
+ * and
+ * http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
*/
var ICU_CALENDAR_MAP = {
'gregorian': 'gregory',
- 'japanese': 'japanese',
- 'buddhist': 'buddhist',
- 'roc': 'roc',
- 'persian': 'persian',
- 'islamic-civil': 'islamicc',
- 'islamic': 'islamic',
- 'hebrew': 'hebrew',
- 'chinese': 'chinese',
- 'indian': 'indian',
- 'coptic': 'coptic',
- 'ethiopic': 'ethiopic',
'ethiopic-amete-alem': 'ethioaa'
};
@@ -1683,8 +1732,7 @@ InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
var fromPattern = fromLDMLString(format[resolvedSymbol][patternSymbol]);
var userCalendar = ICU_CALENDAR_MAP[format[resolvedSymbol].calendar];
if (IS_UNDEFINED(userCalendar)) {
- // Use ICU name if we don't have a match. It shouldn't happen, but
- // it would be too strict to throw for this.
+ // No match means that ICU's legacy name is identical to LDML/BCP type.
userCalendar = format[resolvedSymbol].calendar;
}
@@ -1722,7 +1770,7 @@ InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
*/
InstallFunction(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
return supportedLocalesOf('dateformat', locales, arguments[1]);
@@ -1743,7 +1791,7 @@ function formatDate(formatter, dateValue) {
dateMs = TO_NUMBER(dateValue);
}
- if (!IsFinite(dateMs)) throw MakeRangeError(kDateRange);
+ if (!NUMBER_IS_FINITE(dateMs)) throw %make_range_error(kDateRange);
return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
new GlobalDate(dateMs));
@@ -1756,15 +1804,14 @@ function formatDate(formatter, dateValue) {
* DateTimeFormat.
* Returns undefined if date string cannot be parsed.
*/
-function parseDate(formatter, value) {
+function IntlParseDate(formatter, value) {
return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
- GlobalString(value));
+ TO_STRING(value));
}
// 0 because date is optional argument.
-AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
-AddBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
+AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0, 'dateformat');
/**
@@ -1777,6 +1824,9 @@ function canonicalizeTimeZoneID(tzID) {
return tzID;
}
+ // Convert zone name to string.
+ tzID = TO_STRING(tzID);
+
// Special case handling (UTC, GMT).
var upperID = %StringToUpperCase(tzID);
if (upperID === 'UTC' || upperID === 'GMT' ||
@@ -1789,13 +1839,13 @@ function canonicalizeTimeZoneID(tzID) {
// We expect only _, '-' and / beside ASCII letters.
// All inputs should conform to Area/Location(/Location)* from now on.
var match = InternalRegExpMatch(GetTimezoneNameCheckRE(), tzID);
- if (IS_NULL(match)) throw MakeRangeError(kExpectedTimezoneID, tzID);
+ if (IS_NULL(match)) throw %make_range_error(kExpectedTimezoneID, tzID);
var result = toTitleCaseTimezoneLocation(match[1]) + '/' +
toTitleCaseTimezoneLocation(match[2]);
if (!IS_UNDEFINED(match[3]) && 3 < match.length) {
- var locations = %_Call(StringSplit, match[3], '/');
+ var locations = %StringSplit(match[3], '/', kMaxUint32);
// The 1st element is empty. Starts with i=1.
for (var i = 1; i < locations.length; i++) {
result = result + '/' + toTitleCaseTimezoneLocation(locations[i]);
@@ -1811,7 +1861,7 @@ function canonicalizeTimeZoneID(tzID) {
*/
function initializeBreakIterator(iterator, locales, options) {
if (%IsInitializedIntlObject(iterator)) {
- throw MakeTypeError(kReinitializeIntl, "v8BreakIterator");
+ throw %make_type_error(kReinitializeIntl, "v8BreakIterator");
}
if (IS_UNDEFINED(options)) {
@@ -1826,7 +1876,7 @@ function initializeBreakIterator(iterator, locales, options) {
'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
var locale = resolveLocale('breakiterator', locales, options);
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
requestedLocale: {value: locale.locale, writable: true},
type: {value: internalOptions.type, writable: true},
locale: {writable: true}
@@ -1839,7 +1889,9 @@ function initializeBreakIterator(iterator, locales, options) {
%MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
internalIterator);
iterator[resolvedSymbol] = resolved;
- ObjectDefineProperty(iterator, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(iterator, 'resolved', resolvedAccessor);
+ }
return iterator;
}
@@ -1871,11 +1923,11 @@ InstallConstructor(Intl, 'v8BreakIterator', function() {
InstallFunction(Intl.v8BreakIterator.prototype, 'resolvedOptions',
function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (!%IsInitializedIntlObjectOfType(this, 'breakiterator')) {
- throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "v8BreakIterator");
+ throw %make_type_error(kResolvedOptionsCalledOnNonObject, "v8BreakIterator");
}
var segmenter = this;
@@ -1900,7 +1952,7 @@ InstallFunction(Intl.v8BreakIterator.prototype, 'resolvedOptions',
InstallFunction(Intl.v8BreakIterator, 'supportedLocalesOf',
function(locales) {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
return supportedLocalesOf('breakiterator', locales, arguments[1]);
@@ -1914,7 +1966,7 @@ InstallFunction(Intl.v8BreakIterator, 'supportedLocalesOf',
*/
function adoptText(iterator, text) {
%BreakIteratorAdoptText(%GetImplFromInitializedIntlObject(iterator),
- GlobalString(text));
+ TO_STRING(text));
}
@@ -1950,11 +2002,13 @@ function breakType(iterator) {
}
-AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
-AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
+AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1,
+ 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0,
+ 'breakiterator');
// Save references to Intl objects and methods we use, for added security.
var savedObjects = {
@@ -1976,6 +2030,23 @@ var defaultObjects = {
'dateformattime': UNDEFINED,
};
+function clearDefaultObjects() {
+ defaultObjects['dateformatall'] = UNDEFINED;
+ defaultObjects['dateformatdate'] = UNDEFINED;
+ defaultObjects['dateformattime'] = UNDEFINED;
+}
+
+var date_cache_version = 0;
+
+function checkDateCacheCurrent() {
+ var new_date_cache_version = %DateCacheVersion();
+ if (new_date_cache_version == date_cache_version) {
+ return;
+ }
+ date_cache_version = new_date_cache_version;
+
+ clearDefaultObjects();
+}
/**
* Returns cached or newly created instance of a given service.
@@ -1984,6 +2055,7 @@ var defaultObjects = {
function cachedOrNewService(service, locales, options, defaults) {
var useOptions = (IS_UNDEFINED(defaults)) ? options : defaults;
if (IS_UNDEFINED(locales) && IS_UNDEFINED(options)) {
+ checkDateCacheCurrent();
if (IS_UNDEFINED(defaultObjects[service])) {
defaultObjects[service] = new savedObjects[service](locales, useOptions);
}
@@ -1992,17 +2064,48 @@ function cachedOrNewService(service, locales, options, defaults) {
return new savedObjects[service](locales, useOptions);
}
+function LocaleConvertCase(s, locales, isToUpper) {
+ // ECMA 402 section 13.1.2 steps 1 through 12.
+ var language;
+ // Optimize for the most common two cases. initializeLocaleList() can handle
+ // them as well, but it's rather slow accounting for over 60% of
+ // toLocale{U,L}Case() and about 40% of toLocale{U,L}Case("<locale>").
+ if (IS_UNDEFINED(locales)) {
+ language = GetDefaultICULocaleJS();
+ } else if (IS_STRING(locales)) {
+ language = canonicalizeLanguageTag(locales);
+ } else {
+ var locales = initializeLocaleList(locales);
+ language = locales.length > 0 ? locales[0] : GetDefaultICULocaleJS();
+ }
+
+ // StringSplit is slower than this.
+ var pos = %_Call(StringIndexOf, language, '-');
+ if (pos != -1) {
+ language = %_Call(StringSubstring, language, 0, pos);
+ }
+
+ var CUSTOM_CASE_LANGUAGES = ['az', 'el', 'lt', 'tr'];
+ var langIndex = %ArrayIndexOf(CUSTOM_CASE_LANGUAGES, language, 0);
+ if (langIndex == -1) {
+ // language-independent case conversion.
+ return isToUpper ? %StringToUpperCaseI18N(s) : %StringToLowerCaseI18N(s);
+ }
+ return %StringLocaleConvertCase(s, isToUpper,
+ CUSTOM_CASE_LANGUAGES[langIndex]);
+}
+
/**
* Compares this and that, and returns less than 0, 0 or greater than 0 value.
* Overrides the built-in method.
*/
OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (IS_NULL_OR_UNDEFINED(this)) {
- throw MakeTypeError(kMethodInvokedOnNullOrUndefined);
+ throw %make_type_error(kMethodInvokedOnNullOrUndefined);
}
var locales = arguments[1];
@@ -2023,7 +2126,7 @@ OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) {
OverrideFunction(GlobalString.prototype, 'normalize', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
@@ -2034,9 +2137,9 @@ OverrideFunction(GlobalString.prototype, 'normalize', function() {
var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
- var normalizationForm = %_Call(ArrayIndexOf, NORMALIZATION_FORMS, form);
+ var normalizationForm = %ArrayIndexOf(NORMALIZATION_FORMS, form, 0);
if (normalizationForm === -1) {
- throw MakeRangeError(kNormalizationForm,
+ throw %make_range_error(kNormalizationForm,
%_Call(ArrayJoin, NORMALIZATION_FORMS, ', '));
}
@@ -2044,6 +2147,56 @@ OverrideFunction(GlobalString.prototype, 'normalize', function() {
}
);
+function ToLowerCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
+ var s = TO_STRING(this);
+ return %StringToLowerCaseI18N(s);
+}
+
+function ToUpperCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toUpperCase");
+ var s = TO_STRING(this);
+ return %StringToUpperCaseI18N(s);
+}
+
+function ToLocaleLowerCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleLowerCase");
+ return LocaleConvertCase(TO_STRING(this), locales, false);
+}
+
+%FunctionSetLength(ToLocaleLowerCaseI18N, 0);
+
+function ToLocaleUpperCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleUpperCase");
+ return LocaleConvertCase(TO_STRING(this), locales, true);
+}
+
+%FunctionSetLength(ToLocaleUpperCaseI18N, 0);
+
+%FunctionRemovePrototype(ToLowerCaseI18N);
+%FunctionRemovePrototype(ToUpperCaseI18N);
+%FunctionRemovePrototype(ToLocaleLowerCaseI18N);
+%FunctionRemovePrototype(ToLocaleUpperCaseI18N);
+
+utils.Export(function(to) {
+ to.ToLowerCaseI18N = ToLowerCaseI18N;
+ to.ToUpperCaseI18N = ToUpperCaseI18N;
+ to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
+ to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
+});
+
/**
* Formats a Number object (this) using locale and options values.
@@ -2051,11 +2204,11 @@ OverrideFunction(GlobalString.prototype, 'normalize', function() {
*/
OverrideFunction(GlobalNumber.prototype, 'toLocaleString', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
if (!(this instanceof GlobalNumber) && typeof(this) !== 'number') {
- throw MakeTypeError(kMethodInvokedOnWrongType, "Number");
+ throw %make_type_error(kMethodInvokedOnWrongType, "Number");
}
var locales = arguments[0];
@@ -2071,7 +2224,7 @@ OverrideFunction(GlobalNumber.prototype, 'toLocaleString', function() {
*/
function toLocaleDateTime(date, locales, options, required, defaults, service) {
if (!(date instanceof GlobalDate)) {
- throw MakeTypeError(kMethodInvokedOnWrongType, "Date");
+ throw %make_type_error(kMethodInvokedOnWrongType, "Date");
}
if (IsNaN(date)) return 'Invalid Date';
@@ -2092,7 +2245,7 @@ function toLocaleDateTime(date, locales, options, required, defaults, service) {
*/
OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
var locales = arguments[0];
@@ -2110,7 +2263,7 @@ OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() {
*/
OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
var locales = arguments[0];
@@ -2128,7 +2281,7 @@ OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() {
*/
OverrideFunction(GlobalDate.prototype, 'toLocaleTimeString', function() {
if (!IS_UNDEFINED(new.target)) {
- throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
var locales = arguments[0];
@@ -2138,4 +2291,10 @@ OverrideFunction(GlobalDate.prototype, 'toLocaleTimeString', function() {
}
);
+utils.Export(function(to) {
+ to.AddBoundMethod = AddBoundMethod;
+ to.IntlParseDate = IntlParseDate;
+ to.IntlParseNumber = IntlParseNumber;
+});
+
})