Commit 41db90b0 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Move most functions from DateFormat to JSDateTimeFormat

Move Unwrap,FormatDateTime,DateTimeFormat,ToDateTimeOptions,ToLocaleDateTime to JSDateTimeFormat

Bug: v8:8066
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng;luci.chromium.try:linux_chromium_rel_ng
Change-Id: I4d83cc96ea280ab8f77df5a431b877b76b05f1ac
Reviewed-on: https://chromium-review.googlesource.com/1198142
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarJungshik Shin <jshin@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55626}
parent d7ae63e6
......@@ -12,6 +12,7 @@
#include "src/objects-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/intl-objects.h"
#include "src/objects/js-date-time-format.h"
#endif
namespace v8 {
......@@ -843,45 +844,45 @@ BUILTIN(DatePrototypeToTimeString) {
BUILTIN(DatePrototypeToLocaleDateString) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleDateString");
RETURN_RESULT_OR_FAILURE(
isolate,
DateFormat::ToLocaleDateTime(isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"date", // required
"date", // defaults
"dateformatdate")); // service
RETURN_RESULT_OR_FAILURE(isolate,
JSDateTimeFormat::ToLocaleDateTime(
isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"date", // required
"date", // defaults
"dateformatdate")); // service
}
// ecma402 #sup-date.prototype.tolocalestring
BUILTIN(DatePrototypeToLocaleString) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleString");
RETURN_RESULT_OR_FAILURE(
isolate,
DateFormat::ToLocaleDateTime(isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"any", // required
"all", // defaults
"dateformatall")); // service
RETURN_RESULT_OR_FAILURE(isolate,
JSDateTimeFormat::ToLocaleDateTime(
isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"any", // required
"all", // defaults
"dateformatall")); // service
}
// ecma402 #sup-date.prototype.tolocaletimestring
BUILTIN(DatePrototypeToLocaleTimeString) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleTimeString");
RETURN_RESULT_OR_FAILURE(
isolate,
DateFormat::ToLocaleDateTime(isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"time", // required
"time", // defaults
"dateformattime")); // service
RETURN_RESULT_OR_FAILURE(isolate,
JSDateTimeFormat::ToLocaleDateTime(
isolate,
date, // date
args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options
"time", // required
"time", // defaults
"dateformattime")); // service
}
#endif // V8_INTL_SUPPORT
......
......@@ -20,6 +20,7 @@
#include "src/objects/intl-objects.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collator-inl.h"
#include "src/objects/js-date-time-format-inl.h"
#include "src/objects/js-list-format-inl.h"
#include "src/objects/js-locale-inl.h"
#include "src/objects/js-number-format-inl.h"
......@@ -725,7 +726,7 @@ BUILTIN(DateTimeFormatPrototypeFormat) {
Handle<JSObject> date_format_holder;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, date_format_holder,
DateFormat::Unwrap(isolate, receiver, method));
JSDateTimeFormat::Unwrap(isolate, receiver, method));
DCHECK(Intl::IsObjectOfType(isolate, date_format_holder,
Intl::Type::kDateTimeFormat));
......@@ -768,8 +769,8 @@ BUILTIN(DateTimeFormatInternalFormat) {
Handle<Object> date = args.atOrUndefined(isolate, 1);
RETURN_RESULT_OR_FAILURE(
isolate, DateFormat::DateTimeFormat(isolate, date_format_holder, date));
RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::DateTimeFormat(
isolate, date_format_holder, date));
}
BUILTIN(ListFormatConstructor) {
......
......@@ -277,11 +277,11 @@ void SetResolvedBreakIteratorSettings(Isolate* isolate,
}
}
MaybeHandle<JSObject> CachedOrNewService(Isolate* isolate,
Handle<String> service,
Handle<Object> locales,
Handle<Object> options,
Handle<Object> internal_options) {
} // namespace
MaybeHandle<JSObject> Intl::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);
......@@ -294,8 +294,6 @@ MaybeHandle<JSObject> CachedOrNewService(Isolate* isolate,
return Handle<JSObject>::cast(result);
}
} // namespace
icu::Locale Intl::CreateICULocale(Isolate* isolate,
Handle<String> bcp47_locale_str) {
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
......@@ -380,110 +378,6 @@ void DateFormat::DeleteDateFormat(const v8::WeakCallbackInfo<void>& data) {
GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter()));
}
MaybeHandle<JSObject> DateFormat::Unwrap(Isolate* isolate,
Handle<JSReceiver> receiver,
const char* method_name) {
Handle<Context> native_context =
Handle<Context>(isolate->context()->native_context(), isolate);
Handle<JSFunction> constructor = Handle<JSFunction>(
JSFunction::cast(native_context->intl_date_time_format_function()),
isolate);
Handle<String> method_name_str =
isolate->factory()->NewStringFromAsciiChecked(method_name);
return Intl::UnwrapReceiver(isolate, receiver, constructor,
Intl::Type::kDateTimeFormat, method_name_str,
true);
}
// ecma402/#sec-formatdatetime
// FormatDateTime( dateTimeFormat, x )
MaybeHandle<String> DateFormat::FormatDateTime(
Isolate* isolate, Handle<JSObject> date_time_format_holder, double x) {
double date_value = DateCache::TimeClip(x);
if (std::isnan(date_value)) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidTimeValue),
String);
}
CHECK(Intl::IsObjectOfType(isolate, date_time_format_holder,
Intl::Type::kDateTimeFormat));
icu::SimpleDateFormat* date_format =
DateFormat::UnpackDateFormat(date_time_format_holder);
CHECK_NOT_NULL(date_format);
icu::UnicodeString result;
date_format->format(date_value, result);
return isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length()));
}
// ecma402/#sec-datetime-format-functions
// DateTime Format Functions
MaybeHandle<String> DateFormat::DateTimeFormat(
Isolate* isolate, Handle<JSObject> date_time_format_holder,
Handle<Object> date) {
// 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]]
// internal slot.
DCHECK(Intl::IsObjectOfType(isolate, date_time_format_holder,
Intl::Type::kDateTimeFormat));
// 3. If date is not provided or is undefined, then
double x;
if (date->IsUndefined()) {
// 3.a Let x be Call(%Date_now%, undefined).
x = JSDate::CurrentTimeValue(isolate);
} else {
// 4. Else,
// a. Let x be ? ToNumber(date).
ASSIGN_RETURN_ON_EXCEPTION(isolate, date, Object::ToNumber(isolate, date),
String);
CHECK(date->IsNumber());
x = date->Number();
}
// 5. Return FormatDateTime(dtf, 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::BreakIterator* V8BreakIterator::InitializeBreakIterator(
Isolate* isolate, Handle<String> locale, Handle<JSObject> options,
Handle<JSObject> resolved) {
......@@ -622,110 +516,6 @@ bool Intl::RemoveLocaleScriptTag(const std::string& icu_locale,
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) {
const icu::Locale* icu_available_locales = nullptr;
int32_t count = 0;
......
......@@ -47,36 +47,7 @@ class DateFormat {
// holds the pointer gets garbage collected.
static void DeleteDateFormat(const v8::WeakCallbackInfo<void>& data);
// ecma402/#sec-formatdatetime
// FormatDateTime( dateTimeFormat, x )
V8_WARN_UNUSED_RESULT static MaybeHandle<String> FormatDateTime(
Isolate* isolate, Handle<JSObject> date_time_format_holder, double x);
// ecma402/#sec-datetime-format-functions
// DateTime Format Functions
V8_WARN_UNUSED_RESULT static MaybeHandle<String> DateTimeFormat(
Isolate* isolate, Handle<JSObject> date_time_format_holder,
Handle<Object> date);
// The UnwrapDateTimeFormat abstract operation gets the underlying
// DateTimeFormat operation for various methods which implement ECMA-402 v1
// semantics for supporting initializing existing Intl objects.
//
// ecma402/#sec-unwrapdatetimeformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> Unwrap(
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) \
V(kSimpleDateFormat, kPointerSize) \
V(kBoundFormat, kPointerSize) \
......@@ -383,6 +354,11 @@ class Intl {
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> LegacyUnwrapReceiver(
Isolate* isolate, Handle<JSReceiver> receiver,
Handle<JSFunction> constructor, bool has_initialized_slot);
// A factory method to got cached objects.
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> CachedOrNewService(
Isolate* isolate, Handle<String> service, Handle<Object> locales,
Handle<Object> options, Handle<Object> internal_options);
};
} // namespace internal
......
......@@ -448,5 +448,225 @@ Maybe<std::string> JSDateTimeFormat::OptionsToSkeleton(
return Just(result);
}
namespace {
// ecma402/#sec-formatdatetime
// FormatDateTime( dateTimeFormat, x )
MaybeHandle<String> FormatDateTime(Isolate* isolate,
Handle<JSObject> date_time_format_holder,
double x) {
double date_value = DateCache::TimeClip(x);
if (std::isnan(date_value)) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidTimeValue),
String);
}
CHECK(Intl::IsObjectOfType(isolate, date_time_format_holder,
Intl::Type::kDateTimeFormat));
icu::SimpleDateFormat* date_format =
DateFormat::UnpackDateFormat(date_time_format_holder);
CHECK_NOT_NULL(date_format);
icu::UnicodeString result;
date_format->format(date_value, result);
return isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length()));
}
} // namespace
// ecma402/#sec-datetime-format-functions
// DateTime Format Functions
MaybeHandle<String> JSDateTimeFormat::DateTimeFormat(
Isolate* isolate, Handle<JSObject> date_time_format_holder,
Handle<Object> date) {
// 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]]
// internal slot.
DCHECK(Intl::IsObjectOfType(isolate, date_time_format_holder,
Intl::Type::kDateTimeFormat));
// 3. If date is not provided or is undefined, then
double x;
if (date->IsUndefined()) {
// 3.a Let x be Call(%Date_now%, undefined).
x = JSDate::CurrentTimeValue(isolate);
} else {
// 4. Else,
// a. Let x be ? ToNumber(date).
ASSIGN_RETURN_ON_EXCEPTION(isolate, date, Object::ToNumber(isolate, date),
String);
CHECK(date->IsNumber());
x = date->Number();
}
// 5. Return FormatDateTime(dtf, x).
return FormatDateTime(isolate, date_time_format_holder, x);
}
MaybeHandle<String> JSDateTimeFormat::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,
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,
Intl::CachedOrNewService(isolate,
factory->NewStringFromAsciiChecked(service),
locales, options, internal_options),
String);
// 5. Return FormatDateTime(dateFormat, x).
return FormatDateTime(isolate, date_format, x);
}
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));
}
Maybe<bool> NeedsDefault(Isolate* isolate, Handle<JSObject> options,
const std::vector<std::string>& props) {
bool needs_default = true;
for (const auto& prop : props) {
// i. Let prop be the property name.
// ii. Let value be ? Get(options, prop)
Maybe<bool> maybe_undefined =
IsPropertyUndefined(isolate, options, prop.c_str());
MAYBE_RETURN(maybe_undefined, Nothing<bool>());
// iii. If value is not undefined, let needDefaults be false.
if (!maybe_undefined.FromJust()) {
needs_default = false;
}
}
return Just(needs_default);
}
Maybe<bool> CreateDefault(Isolate* isolate, Handle<JSObject> options,
const std::vector<std::string>& props) {
Factory* factory = isolate->factory();
// i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
for (const auto& prop : props) {
MAYBE_RETURN(
JSReceiver::CreateDataProperty(
isolate, options, factory->NewStringFromAsciiChecked(prop.c_str()),
factory->numeric_string(), kThrowOnError),
Nothing<bool>());
}
return Just(true);
}
} // namespace
// ecma-402/#sec-todatetimeoptions
MaybeHandle<JSObject> JSDateTimeFormat::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
const std::vector<std::string> list({"weekday", "year", "month", "day"});
Maybe<bool> maybe_needs_default = NeedsDefault(isolate, options, list);
MAYBE_RETURN(maybe_needs_default, Handle<JSObject>());
needs_default = maybe_needs_default.FromJust();
}
// 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
const std::vector<std::string> list({"hour", "minute", "second"});
Maybe<bool> maybe_needs_default = NeedsDefault(isolate, options, list);
MAYBE_RETURN(maybe_needs_default, Handle<JSObject>());
needs_default &= maybe_needs_default.FromJust();
}
// 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)
const std::vector<std::string> list({"year", "month", "day"});
MAYBE_RETURN(CreateDefault(isolate, options, list), 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
const std::vector<std::string> list({"hour", "minute", "second"});
MAYBE_RETURN(CreateDefault(isolate, options, list), Handle<JSObject>());
}
}
// 8. Return options.
return options;
}
MaybeHandle<JSObject> JSDateTimeFormat::Unwrap(Isolate* isolate,
Handle<JSReceiver> receiver,
const char* method_name) {
Handle<Context> native_context =
Handle<Context>(isolate->context()->native_context(), isolate);
Handle<JSFunction> constructor = Handle<JSFunction>(
JSFunction::cast(native_context->intl_date_time_format_function()),
isolate);
Handle<String> method_name_str =
isolate->factory()->NewStringFromAsciiChecked(method_name);
return Intl::UnwrapReceiver(isolate, receiver, constructor,
Intl::Type::kDateTimeFormat, method_name_str,
true);
}
} // namespace internal
} // namespace v8
......@@ -26,6 +26,14 @@ class JSDateTimeFormat : public JSObject {
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSReceiver> date_time_holder);
// The UnwrapDateTimeFormat abstract operation gets the underlying
// DateTimeFormat operation for various methods which implement ECMA-402 v1
// semantics for supporting initializing existing Intl objects.
//
// ecma402/#sec-unwrapdatetimeformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> Unwrap(
Isolate* isolate, Handle<JSReceiver> receiver, const char* method_name);
// Convert the options to ICU DateTimePatternGenerator skeleton.
static Maybe<std::string> OptionsToSkeleton(Isolate* isolate,
Handle<JSReceiver> options);
......@@ -35,6 +43,22 @@ class JSDateTimeFormat : public JSObject {
static std::string CanonicalizeTimeZoneID(Isolate* isolate,
const std::string& input);
// ecma402/#sec-datetime-format-functions
// DateTime Format Functions
V8_WARN_UNUSED_RESULT static MaybeHandle<String> DateTimeFormat(
Isolate* isolate, Handle<JSObject> date_time_format_holder,
Handle<Object> date);
// 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);
DECL_CAST(JSDateTimeFormat)
// Layout description.
......
......@@ -368,10 +368,10 @@ RUNTIME_FUNCTION(Runtime_ToDateTimeOptions) {
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()));
RETURN_RESULT_OR_FAILURE(isolate,
JSDateTimeFormat::ToDateTimeOptions(
isolate, options, required->ToCString().get(),
defaults->ToCString().get()));
}
RUNTIME_FUNCTION(Runtime_StringToLowerCaseIntl) {
......
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