Commit e0359c36 authored by littledan's avatar littledan Committed by Commit bot

[intl] Create the Intl constructors to C++

This patch moves the creation of the Intl constructors from JavaScript
to C++ in bootstrapper.cc, to match all of the other builtins exposed
to the web.

BUG=v8:5751

Review-Url: https://codereview.chromium.org/2586763002
Cr-Commit-Position: refs/heads/master@{#41959}
parent d20c23cd
...@@ -2326,6 +2326,74 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -2326,6 +2326,74 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
} }
#ifdef V8_I18N_SUPPORT
{ // -- I n t l
Handle<String> name = factory->InternalizeUtf8String("Intl");
Handle<JSFunction> cons = factory->NewFunction(name);
JSFunction::SetInstancePrototype(
cons,
Handle<Object>(native_context()->initial_object_prototype(), isolate));
Handle<JSObject> intl = factory->NewJSObject(cons, TENURED);
DCHECK(intl->IsJSObject());
JSObject::AddProperty(global, name, intl, DONT_ENUM);
Handle<JSObject> date_time_format_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(
date_time_format_prototype, factory->to_string_tag_symbol(),
factory->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> date_time_format_constructor = InstallFunction(
intl, "DateTimeFormat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
date_time_format_prototype, Builtins::kIllegal);
JSObject::AddProperty(date_time_format_prototype,
factory->constructor_string(),
date_time_format_constructor, DONT_ENUM);
Handle<JSObject> number_format_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(
number_format_prototype, factory->to_string_tag_symbol(),
factory->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> number_format_constructor = InstallFunction(
intl, "NumberFormat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
number_format_prototype, Builtins::kIllegal);
JSObject::AddProperty(number_format_prototype,
factory->constructor_string(),
number_format_constructor, DONT_ENUM);
Handle<JSObject> collator_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(
collator_prototype, factory->to_string_tag_symbol(),
factory->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> collator_constructor =
InstallFunction(intl, "Collator", JS_OBJECT_TYPE, JSObject::kHeaderSize,
collator_prototype, Builtins::kIllegal);
JSObject::AddProperty(collator_prototype, factory->constructor_string(),
collator_constructor, DONT_ENUM);
Handle<JSObject> v8_break_iterator_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(
v8_break_iterator_prototype, factory->to_string_tag_symbol(),
factory->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> v8_break_iterator_constructor = InstallFunction(
intl, "v8BreakIterator", JS_OBJECT_TYPE, JSObject::kHeaderSize,
v8_break_iterator_prototype, Builtins::kIllegal);
JSObject::AddProperty(v8_break_iterator_prototype,
factory->constructor_string(),
v8_break_iterator_constructor, DONT_ENUM);
}
#endif // V8_I18N_SUPPORT
{ // -- A r r a y B u f f e r { // -- A r r a y B u f f e r
Handle<JSFunction> array_buffer_fun = InstallArrayBuffer( Handle<JSFunction> array_buffer_fun = InstallArrayBuffer(
global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength, global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength,
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
var ArrayJoin; var ArrayJoin;
var ArrayPush; var ArrayPush;
var GlobalDate = global.Date; var GlobalDate = global.Date;
var GlobalIntl = global.Intl;
var GlobalIntlDateTimeFormat = GlobalIntl.DateTimeFormat;
var GlobalIntlNumberFormat = GlobalIntl.NumberFormat;
var GlobalIntlCollator = GlobalIntl.Collator;
var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator;
var GlobalNumber = global.Number; var GlobalNumber = global.Number;
var GlobalRegExp = global.RegExp; var GlobalRegExp = global.RegExp;
var GlobalString = global.String; var GlobalString = global.String;
...@@ -47,14 +52,6 @@ function InstallFunction(object, name, func) { ...@@ -47,14 +52,6 @@ function InstallFunction(object, name, func) {
} }
function InstallConstructor(object, name, func) {
%CheckIsBootstrapping();
SetFunctionName(func, name);
%AddNamedProperty(object, name, func, DONT_ENUM);
%SetNativeFlag(func);
%ToFastProperties(object);
}
/** /**
* Adds bound method to the prototype of the given object. * Adds bound method to the prototype of the given object.
*/ */
...@@ -138,10 +135,6 @@ function Unwrap(receiver, typename, constructor, method, compat) { ...@@ -138,10 +135,6 @@ function Unwrap(receiver, typename, constructor, method, compat) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
var Intl = {};
%AddNamedProperty(global, "Intl", Intl, DONT_ENUM);
/** /**
* Caches available locales for each service. * Caches available locales for each service.
*/ */
...@@ -948,7 +941,7 @@ var resolvedAccessor = { ...@@ -948,7 +941,7 @@ var resolvedAccessor = {
}; };
// ECMA 402 section 8.2.1 // ECMA 402 section 8.2.1
InstallFunction(Intl, 'getCanonicalLocales', function(locales) { InstallFunction(GlobalIntl, 'getCanonicalLocales', function(locales) {
return makeArray(canonicalizeLocaleList(locales)); return makeArray(canonicalizeLocaleList(locales));
} }
); );
...@@ -1066,18 +1059,19 @@ function initializeCollator(collator, locales, options) { ...@@ -1066,18 +1059,19 @@ function initializeCollator(collator, locales, options) {
* *
* @constructor * @constructor
*/ */
function Collator() { function CollatorConstructor() {
return IntlConstruct(this, Collator, initializeCollator, new.target, return IntlConstruct(this, GlobalIntlCollator, initializeCollator, new.target,
arguments); arguments);
} }
InstallConstructor(Intl, 'Collator', Collator); %SetCode(GlobalIntlCollator, CollatorConstructor);
/** /**
* Collator resolvedOptions method. * Collator resolvedOptions method.
*/ */
InstallFunction(Intl.Collator.prototype, 'resolvedOptions', function() { InstallFunction(GlobalIntlCollator.prototype, 'resolvedOptions', function() {
var coll = Unwrap(this, 'collator', Collator, 'resolvedOptions', false); var coll = Unwrap(this, 'collator', GlobalIntlCollator, 'resolvedOptions',
false);
var locale = getOptimalLanguageTag(coll[resolvedSymbol].requestedLocale, var locale = getOptimalLanguageTag(coll[resolvedSymbol].requestedLocale,
coll[resolvedSymbol].locale); coll[resolvedSymbol].locale);
...@@ -1100,7 +1094,7 @@ InstallFunction(Intl.Collator.prototype, 'resolvedOptions', function() { ...@@ -1100,7 +1094,7 @@ InstallFunction(Intl.Collator.prototype, 'resolvedOptions', function() {
* order in the returned list as in the input list. * order in the returned list as in the input list.
* Options are optional parameter. * Options are optional parameter.
*/ */
InstallFunction(Intl.Collator, 'supportedLocalesOf', function(locales) { InstallFunction(GlobalIntlCollator, 'supportedLocalesOf', function(locales) {
return supportedLocalesOf('collator', locales, arguments[1]); return supportedLocalesOf('collator', locales, arguments[1]);
} }
); );
...@@ -1122,7 +1116,7 @@ function compare(collator, x, y) { ...@@ -1122,7 +1116,7 @@ function compare(collator, x, y) {
}; };
AddBoundMethod(Intl.Collator, 'compare', compare, 2, 'collator', false); AddBoundMethod(GlobalIntlCollator, 'compare', compare, 2, 'collator', false);
/** /**
* Verifies that the input is a well-formed ISO 4217 currency code. * Verifies that the input is a well-formed ISO 4217 currency code.
...@@ -1288,18 +1282,19 @@ function initializeNumberFormat(numberFormat, locales, options) { ...@@ -1288,18 +1282,19 @@ function initializeNumberFormat(numberFormat, locales, options) {
* *
* @constructor * @constructor
*/ */
function NumberFormat() { function NumberFormatConstructor() {
return IntlConstruct(this, NumberFormat, initializeNumberFormat, new.target, return IntlConstruct(this, GlobalIntlNumberFormat, initializeNumberFormat,
arguments, true); new.target, arguments, true);
} }
InstallConstructor(Intl, 'NumberFormat', NumberFormat); %SetCode(GlobalIntlNumberFormat, NumberFormatConstructor);
/** /**
* NumberFormat resolvedOptions method. * NumberFormat resolvedOptions method.
*/ */
InstallFunction(Intl.NumberFormat.prototype, 'resolvedOptions', function() { InstallFunction(GlobalIntlNumberFormat.prototype, 'resolvedOptions',
var format = Unwrap(this, 'numberformat', NumberFormat, function() {
var format = Unwrap(this, 'numberformat', GlobalIntlNumberFormat,
'resolvedOptions', true); 'resolvedOptions', true);
var locale = getOptimalLanguageTag(format[resolvedSymbol].requestedLocale, var locale = getOptimalLanguageTag(format[resolvedSymbol].requestedLocale,
format[resolvedSymbol].locale); format[resolvedSymbol].locale);
...@@ -1341,7 +1336,8 @@ InstallFunction(Intl.NumberFormat.prototype, 'resolvedOptions', function() { ...@@ -1341,7 +1336,8 @@ InstallFunction(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
* order in the returned list as in the input list. * order in the returned list as in the input list.
* Options are optional parameter. * Options are optional parameter.
*/ */
InstallFunction(Intl.NumberFormat, 'supportedLocalesOf', function(locales) { InstallFunction(GlobalIntlNumberFormat, 'supportedLocalesOf',
function(locales) {
return supportedLocalesOf('numberformat', locales, arguments[1]); return supportedLocalesOf('numberformat', locales, arguments[1]);
} }
); );
...@@ -1361,8 +1357,8 @@ function formatNumber(formatter, value) { ...@@ -1361,8 +1357,8 @@ function formatNumber(formatter, value) {
} }
AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1, 'numberformat', AddBoundMethod(GlobalIntlNumberFormat, 'format', formatNumber, 1,
true); 'numberformat', true);
/** /**
* Returns a string that matches LDML representation of the options object. * Returns a string that matches LDML representation of the options object.
...@@ -1655,18 +1651,19 @@ function initializeDateTimeFormat(dateFormat, locales, options) { ...@@ -1655,18 +1651,19 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
* *
* @constructor * @constructor
*/ */
function DateTimeFormat() { function DateTimeFormatConstructor() {
return IntlConstruct(this, DateTimeFormat, initializeDateTimeFormat, return IntlConstruct(this, GlobalIntlDateTimeFormat, initializeDateTimeFormat,
new.target, arguments, true); new.target, arguments, true);
} }
InstallConstructor(Intl, 'DateTimeFormat', DateTimeFormat); %SetCode(GlobalIntlDateTimeFormat, DateTimeFormatConstructor);
/** /**
* DateTimeFormat resolvedOptions method. * DateTimeFormat resolvedOptions method.
*/ */
InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() { InstallFunction(GlobalIntlDateTimeFormat.prototype, 'resolvedOptions',
var format = Unwrap(this, 'dateformat', DateTimeFormat, function() {
var format = Unwrap(this, 'dateformat', GlobalIntlDateTimeFormat,
'resolvedOptions', true); 'resolvedOptions', true);
/** /**
...@@ -1719,7 +1716,8 @@ InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() { ...@@ -1719,7 +1716,8 @@ InstallFunction(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
* order in the returned list as in the input list. * order in the returned list as in the input list.
* Options are optional parameter. * Options are optional parameter.
*/ */
InstallFunction(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) { InstallFunction(GlobalIntlDateTimeFormat, 'supportedLocalesOf',
function(locales) {
return supportedLocalesOf('dateformat', locales, arguments[1]); return supportedLocalesOf('dateformat', locales, arguments[1]);
} }
); );
...@@ -1766,7 +1764,7 @@ function FormatDateToParts(dateValue) { ...@@ -1766,7 +1764,7 @@ function FormatDateToParts(dateValue) {
// 0 because date is optional argument. // 0 because date is optional argument.
AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0, 'dateformat', AddBoundMethod(GlobalIntlDateTimeFormat, 'format', formatDate, 0, 'dateformat',
true); true);
...@@ -1856,23 +1854,23 @@ function initializeBreakIterator(iterator, locales, options) { ...@@ -1856,23 +1854,23 @@ function initializeBreakIterator(iterator, locales, options) {
* *
* @constructor * @constructor
*/ */
function v8BreakIterator() { function v8BreakIteratorConstructor() {
return IntlConstruct(this, v8BreakIterator, initializeBreakIterator, return IntlConstruct(this, GlobalIntlv8BreakIterator, initializeBreakIterator,
new.target, arguments); new.target, arguments);
} }
InstallConstructor(Intl, 'v8BreakIterator', v8BreakIterator); %SetCode(GlobalIntlv8BreakIterator, v8BreakIteratorConstructor);
/** /**
* BreakIterator resolvedOptions method. * BreakIterator resolvedOptions method.
*/ */
InstallFunction(Intl.v8BreakIterator.prototype, 'resolvedOptions', InstallFunction(GlobalIntlv8BreakIterator.prototype, 'resolvedOptions',
function() { function() {
if (!IS_UNDEFINED(new.target)) { if (!IS_UNDEFINED(new.target)) {
throw %make_type_error(kOrdinaryFunctionCalledAsConstructor); throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
} }
var segmenter = Unwrap(this, 'breakiterator', v8BreakIterator, var segmenter = Unwrap(this, 'breakiterator', GlobalIntlv8BreakIterator,
'resolvedOptions', false); 'resolvedOptions', false);
var locale = var locale =
...@@ -1893,7 +1891,7 @@ InstallFunction(Intl.v8BreakIterator.prototype, 'resolvedOptions', ...@@ -1893,7 +1891,7 @@ InstallFunction(Intl.v8BreakIterator.prototype, 'resolvedOptions',
* order in the returned list as in the input list. * order in the returned list as in the input list.
* Options are optional parameter. * Options are optional parameter.
*/ */
InstallFunction(Intl.v8BreakIterator, 'supportedLocalesOf', InstallFunction(GlobalIntlv8BreakIterator, 'supportedLocalesOf',
function(locales) { function(locales) {
if (!IS_UNDEFINED(new.target)) { if (!IS_UNDEFINED(new.target)) {
throw %make_type_error(kOrdinaryFunctionCalledAsConstructor); throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
...@@ -1946,21 +1944,22 @@ function breakType(iterator) { ...@@ -1946,21 +1944,22 @@ function breakType(iterator) {
} }
AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1, AddBoundMethod(GlobalIntlv8BreakIterator, 'adoptText', adoptText, 1,
'breakiterator');
AddBoundMethod(GlobalIntlv8BreakIterator, 'first', first, 0, 'breakiterator');
AddBoundMethod(GlobalIntlv8BreakIterator, 'next', next, 0, 'breakiterator');
AddBoundMethod(GlobalIntlv8BreakIterator, 'current', current, 0,
'breakiterator'); 'breakiterator');
AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0, 'breakiterator'); AddBoundMethod(GlobalIntlv8BreakIterator, 'breakType', breakType, 0,
AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0, 'breakiterator');
AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0, 'breakiterator');
AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0,
'breakiterator'); 'breakiterator');
// Save references to Intl objects and methods we use, for added security. // Save references to Intl objects and methods we use, for added security.
var savedObjects = { var savedObjects = {
'collator': Intl.Collator, 'collator': GlobalIntlCollator,
'numberformat': Intl.NumberFormat, 'numberformat': GlobalIntlNumberFormat,
'dateformatall': Intl.DateTimeFormat, 'dateformatall': GlobalIntlDateTimeFormat,
'dateformatdate': Intl.DateTimeFormat, 'dateformatdate': GlobalIntlDateTimeFormat,
'dateformattime': Intl.DateTimeFormat 'dateformattime': GlobalIntlDateTimeFormat
}; };
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let descriptor;
descriptor = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype,
Symbol.toStringTag);
assertEquals("Object", descriptor.value);
assertFalse(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
descriptor = Object.getOwnPropertyDescriptor(Intl.NumberFormat.prototype,
Symbol.toStringTag);
assertEquals("Object", descriptor.value);
assertFalse(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
descriptor = Object.getOwnPropertyDescriptor(Intl.Collator.prototype,
Symbol.toStringTag);
assertEquals("Object", descriptor.value);
assertFalse(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment