| Index: src/runtime/runtime-i18n.cc
|
| diff --git a/src/runtime/runtime-i18n.cc b/src/runtime/runtime-i18n.cc
|
| index 8b9d92ec006eb570bf14755087d97987b8d04e2d..7fcb8025922db00d7a86f00ac64e5502b70421e8 100644
|
| --- a/src/runtime/runtime-i18n.cc
|
| +++ b/src/runtime/runtime-i18n.cc
|
| @@ -25,6 +25,8 @@
|
| #include "unicode/decimfmt.h"
|
| #include "unicode/dtfmtsym.h"
|
| #include "unicode/dtptngen.h"
|
| +#include "unicode/fieldpos.h"
|
| +#include "unicode/fpositer.h"
|
| #include "unicode/locid.h"
|
| #include "unicode/normalizer2.h"
|
| #include "unicode/numfmt.h"
|
| @@ -322,7 +324,7 @@ RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
|
| Handle<Symbol> marker = isolate->factory()->intl_impl_object_symbol();
|
|
|
| Handle<Object> impl = JSReceiver::GetDataProperty(obj, marker);
|
| - if (impl->IsTheHole(isolate)) {
|
| + if (!impl->IsJSObject()) {
|
| THROW_NEW_ERROR_RETURN_FAILURE(
|
| isolate, NewTypeError(MessageTemplate::kNotIntlObject, obj));
|
| }
|
| @@ -393,6 +395,138 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
|
| result.length())));
|
| }
|
|
|
| +namespace {
|
| +// The list comes from third_party/icu/source/i18n/unicode/udat.h.
|
| +// They're mapped to DateTimeFormat components listed at
|
| +// https://tc39.github.io/ecma402/#sec-datetimeformat-abstracts .
|
| +
|
| +Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) {
|
| + switch (field_id) {
|
| + case -1:
|
| + return isolate->factory()->literal_string();
|
| + case UDAT_YEAR_FIELD:
|
| + case UDAT_EXTENDED_YEAR_FIELD:
|
| + case UDAT_YEAR_NAME_FIELD:
|
| + return isolate->factory()->year_string();
|
| + case UDAT_MONTH_FIELD:
|
| + case UDAT_STANDALONE_MONTH_FIELD:
|
| + return isolate->factory()->month_string();
|
| + case UDAT_DATE_FIELD:
|
| + return isolate->factory()->day_string();
|
| + case UDAT_HOUR_OF_DAY1_FIELD:
|
| + case UDAT_HOUR_OF_DAY0_FIELD:
|
| + case UDAT_HOUR1_FIELD:
|
| + case UDAT_HOUR0_FIELD:
|
| + return isolate->factory()->hour_string();
|
| + case UDAT_MINUTE_FIELD:
|
| + return isolate->factory()->minute_string();
|
| + case UDAT_SECOND_FIELD:
|
| + return isolate->factory()->second_string();
|
| + case UDAT_DAY_OF_WEEK_FIELD:
|
| + case UDAT_DOW_LOCAL_FIELD:
|
| + case UDAT_STANDALONE_DAY_FIELD:
|
| + return isolate->factory()->weekday_string();
|
| + case UDAT_AM_PM_FIELD:
|
| + return isolate->factory()->dayperiod_string();
|
| + case UDAT_TIMEZONE_FIELD:
|
| + case UDAT_TIMEZONE_RFC_FIELD:
|
| + case UDAT_TIMEZONE_GENERIC_FIELD:
|
| + case UDAT_TIMEZONE_SPECIAL_FIELD:
|
| + case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD:
|
| + case UDAT_TIMEZONE_ISO_FIELD:
|
| + case UDAT_TIMEZONE_ISO_LOCAL_FIELD:
|
| + return isolate->factory()->timeZoneName_string();
|
| + case UDAT_ERA_FIELD:
|
| + return isolate->factory()->era_string();
|
| + default:
|
| + // Other UDAT_*_FIELD's cannot show up because there is no way to specify
|
| + // them via options of Intl.DateTimeFormat.
|
| + UNREACHABLE();
|
| + // To prevent MSVC from issuing C4715 warning.
|
| + return Handle<String>();
|
| + }
|
| +}
|
| +
|
| +bool AddElement(Handle<JSArray> array, int index, int32_t field_id,
|
| + const icu::UnicodeString& formatted, int32_t begin, int32_t end,
|
| + Isolate* isolate) {
|
| + HandleScope scope(isolate);
|
| + Factory* factory = isolate->factory();
|
| + Handle<JSObject> element = factory->NewJSObject(isolate->object_function());
|
| + Handle<String> value = IcuDateFieldIdToDateType(field_id, isolate);
|
| + JSObject::AddProperty(element, factory->type_string(), value, NONE);
|
| +
|
| + icu::UnicodeString field(formatted.tempSubStringBetween(begin, end));
|
| + ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| + isolate, value, factory->NewStringFromTwoByte(Vector<const uint16_t>(
|
| + reinterpret_cast<const uint16_t*>(field.getBuffer()),
|
| + field.length())),
|
| + false);
|
| +
|
| + JSObject::AddProperty(element, factory->value_string(), value, NONE);
|
| + RETURN_ON_EXCEPTION_VALUE(
|
| + isolate, JSObject::AddDataElement(array, index, element, NONE), false);
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) {
|
| + HandleScope scope(isolate);
|
| + Factory* factory = isolate->factory();
|
| +
|
| + DCHECK(args.length() == 2);
|
| +
|
| + CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
|
| +
|
| + Handle<Object> value;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(date));
|
| +
|
| + icu::SimpleDateFormat* date_format =
|
| + DateFormat::UnpackDateFormat(isolate, date_format_holder);
|
| + if (!date_format) return isolate->ThrowIllegalOperation();
|
| +
|
| + icu::UnicodeString formatted;
|
| + icu::FieldPositionIterator fp_iter;
|
| + icu::FieldPosition fp;
|
| + UErrorCode status = U_ZERO_ERROR;
|
| + date_format->format(value->Number(), formatted, &fp_iter, status);
|
| + if (U_FAILURE(status)) return isolate->heap()->undefined_value();
|
| +
|
| + Handle<JSArray> result = factory->NewJSArray(0);
|
| + int32_t length = formatted.length();
|
| + if (length == 0) return *result;
|
| +
|
| + int index = 0;
|
| + int32_t previous_end_pos = 0;
|
| + while (fp_iter.next(fp)) {
|
| + int32_t begin_pos = fp.getBeginIndex();
|
| + int32_t end_pos = fp.getEndIndex();
|
| +
|
| + if (previous_end_pos < begin_pos) {
|
| + if (!AddElement(result, index, -1, formatted, previous_end_pos, begin_pos,
|
| + isolate)) {
|
| + return isolate->heap()->undefined_value();
|
| + }
|
| + ++index;
|
| + }
|
| + if (!AddElement(result, index, fp.getField(), formatted, begin_pos, end_pos,
|
| + isolate)) {
|
| + return isolate->heap()->undefined_value();
|
| + }
|
| + previous_end_pos = end_pos;
|
| + ++index;
|
| + }
|
| + if (previous_end_pos < length) {
|
| + if (!AddElement(result, index, -1, formatted, previous_end_pos, length,
|
| + isolate)) {
|
| + return isolate->heap()->undefined_value();
|
| + }
|
| + }
|
| + JSObject::ValidateElements(result);
|
| + return *result;
|
| +}
|
|
|
| RUNTIME_FUNCTION(Runtime_InternalDateParse) {
|
| HandleScope scope(isolate);
|
|
|