Commit 41b3955f authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

Revert "[Intl] Move ToDateTimeOptions/ToLocaleDateTime to C++"

This reverts commit cabcfb3a.

Reason for revert: Breaks a layout test "fast/js/date-proto-generic-invocation.html" as can be seen in 
https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8-Blink%20Linux%2064/25626

Original change's description:
> [Intl] Move ToDateTimeOptions/ToLocaleDateTime to C++
> 
> Bug: v8:7961
> Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
> Change-Id: Ic414a51a64040f253da1d7ccf03c558ea70ad2bf
> Reviewed-on: https://chromium-review.googlesource.com/1155271
> Commit-Queue: Frank Tang <ftang@chromium.org>
> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#55199}

TBR=kadams@nvidia.com,jshin@chromium.org,gsathya@chromium.org,ftang@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: v8:7961
Change-Id: I39203fb281b9a54236b12a69c1f8389bcb5d411f
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/1183165Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55259}
parent fcfd995a
...@@ -1102,7 +1102,7 @@ function CreateDateTimeFormat(locales, options) { ...@@ -1102,7 +1102,7 @@ function CreateDateTimeFormat(locales, options) {
var locale = resolveLocale('dateformat', locales, options); var locale = resolveLocale('dateformat', locales, options);
options = %ToDateTimeOptions(options, 'any', 'date'); options = toDateTimeOptions(options, 'any', 'date');
var getOption = getGetOption(options, 'dateformat'); var getOption = getGetOption(options, 'dateformat');
...@@ -1510,6 +1510,26 @@ function cachedOrNewService(service, locales, options, defaults) { ...@@ -1510,6 +1510,26 @@ function cachedOrNewService(service, locales, options, defaults) {
"cached_or_new_service", cachedOrNewService "cached_or_new_service", cachedOrNewService
]); ]);
/**
* Returns actual formatted date or fails if date parameter is invalid.
*/
function toLocaleDateTime(date, locales, options, required, defaults, service) {
if (!(date instanceof GlobalDate)) {
throw %make_type_error(kMethodInvokedOnWrongType, "Date");
}
var dateValue = TO_NUMBER(date);
if (NUMBER_IS_NAN(dateValue)) return 'Invalid Date';
var internalOptions = toDateTimeOptions(options, required, defaults);
var dateFormat =
cachedOrNewService(service, locales, options, internalOptions);
return %FormatDate(dateFormat, date);
}
/** /**
* Formats a Date object (this) using locale and options values. * Formats a Date object (this) using locale and options values.
* If locale or options are omitted, defaults are used - both date and time are * If locale or options are omitted, defaults are used - both date and time are
...@@ -1520,7 +1540,7 @@ DEFINE_METHOD( ...@@ -1520,7 +1540,7 @@ DEFINE_METHOD(
toLocaleString() { toLocaleString() {
var locales = arguments[0]; var locales = arguments[0];
var options = arguments[1]; var options = arguments[1];
return %ToLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'any', 'all', 'dateformatall'); this, locales, options, 'any', 'all', 'dateformatall');
} }
); );
...@@ -1536,7 +1556,7 @@ DEFINE_METHOD( ...@@ -1536,7 +1556,7 @@ DEFINE_METHOD(
toLocaleDateString() { toLocaleDateString() {
var locales = arguments[0]; var locales = arguments[0];
var options = arguments[1]; var options = arguments[1];
return %ToLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'date', 'date', 'dateformatdate'); this, locales, options, 'date', 'date', 'dateformatdate');
} }
); );
...@@ -1552,7 +1572,7 @@ DEFINE_METHOD( ...@@ -1552,7 +1572,7 @@ DEFINE_METHOD(
toLocaleTimeString() { toLocaleTimeString() {
var locales = arguments[0]; var locales = arguments[0];
var options = arguments[1]; var options = arguments[1];
return %ToLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'time', 'time', 'dateformattime'); this, locales, options, 'time', 'time', 'dateformattime');
} }
); );
......
...@@ -1342,27 +1342,6 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor, ...@@ -1342,27 +1342,6 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
return result; return result;
} }
// 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
// Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
Handle<Object> prototype) {
// Generate the map with the specified {prototype} based on the Object
// function's initial map from the current native context.
// TODO(bmeurer): Use a dedicated cache for Object.create; think about
// slack tracking for Object.create.
Handle<Map> map =
Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
// Actually allocate the object.
Handle<JSObject> object;
if (map->is_dictionary_map()) {
object = isolate->factory()->NewSlowJSObjectFromMap(map);
} else {
object = isolate->factory()->NewJSObjectFromMap(map);
}
return object;
}
void JSObject::EnsureWritableFastElements(Handle<JSObject> object) { void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
DCHECK(object->HasSmiOrObjectElements() || DCHECK(object->HasSmiOrObjectElements() ||
object->HasFastStringWrapperElements()); object->HasFastStringWrapperElements());
......
...@@ -2235,11 +2235,6 @@ class JSObject: public JSReceiver { ...@@ -2235,11 +2235,6 @@ class JSObject: public JSReceiver {
static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object); static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
// 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
// Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
static V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> ObjectCreate(
Isolate* isolate, Handle<Object> prototype);
// [elements]: The elements (properties with names that are integers). // [elements]: The elements (properties with names that are integers).
// //
// Elements can be in two general modes: fast and slow. Each mode // Elements can be in two general modes: fast and slow. Each mode
......
...@@ -552,23 +552,6 @@ void SetResolvedBreakIteratorSettings(Isolate* isolate, ...@@ -552,23 +552,6 @@ void SetResolvedBreakIteratorSettings(Isolate* isolate,
.Assert(); .Assert();
} }
} }
MaybeHandle<JSObject> CachedOrNewService(Isolate* isolate,
Handle<String> service,
Handle<Object> locales,
Handle<Object> options,
Handle<Object> internal_options) {
Handle<Object> result;
Handle<Object> undefined_value(ReadOnlyRoots(isolate).undefined_value(),
isolate);
Handle<Object> args[] = {service, locales, options, internal_options};
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, isolate->cached_or_new_service(),
undefined_value, arraysize(args), args),
JSArray);
return Handle<JSObject>::cast(result);
}
} // namespace } // namespace
icu::Locale Intl::CreateICULocale(Isolate* isolate, icu::Locale Intl::CreateICULocale(Isolate* isolate,
...@@ -705,44 +688,6 @@ MaybeHandle<String> DateFormat::DateTimeFormat( ...@@ -705,44 +688,6 @@ MaybeHandle<String> DateFormat::DateTimeFormat(
return DateFormat::FormatDateTime(isolate, date_time_format_holder, x); return DateFormat::FormatDateTime(isolate, date_time_format_holder, x);
} }
MaybeHandle<String> DateFormat::ToLocaleDateTime(
Isolate* isolate, Handle<Object> date, Handle<Object> locales,
Handle<Object> options, const char* required, const char* defaults,
const char* service) {
Factory* factory = isolate->factory();
// 1. Let x be ? thisTimeValue(this value);
if (!date->IsJSDate()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
factory->NewStringFromStaticChars("date")),
String);
}
double const x = Handle<JSDate>::cast(date)->value()->Number();
// 2. If x is NaN, return "Invalid Date"
if (std::isnan(x)) {
return factory->NewStringFromStaticChars("Invalid Date");
}
// 3. Let options be ? ToDateTimeOptions(options, required, defaults).
Handle<JSObject> internal_options;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, internal_options,
DateFormat::ToDateTimeOptions(isolate, options, required, defaults),
String);
// 4. Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »).
Handle<JSObject> date_format;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, date_format,
CachedOrNewService(isolate, factory->NewStringFromAsciiChecked(service),
locales, options, internal_options),
String);
// 5. Return FormatDateTime(dateFormat, x).
return DateFormat::FormatDateTime(isolate, date_format, x);
}
icu::DecimalFormat* NumberFormat::InitializeNumberFormat( icu::DecimalFormat* NumberFormat::InitializeNumberFormat(
Isolate* isolate, Handle<String> locale, Handle<JSObject> options, Isolate* isolate, Handle<String> locale, Handle<JSObject> options,
Handle<JSObject> resolved) { Handle<JSObject> resolved) {
...@@ -894,110 +839,6 @@ bool Intl::RemoveLocaleScriptTag(const std::string& icu_locale, ...@@ -894,110 +839,6 @@ bool Intl::RemoveLocaleScriptTag(const std::string& icu_locale,
return true; return true;
} }
namespace {
Maybe<bool> IsPropertyUndefined(Isolate* isolate, Handle<JSObject> options,
const char* property) {
Factory* factory = isolate->factory();
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(
isolate, options, factory->NewStringFromAsciiChecked(property)),
Nothing<bool>());
return Just(value->IsUndefined(isolate));
}
} // namespace
// ecma-402/#sec-todatetimeoptions
MaybeHandle<JSObject> DateFormat::ToDateTimeOptions(
Isolate* isolate, Handle<Object> input_options, const char* required,
const char* defaults) {
Factory* factory = isolate->factory();
// 1. If options is undefined, let options be null; otherwise let options be ?
// ToObject(options).
Handle<JSObject> options;
if (input_options->IsUndefined(isolate)) {
options = factory->NewJSObjectWithNullProto();
} else {
Handle<JSReceiver> options_obj;
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
Object::ToObject(isolate, input_options),
JSObject);
// 2. Let options be ObjectCreate(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
JSObject::ObjectCreate(isolate, options_obj),
JSObject);
}
// 3. Let needDefaults be true.
bool needs_default = true;
bool required_is_any = strcmp(required, "any") == 0;
// 4. If required is "date" or "any", then
if (required_is_any || (strcmp(required, "date") == 0)) {
// a. For each of the property names "weekday", "year", "month", "day", do
for (auto& prop : {"weekday", "year", "month", "day"}) {
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop)
Maybe<bool> maybe_undefined = IsPropertyUndefined(isolate, options, prop);
MAYBE_RETURN(maybe_undefined, Handle<JSObject>());
// iii. If value is not undefined, let needDefaults be false.
if (!maybe_undefined.FromJust()) {
needs_default = false;
}
}
}
// 5. If required is "time" or "any", then
if (required_is_any || (strcmp(required, "time") == 0)) {
// a. For each of the property names "hour", "minute", "second", do
for (auto& prop : {"hour", "minute", "second"}) {
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop)
Maybe<bool> maybe_undefined = IsPropertyUndefined(isolate, options, prop);
MAYBE_RETURN(maybe_undefined, Handle<JSObject>());
// iii. If value is not undefined, let needDefaults be false.
if (!maybe_undefined.FromJust()) {
needs_default = false;
}
}
}
// 6. If needDefaults is true and defaults is either "date" or "all", then
if (needs_default) {
bool default_is_all = strcmp(defaults, "all") == 0;
if (default_is_all || (strcmp(defaults, "date") == 0)) {
// a. For each of the property names "year", "month", "day", do
// i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
for (auto& prop : {"year", "month", "day"}) {
MAYBE_RETURN(
JSReceiver::CreateDataProperty(
isolate, options, factory->NewStringFromAsciiChecked(prop),
factory->numeric_string(), kThrowOnError),
Handle<JSObject>());
}
}
// 7. If needDefaults is true and defaults is either "time" or "all", then
if (default_is_all || (strcmp(defaults, "time") == 0)) {
// a. For each of the property names "hour", "minute", "second", do
// i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
for (auto& prop : {"hour", "minute", "second"}) {
MAYBE_RETURN(
JSReceiver::CreateDataProperty(
isolate, options, factory->NewStringFromAsciiChecked(prop),
factory->numeric_string(), kThrowOnError),
Handle<JSObject>());
}
}
}
// 8. Return options.
return options;
}
std::set<std::string> Intl::GetAvailableLocales(const IcuService& service) { std::set<std::string> Intl::GetAvailableLocales(const IcuService& service) {
const icu::Locale* icu_available_locales = nullptr; const icu::Locale* icu_available_locales = nullptr;
int32_t count = 0; int32_t count = 0;
...@@ -1915,6 +1756,28 @@ bool IsAToZ(char ch) { ...@@ -1915,6 +1756,28 @@ bool IsAToZ(char ch) {
return IsInRange(AsciiAlphaToLower(ch), 'a', 'z'); return IsInRange(AsciiAlphaToLower(ch), 'a', 'z');
} }
// The following are temporary function calling back into js code in
// src/js/intl.js to call pre-existing functions until they are all moved to C++
// under src/objects/*.
// TODO(ftang): remove these temp function after bstell move them from js into
// C++
MaybeHandle<JSObject> CachedOrNewService(Isolate* isolate,
Handle<String> service,
Handle<Object> locales,
Handle<Object> options) {
Handle<Object> result;
Handle<Object> undefined_value(ReadOnlyRoots(isolate).undefined_value(),
isolate);
Handle<Object> args[] = {service, locales, options};
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, isolate->cached_or_new_service(),
undefined_value, arraysize(args), args),
JSArray);
return Handle<JSObject>::cast(result);
}
} // namespace } // namespace
// Verifies that the input is a well-formed ISO 4217 currency code. // Verifies that the input is a well-formed ISO 4217 currency code.
...@@ -1989,7 +1852,7 @@ MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate, ...@@ -1989,7 +1852,7 @@ MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate,
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, collator, isolate, collator,
CachedOrNewService(isolate, factory->NewStringFromStaticChars("collator"), CachedOrNewService(isolate, factory->NewStringFromStaticChars("collator"),
locales, options, factory->undefined_value()), locales, options),
Object); Object);
CHECK(collator->IsJSCollator()); CHECK(collator->IsJSCollator());
return Intl::CompareStrings(isolate, Handle<JSCollator>::cast(collator), return Intl::CompareStrings(isolate, Handle<JSCollator>::cast(collator),
...@@ -2041,7 +1904,7 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, ...@@ -2041,7 +1904,7 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
isolate, number_format_holder, isolate, number_format_holder,
CachedOrNewService(isolate, CachedOrNewService(isolate,
factory->NewStringFromStaticChars("numberformat"), factory->NewStringFromStaticChars("numberformat"),
locales, options, factory->undefined_value()), locales, options),
String); String);
DCHECK( DCHECK(
Intl::IsObjectOfType(isolate, number_format_holder, Intl::kNumberFormat)); Intl::IsObjectOfType(isolate, number_format_holder, Intl::kNumberFormat));
......
...@@ -68,16 +68,6 @@ class DateFormat { ...@@ -68,16 +68,6 @@ class DateFormat {
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> Unwrap( V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> Unwrap(
Isolate* isolate, Handle<JSReceiver> receiver, const char* method_name); Isolate* isolate, Handle<JSReceiver> receiver, const char* method_name);
// ecma-402/#sec-todatetimeoptions
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ToDateTimeOptions(
Isolate* isolate, Handle<Object> input_options, const char* required,
const char* defaults);
V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToLocaleDateTime(
Isolate* isolate, Handle<Object> date, Handle<Object> locales,
Handle<Object> options, const char* required, const char* defaults,
const char* service);
// Layout description. // Layout description.
#define DATE_FORMAT_FIELDS(V) \ #define DATE_FORMAT_FIELDS(V) \
V(kSimpleDateFormat, kPointerSize) \ V(kSimpleDateFormat, kPointerSize) \
......
...@@ -487,36 +487,6 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) { ...@@ -487,36 +487,6 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
} }
} }
RUNTIME_FUNCTION(Runtime_ToLocaleDateTime) {
HandleScope scope(isolate);
DCHECK_EQ(6, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, date, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, locales, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, options, 2);
CONVERT_ARG_HANDLE_CHECKED(String, required, 3);
CONVERT_ARG_HANDLE_CHECKED(String, defaults, 4);
CONVERT_ARG_HANDLE_CHECKED(String, service, 5);
RETURN_RESULT_OR_FAILURE(
isolate, DateFormat::ToLocaleDateTime(
isolate, date, locales, options, required->ToCString().get(),
defaults->ToCString().get(), service->ToCString().get()));
}
RUNTIME_FUNCTION(Runtime_ToDateTimeOptions) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 3);
CONVERT_ARG_HANDLE_CHECKED(Object, options, 0);
CONVERT_ARG_HANDLE_CHECKED(String, required, 1);
CONVERT_ARG_HANDLE_CHECKED(String, defaults, 2);
RETURN_RESULT_OR_FAILURE(
isolate, DateFormat::ToDateTimeOptions(isolate, options,
required->ToCString().get(),
defaults->ToCString().get()));
}
RUNTIME_FUNCTION(Runtime_StringToLowerCaseIntl) { RUNTIME_FUNCTION(Runtime_StringToLowerCaseIntl) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(args.length(), 1); DCHECK_EQ(args.length(), 1);
......
...@@ -405,26 +405,34 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) { ...@@ -405,26 +405,34 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
RUNTIME_FUNCTION(Runtime_ObjectCreate) { RUNTIME_FUNCTION(Runtime_ObjectCreate) {
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> prototype = args.at(0); Handle<Object> prototype = args.at(0);
Handle<Object> properties = args.at(1);
Handle<JSObject> obj;
// 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
} }
// 2. Let obj be ObjectCreate(O).
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, obj, JSObject::ObjectCreate(isolate, prototype));
// 3. If Properties is not undefined, then // Generate the map with the specified {prototype} based on the Object
if (!properties->IsUndefined(isolate)) { // function's initial map from the current native context.
// a. Return ? ObjectDefineProperties(obj, Properties). // TODO(bmeurer): Use a dedicated cache for Object.create; think about
// slack tracking for Object.create.
Handle<Map> map =
Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
// Actually allocate the object.
Handle<JSObject> object;
if (map->is_dictionary_map()) {
object = isolate->factory()->NewSlowJSObjectFromMap(map);
} else {
object = isolate->factory()->NewJSObjectFromMap(map);
}
// Define the properties if properties was specified and is not undefined. // Define the properties if properties was specified and is not undefined.
RETURN_RESULT_OR_FAILURE( Handle<Object> properties = args.at(1);
isolate, JSReceiver::DefineProperties(isolate, obj, properties)); if (!properties->IsUndefined(isolate)) {
RETURN_FAILURE_ON_EXCEPTION(
isolate, JSReceiver::DefineProperties(isolate, object, properties));
} }
// 4. Return obj.
return *obj; return *object;
} }
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
......
...@@ -229,8 +229,6 @@ namespace internal { ...@@ -229,8 +229,6 @@ namespace internal {
F(ParseExtension, 1, 1) \ F(ParseExtension, 1, 1) \
F(PluralRulesResolvedOptions, 1, 1) \ F(PluralRulesResolvedOptions, 1, 1) \
F(PluralRulesSelect, 2, 1) \ F(PluralRulesSelect, 2, 1) \
F(ToDateTimeOptions, 3, 1) \
F(ToLocaleDateTime, 6, 1) \
F(StringToLowerCaseIntl, 1, 1) \ F(StringToLowerCaseIntl, 1, 1) \
F(StringToUpperCaseIntl, 1, 1) \ F(StringToUpperCaseIntl, 1, 1) \
F(SupportedLocalesOf, 3, 1) \ F(SupportedLocalesOf, 3, 1) \
......
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