[Intl] Create a JSDateTimeFormat and move ResolvedOptions under it.
Bug: v8:8066 Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng Change-Id: I5511b6b9272804ebbb61bf2127a2ad51bfc70e28 Reviewed-on: https://chromium-review.googlesource.com/1179319 Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Adam Klein <adamk@chromium.org> Commit-Queue: Frank Tang <ftang@chromium.org> Cr-Commit-Position: refs/heads/master@{#55481}
This commit is contained in:
parent
38cbc26a75
commit
a279e23ff8
6
BUILD.gn
6
BUILD.gn
@ -2185,6 +2185,9 @@ v8_source_set("v8_base") {
|
||||
"src/objects/js-collator.h",
|
||||
"src/objects/js-collection-inl.h",
|
||||
"src/objects/js-collection.h",
|
||||
"src/objects/js-date-time-format-inl.h",
|
||||
"src/objects/js-date-time-format.cc",
|
||||
"src/objects/js-date-time-format.h",
|
||||
"src/objects/js-generator-inl.h",
|
||||
"src/objects/js-generator.h",
|
||||
"src/objects/js-list-format-inl.h",
|
||||
@ -2895,6 +2898,9 @@ v8_source_set("v8_base") {
|
||||
"src/objects/js-collator-inl.h",
|
||||
"src/objects/js-collator.cc",
|
||||
"src/objects/js-collator.h",
|
||||
"src/objects/js-date-time-format-inl.h",
|
||||
"src/objects/js-date-time-format.cc",
|
||||
"src/objects/js-date-time-format.h",
|
||||
"src/objects/js-list-format-inl.h",
|
||||
"src/objects/js-list-format.cc",
|
||||
"src/objects/js-list-format.h",
|
||||
|
@ -208,6 +208,7 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
case JS_DATE_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
case JS_INTL_PLURAL_RULES_TYPE:
|
||||
|
@ -258,7 +258,6 @@
|
||||
V(generic_symbol) \
|
||||
V(home_object_symbol) \
|
||||
V(intl_initialized_marker_symbol) \
|
||||
V(intl_pattern_symbol) \
|
||||
V(intl_resolved_symbol) \
|
||||
V(interpreter_trampoline_symbol) \
|
||||
V(megamorphic_symbol) \
|
||||
|
182
src/js/intl.js
182
src/js/intl.js
@ -34,7 +34,6 @@ var InternalArray = utils.InternalArray;
|
||||
var MathMax = global.Math.max;
|
||||
var ObjectHasOwnProperty = global.Object.prototype.hasOwnProperty;
|
||||
var ObjectKeys = global.Object.keys;
|
||||
var patternSymbol = utils.ImportNow("intl_pattern_symbol");
|
||||
var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
|
||||
var StringSubstr = GlobalString.prototype.substr;
|
||||
var StringSubstring = GlobalString.prototype.substring;
|
||||
@ -155,18 +154,6 @@ function GetAnyExtensionRE() {
|
||||
return ANY_EXTENSION_RE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace quoted text (single quote, anything but the quote and quote again).
|
||||
*/
|
||||
var QUOTED_STRING_RE = UNDEFINED;
|
||||
|
||||
function GetQuotedStringRE() {
|
||||
if (IS_UNDEFINED(QUOTED_STRING_RE)) {
|
||||
QUOTED_STRING_RE = new GlobalRegExp("'[^']+'", 'g');
|
||||
}
|
||||
return QUOTED_STRING_RE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches valid service name.
|
||||
*/
|
||||
@ -513,7 +500,6 @@ function getAvailableLocalesOf(service) {
|
||||
return available;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines a property and sets writable, enumerable and configurable to true.
|
||||
*/
|
||||
@ -524,18 +510,6 @@ function defineWECProperty(object, property, value) {
|
||||
configurable: true});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds property to an object if the value is not undefined.
|
||||
* Sets all descriptors to true.
|
||||
*/
|
||||
function addWECPropertyIfDefined(object, property, value) {
|
||||
if (!IS_UNDEFINED(value)) {
|
||||
defineWECProperty(object, property, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns titlecased word, aMeRricA -> America.
|
||||
*/
|
||||
@ -898,85 +872,6 @@ function appendToLDMLString(option, pairs) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns object that matches LDML representation of the date.
|
||||
*/
|
||||
function fromLDMLString(ldmlString) {
|
||||
// First remove '' quoted text, so we lose 'Uhr' strings.
|
||||
ldmlString = %RegExpInternalReplace(GetQuotedStringRE(), ldmlString, '');
|
||||
|
||||
var options = {__proto__: null};
|
||||
var match = %regexp_internal_match(/E{3,5}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
|
||||
|
||||
match = %regexp_internal_match(/G{3,5}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
|
||||
|
||||
match = %regexp_internal_match(/y{1,2}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'year', match, {y: 'numeric', yy: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/M{1,5}/, ldmlString);
|
||||
options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
|
||||
M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
|
||||
|
||||
// Sometimes we get L instead of M for month - standalone name.
|
||||
match = %regexp_internal_match(/L{1,5}/, ldmlString);
|
||||
options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
|
||||
L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
|
||||
|
||||
match = %regexp_internal_match(/d{1,2}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'day', match, {d: 'numeric', dd: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/h{1,2}/, ldmlString);
|
||||
if (match !== null) {
|
||||
options['hour12'] = true;
|
||||
}
|
||||
options = appendToDateTimeObject(
|
||||
options, 'hour', match, {h: 'numeric', hh: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/H{1,2}/, ldmlString);
|
||||
if (match !== null) {
|
||||
options['hour12'] = false;
|
||||
}
|
||||
options = appendToDateTimeObject(
|
||||
options, 'hour', match, {H: 'numeric', HH: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/m{1,2}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'minute', match, {m: 'numeric', mm: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/s{1,2}/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'second', match, {s: 'numeric', ss: '2-digit'});
|
||||
|
||||
match = %regexp_internal_match(/z|zzzz/, ldmlString);
|
||||
options = appendToDateTimeObject(
|
||||
options, 'timeZoneName', match, {z: 'short', zzzz: 'long'});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
function appendToDateTimeObject(options, option, match, pairs) {
|
||||
if (IS_NULL(match)) {
|
||||
if (!HAS_OWN_PROPERTY(options, option)) {
|
||||
%DefineWEProperty(options, option, UNDEFINED);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
var property = match[0];
|
||||
%DefineWEProperty(options, option, pairs[property]);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns options with at least default values in it.
|
||||
*/
|
||||
@ -1083,35 +978,18 @@ function CreateDateTimeFormat(locales, options) {
|
||||
getOption, internalOptions);
|
||||
|
||||
var requestedLocale = locale.locale + extension;
|
||||
var resolved = %object_define_properties({__proto__: null}, {
|
||||
calendar: {writable: true},
|
||||
day: {writable: true},
|
||||
era: {writable: true},
|
||||
hour12: {writable: true},
|
||||
hour: {writable: true},
|
||||
locale: {writable: true},
|
||||
minute: {writable: true},
|
||||
month: {writable: true},
|
||||
numberingSystem: {writable: true},
|
||||
[patternSymbol]: {writable: true},
|
||||
requestedLocale: {value: requestedLocale, writable: true},
|
||||
second: {writable: true},
|
||||
timeZone: {writable: true},
|
||||
timeZoneName: {writable: true},
|
||||
tz: {value: tz, writable: true},
|
||||
weekday: {writable: true},
|
||||
year: {writable: true}
|
||||
});
|
||||
// Still need to store locale and numberingSystem till we move the storage
|
||||
// to JSDateTimeFormat
|
||||
var resolved = {__proto__: null};
|
||||
|
||||
var dateFormat = %CreateDateTimeFormat(
|
||||
requestedLocale,
|
||||
{__proto__: null, skeleton: ldmlString, timeZone: tz}, resolved);
|
||||
|
||||
if (resolved.timeZone === "Etc/Unknown") {
|
||||
throw %make_range_error(kInvalidTimeZone, tz);
|
||||
}
|
||||
|
||||
%MarkAsInitializedIntlObjectOfType(dateFormat, DATE_TIME_FORMAT_TYPE);
|
||||
|
||||
// Still need to store locale and numberingSystem till we move the storage
|
||||
// to JSDateTimeFormat
|
||||
dateFormat[resolvedSymbol] = resolved;
|
||||
|
||||
return dateFormat;
|
||||
@ -1130,59 +1008,13 @@ function DateTimeFormatConstructor() {
|
||||
}
|
||||
%SetCode(GlobalIntlDateTimeFormat, DateTimeFormatConstructor);
|
||||
|
||||
|
||||
/**
|
||||
* DateTimeFormat resolvedOptions method.
|
||||
*/
|
||||
DEFINE_METHOD(
|
||||
GlobalIntlDateTimeFormat.prototype,
|
||||
resolvedOptions() {
|
||||
var methodName = 'resolvedOptions';
|
||||
if(!IS_RECEIVER(this)) {
|
||||
throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
|
||||
}
|
||||
var format = %IntlUnwrapReceiver(this, DATE_TIME_FORMAT_TYPE,
|
||||
GlobalIntlDateTimeFormat,
|
||||
methodName, true);
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
__proto__: null,
|
||||
'gregorian': 'gregory',
|
||||
'ethiopic-amete-alem': 'ethioaa'
|
||||
};
|
||||
|
||||
var fromPattern = fromLDMLString(format[resolvedSymbol][patternSymbol]);
|
||||
var userCalendar = ICU_CALENDAR_MAP[format[resolvedSymbol].calendar];
|
||||
if (IS_UNDEFINED(userCalendar)) {
|
||||
// No match means that ICU's legacy name is identical to LDML/BCP type.
|
||||
userCalendar = format[resolvedSymbol].calendar;
|
||||
}
|
||||
|
||||
var result = {
|
||||
locale: format[resolvedSymbol].locale,
|
||||
numberingSystem: format[resolvedSymbol].numberingSystem,
|
||||
calendar: userCalendar,
|
||||
timeZone: format[resolvedSymbol].timeZone
|
||||
};
|
||||
|
||||
addWECPropertyIfDefined(result, 'timeZoneName', fromPattern.timeZoneName);
|
||||
addWECPropertyIfDefined(result, 'era', fromPattern.era);
|
||||
addWECPropertyIfDefined(result, 'year', fromPattern.year);
|
||||
addWECPropertyIfDefined(result, 'month', fromPattern.month);
|
||||
addWECPropertyIfDefined(result, 'day', fromPattern.day);
|
||||
addWECPropertyIfDefined(result, 'weekday', fromPattern.weekday);
|
||||
addWECPropertyIfDefined(result, 'hour12', fromPattern.hour12);
|
||||
addWECPropertyIfDefined(result, 'hour', fromPattern.hour);
|
||||
addWECPropertyIfDefined(result, 'minute', fromPattern.minute);
|
||||
addWECPropertyIfDefined(result, 'second', fromPattern.second);
|
||||
|
||||
return result;
|
||||
return %DateTimeFormatResolvedOptions(this);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -727,6 +727,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
case JS_INTL_PLURAL_RULES_TYPE:
|
||||
|
@ -15,16 +15,18 @@
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/arguments-inl.h"
|
||||
#include "src/objects/bigint.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collator-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/data-handler-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/hash-table-inl.h"
|
||||
#include "src/objects/js-array-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collator-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collection-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-date-time-format-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-generator-inl.h"
|
||||
#include "src/objects/literal-objects-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-list-format-inl.h"
|
||||
#include "src/objects/js-locale-inl.h"
|
||||
@ -35,6 +37,7 @@
|
||||
#include "src/objects/js-plural-rules-inl.h"
|
||||
#include "src/objects/js-relative-time-format-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/literal-objects-inl.h"
|
||||
#include "src/objects/maybe-object.h"
|
||||
#include "src/objects/microtask-inl.h"
|
||||
#include "src/objects/module-inl.h"
|
||||
@ -359,6 +362,9 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
JSCollator::cast(this)->JSCollatorVerify(isolate);
|
||||
break;
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
JSDateTimeFormat::cast(this)->JSDateTimeFormatVerify(isolate);
|
||||
break;
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
JSListFormat::cast(this)->JSListFormatVerify(isolate);
|
||||
break;
|
||||
@ -1878,6 +1884,10 @@ void JSCollator::JSCollatorVerify(Isolate* isolate) {
|
||||
VerifyObjectField(isolate, kBoundCompareOffset);
|
||||
}
|
||||
|
||||
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
|
||||
JSObjectVerify(isolate);
|
||||
}
|
||||
|
||||
void JSListFormat::JSListFormatVerify(Isolate* isolate) {
|
||||
JSObjectVerify(isolate);
|
||||
VerifyObjectField(isolate, kLocaleOffset);
|
||||
|
@ -217,6 +217,7 @@ namespace internal {
|
||||
#define INSTANCE_TYPE_LIST(V) \
|
||||
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
|
||||
V(JS_INTL_COLLATOR_TYPE) \
|
||||
V(JS_INTL_DATE_TIME_FORMAT_TYPE) \
|
||||
V(JS_INTL_LIST_FORMAT_TYPE) \
|
||||
V(JS_INTL_LOCALE_TYPE) \
|
||||
V(JS_INTL_PLURAL_RULES_TYPE) \
|
||||
|
@ -14,15 +14,18 @@
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/arguments-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collator-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/data-handler-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/hash-table-inl.h"
|
||||
#include "src/objects/js-array-buffer-inl.h"
|
||||
#include "src/objects/js-array-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collator-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collection-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-date-time-format-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-generator-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-list-format-inl.h"
|
||||
@ -312,6 +315,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
JSCollator::cast(this)->JSCollatorPrint(os);
|
||||
break;
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
JSDateTimeFormat::cast(this)->JSDateTimeFormatPrint(os);
|
||||
break;
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
JSListFormat::cast(this)->JSListFormatPrint(os);
|
||||
break;
|
||||
@ -1960,6 +1966,10 @@ void JSCollator::JSCollatorPrint(std::ostream& os) { // NOLINT
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void JSDateTimeFormat::JSDateTimeFormatPrint(std::ostream& os) { // NOLINT
|
||||
JSObjectPrintHeader(os, this, "JSDateTimeFormat");
|
||||
}
|
||||
|
||||
void JSListFormat::JSListFormatPrint(std::ostream& os) { // NOLINT
|
||||
JSObjectPrintHeader(os, this, "JSListFormat");
|
||||
os << "\n - locale: " << Brief(locale());
|
||||
|
@ -64,6 +64,9 @@
|
||||
#include "src/objects/js-collator.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-collection-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-date-time-format.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-generator-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-list-format.h"
|
||||
@ -1446,6 +1449,8 @@ int JSObject::GetHeaderSize(InstanceType type,
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
return JSCollator::kSize;
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
return JSDateTimeFormat::kSize;
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
return JSListFormat::kSize;
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
@ -3190,6 +3195,7 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
case JS_REGEXP_STRING_ITERATOR_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
case JS_INTL_PLURAL_RULES_TYPE:
|
||||
@ -13130,6 +13136,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
|
||||
case JS_GENERATOR_OBJECT_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_COLLATOR_TYPE:
|
||||
case JS_INTL_DATE_TIME_FORMAT_TYPE:
|
||||
case JS_INTL_LIST_FORMAT_TYPE:
|
||||
case JS_INTL_PLURAL_RULES_TYPE:
|
||||
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
|
||||
|
@ -76,6 +76,7 @@
|
||||
// - JSMessageObject
|
||||
// - JSModuleNamespace
|
||||
// - JSCollator // If V8_INTL_SUPPORT enabled.
|
||||
// - JSDateTimeFormat // If V8_INTL_SUPPORT enabled.
|
||||
// - JSListFormat // If V8_INTL_SUPPORT enabled.
|
||||
// - JSLocale // If V8_INTL_SUPPORT enabled.
|
||||
// - JSPluralRules // If V8_INTL_SUPPORT enabled.
|
||||
@ -583,6 +584,7 @@ enum InstanceType : uint16_t {
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
JS_INTL_COLLATOR_TYPE,
|
||||
JS_INTL_DATE_TIME_FORMAT_TYPE,
|
||||
JS_INTL_LIST_FORMAT_TYPE,
|
||||
JS_INTL_LOCALE_TYPE,
|
||||
JS_INTL_PLURAL_RULES_TYPE,
|
||||
@ -701,6 +703,7 @@ class JSGlobalObject;
|
||||
class JSGlobalProxy;
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
class JSCollator;
|
||||
class JSDateTimeFormat;
|
||||
class JSListFormat;
|
||||
class JSLocale;
|
||||
class JSPluralRules;
|
||||
@ -912,6 +915,7 @@ class ZoneForwardList;
|
||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
|
||||
HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
|
||||
V(JSCollator) \
|
||||
V(JSDateTimeFormat) \
|
||||
V(JSListFormat) \
|
||||
V(JSLocale) \
|
||||
V(JSPluralRules) \
|
||||
@ -1029,12 +1033,13 @@ class ZoneForwardList;
|
||||
V(WeakArrayList, WEAK_ARRAY_LIST_TYPE)
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
|
||||
#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \
|
||||
INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V) \
|
||||
V(JSCollator, JS_INTL_COLLATOR_TYPE) \
|
||||
V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE) \
|
||||
V(JSLocale, JS_INTL_LOCALE_TYPE) \
|
||||
V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \
|
||||
#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \
|
||||
INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V) \
|
||||
V(JSCollator, JS_INTL_COLLATOR_TYPE) \
|
||||
V(JSDateTimeFormat, JS_INTL_DATE_TIME_FORMAT_TYPE) \
|
||||
V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE) \
|
||||
V(JSLocale, JS_INTL_LOCALE_TYPE) \
|
||||
V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \
|
||||
V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE)
|
||||
|
||||
#else
|
||||
|
@ -169,66 +169,9 @@ void SetResolvedDateSettings(Isolate* isolate, const icu::Locale& icu_locale,
|
||||
Handle<JSObject> resolved) {
|
||||
Factory* factory = isolate->factory();
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
icu::UnicodeString pattern;
|
||||
date_format->toPattern(pattern);
|
||||
JSObject::SetProperty(
|
||||
isolate, resolved, factory->intl_pattern_symbol(),
|
||||
factory
|
||||
->NewStringFromTwoByte(Vector<const uint16_t>(
|
||||
reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
|
||||
pattern.length()))
|
||||
.ToHandleChecked(),
|
||||
LanguageMode::kSloppy)
|
||||
.Assert();
|
||||
|
||||
// Set time zone and calendar.
|
||||
const icu::Calendar* calendar = date_format->getCalendar();
|
||||
// getType() returns legacy calendar type name instead of LDML/BCP47 calendar
|
||||
// key values. intl.js maps them to BCP47 values for key "ca".
|
||||
// TODO(jshin): Consider doing it here, instead.
|
||||
const char* calendar_name = calendar->getType();
|
||||
JSObject::SetProperty(
|
||||
isolate, resolved, factory->NewStringFromStaticChars("calendar"),
|
||||
factory->NewStringFromAsciiChecked(calendar_name), LanguageMode::kSloppy)
|
||||
.Assert();
|
||||
|
||||
const icu::TimeZone& tz = calendar->getTimeZone();
|
||||
icu::UnicodeString time_zone;
|
||||
tz.getID(time_zone);
|
||||
|
||||
icu::UnicodeString canonical_time_zone;
|
||||
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
// In CLDR (http://unicode.org/cldr/trac/ticket/9943), Etc/UTC is made
|
||||
// a separate timezone ID from Etc/GMT even though they're still the same
|
||||
// timezone. We have Etc/UTC because 'UTC', 'Etc/Universal',
|
||||
// 'Etc/Zulu' and others are turned to 'Etc/UTC' by ICU. Etc/GMT comes
|
||||
// from Etc/GMT0, Etc/GMT+0, Etc/GMT-0, Etc/Greenwich.
|
||||
// ecma402##sec-canonicalizetimezonename step 3
|
||||
if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/UTC") ||
|
||||
canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) {
|
||||
JSObject::SetProperty(
|
||||
isolate, resolved, factory->NewStringFromStaticChars("timeZone"),
|
||||
factory->NewStringFromStaticChars("UTC"), LanguageMode::kSloppy)
|
||||
.Assert();
|
||||
} else {
|
||||
JSObject::SetProperty(isolate, resolved,
|
||||
factory->NewStringFromStaticChars("timeZone"),
|
||||
factory
|
||||
->NewStringFromTwoByte(Vector<const uint16_t>(
|
||||
reinterpret_cast<const uint16_t*>(
|
||||
canonical_time_zone.getBuffer()),
|
||||
canonical_time_zone.length()))
|
||||
.ToHandleChecked(),
|
||||
LanguageMode::kSloppy)
|
||||
.Assert();
|
||||
}
|
||||
}
|
||||
|
||||
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
|
||||
// to assume that for given locale NumberingSystem constructor produces the
|
||||
// same digits as NumberFormat/Calendar would.
|
||||
status = U_ZERO_ERROR;
|
||||
icu::NumberingSystem* numbering_system =
|
||||
icu::NumberingSystem::createInstance(icu_locale, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
@ -600,6 +543,21 @@ icu::Locale Intl::CreateICULocale(Isolate* isolate,
|
||||
return icu_locale;
|
||||
}
|
||||
|
||||
bool DateFormat::IsValidTimeZone(icu::SimpleDateFormat* date_format) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// Set time zone and calendar.
|
||||
const icu::Calendar* calendar = date_format->getCalendar();
|
||||
const icu::TimeZone& tz = calendar->getTimeZone();
|
||||
icu::UnicodeString time_zone;
|
||||
tz.getID(time_zone);
|
||||
icu::UnicodeString canonical_time_zone;
|
||||
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status);
|
||||
std::string timezone_str;
|
||||
canonical_time_zone.toUTF8String(timezone_str);
|
||||
if (U_SUCCESS(status)) return timezone_str != "Etc/Unknown";
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
icu::SimpleDateFormat* DateFormat::InitializeDateTimeFormat(
|
||||
Isolate* isolate, Handle<String> locale, Handle<JSObject> options,
|
||||
|
@ -45,6 +45,9 @@ class DateFormat {
|
||||
// Unpacks date format object from corresponding JavaScript object.
|
||||
static icu::SimpleDateFormat* UnpackDateFormat(Handle<JSObject> obj);
|
||||
|
||||
// Determine the TimeZone is valid.
|
||||
static bool IsValidTimeZone(icu::SimpleDateFormat* date_format);
|
||||
|
||||
// Release memory we allocated for the DateFormat once the JS object that
|
||||
// holds the pointer gets garbage collected.
|
||||
static void DeleteDateFormat(const v8::WeakCallbackInfo<void>& data);
|
||||
|
28
src/objects/js-date-time-format-inl.h
Normal file
28
src/objects/js-date-time-format-inl.h
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
#ifndef V8_INTL_SUPPORT
|
||||
#error Internationalization is expected to be enabled.
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_INL_H_
|
||||
#define V8_OBJECTS_JS_DATE_TIME_FORMAT_INL_H_
|
||||
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/js-date-time-format.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
CAST_ACCESSOR(JSDateTimeFormat);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_JS_DATE_TIME_FORMAT_INL_H_
|
274
src/objects/js-date-time-format.cc
Normal file
274
src/objects/js-date-time-format.cc
Normal file
@ -0,0 +1,274 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
#ifndef V8_INTL_SUPPORT
|
||||
#error Internationalization is expected to be enabled.
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#include "src/objects/js-date-time-format.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "src/heap/factory.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects/intl-objects.h"
|
||||
#include "src/objects/js-date-time-format-inl.h"
|
||||
|
||||
#include "unicode/calendar.h"
|
||||
#include "unicode/smpdtfmt.h"
|
||||
#include "unicode/unistr.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
class PatternMap {
|
||||
public:
|
||||
PatternMap(std::string pattern, std::string value)
|
||||
: pattern(pattern), value(value) {}
|
||||
virtual ~PatternMap() {}
|
||||
std::string pattern;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
class PatternItem {
|
||||
public:
|
||||
PatternItem(const std::string property, std::vector<PatternMap> pairs,
|
||||
std::vector<const char*>* allowed_values)
|
||||
: property(property), pairs(pairs), allowed_values(allowed_values) {}
|
||||
virtual ~PatternItem() {}
|
||||
|
||||
const std::string property;
|
||||
// It is important for the pattern in the pairs from longer one to shorter one
|
||||
// if the longer one contains substring of an shorter one.
|
||||
std::vector<PatternMap> pairs;
|
||||
std::vector<const char*>* allowed_values;
|
||||
};
|
||||
|
||||
static const std::vector<PatternItem>& GetPatternItems() {
|
||||
static std::vector<const char*> kLongShort = {"long", "short"};
|
||||
static std::vector<const char*> kNarrowLongShort = {"narrow", "long",
|
||||
"short"};
|
||||
static std::vector<const char*> k2DigitNumeric = {"2-digit", "numeric"};
|
||||
static std::vector<const char*> kNarrowLongShort2DigitNumeric = {
|
||||
"narrow", "long", "short", "2-digit", "numeric"};
|
||||
static std::vector<PatternItem> kPatternItems = {
|
||||
PatternItem("weekday",
|
||||
{{"EEEEE", "narrow"}, {"EEEE", "long"}, {"EEE", "short"}},
|
||||
&kNarrowLongShort),
|
||||
PatternItem("era",
|
||||
{{"GGGGG", "narrow"}, {"GGGG", "long"}, {"GGG", "short"}},
|
||||
&kNarrowLongShort),
|
||||
PatternItem("year", {{"yy", "2-digit"}, {"y", "numeric"}},
|
||||
&k2DigitNumeric),
|
||||
// Sometimes we get L instead of M for month - standalone name.
|
||||
PatternItem("month",
|
||||
{{"MMMMM", "narrow"},
|
||||
{"MMMM", "long"},
|
||||
{"MMM", "short"},
|
||||
{"MM", "2-digit"},
|
||||
{"M", "numeric"},
|
||||
{"LLLLL", "narrow"},
|
||||
{"LLLL", "long"},
|
||||
{"LLL", "short"},
|
||||
{"LL", "2-digit"},
|
||||
{"L", "numeric"}},
|
||||
&kNarrowLongShort2DigitNumeric),
|
||||
PatternItem("day", {{"dd", "2-digit"}, {"d", "numeric"}},
|
||||
&k2DigitNumeric),
|
||||
PatternItem("hour",
|
||||
{{"HH", "2-digit"},
|
||||
{"H", "numeric"},
|
||||
{"hh", "2-digit"},
|
||||
{"h", "numeric"}},
|
||||
&k2DigitNumeric),
|
||||
PatternItem("minute", {{"mm", "2-digit"}, {"m", "numeric"}},
|
||||
&k2DigitNumeric),
|
||||
PatternItem("second", {{"ss", "2-digit"}, {"s", "numeric"}},
|
||||
&k2DigitNumeric),
|
||||
PatternItem("timeZoneName", {{"zzzz", "long"}, {"z", "short"}},
|
||||
&kLongShort)};
|
||||
return kPatternItems;
|
||||
}
|
||||
|
||||
void SetPropertyFromPattern(Isolate* isolate, const std::string& pattern,
|
||||
Handle<JSObject> options) {
|
||||
Factory* factory = isolate->factory();
|
||||
const std::vector<PatternItem>& items = GetPatternItems();
|
||||
for (auto item = items.cbegin(); item != items.cend(); ++item) {
|
||||
for (auto pair = item->pairs.cbegin(); pair != item->pairs.cend(); ++pair) {
|
||||
if (pattern.find(pair->pattern) != std::string::npos) {
|
||||
// After we find the first pair in the item which matching the pattern,
|
||||
// we set the property and look for the next item in kPatternItems.
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options,
|
||||
factory->NewStringFromAsciiChecked(item->property.c_str()),
|
||||
factory->NewStringFromAsciiChecked(pair->value.c_str()),
|
||||
kDontThrow)
|
||||
.FromJust());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// hour12
|
||||
// b. If p is "hour12", then
|
||||
// i. Let hc be dtf.[[HourCycle]].
|
||||
// ii. If hc is "h11" or "h12", let v be true.
|
||||
// iii. Else if, hc is "h23" or "h24", let v be false.
|
||||
// iv. Else, let v be undefined.
|
||||
if (pattern.find("h") != std::string::npos) {
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->NewStringFromStaticChars("hour12"),
|
||||
factory->true_value(), kDontThrow)
|
||||
.FromJust());
|
||||
} else if (pattern.find("H") != std::string::npos) {
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->NewStringFromStaticChars("hour12"),
|
||||
factory->false_value(), kDontThrow)
|
||||
.FromJust());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
|
||||
Isolate* isolate, Handle<JSReceiver> format_holder) {
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
// 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
|
||||
if (!Intl::IsObjectOfType(isolate, format_holder,
|
||||
Intl::Type::kDateTimeFormat)) {
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
|
||||
factory->NewStringFromStaticChars(
|
||||
"Intl.DateTimeFormat.resolvedOptions"),
|
||||
format_holder),
|
||||
JSObject);
|
||||
}
|
||||
CHECK(format_holder->IsJSObject());
|
||||
icu::SimpleDateFormat* icu_simple_date_format =
|
||||
DateFormat::UnpackDateFormat(Handle<JSObject>::cast(format_holder));
|
||||
|
||||
// 4. Let options be ! ObjectCreate(%ObjectPrototype%).
|
||||
Handle<JSObject> options = factory->NewJSObject(isolate->object_function());
|
||||
|
||||
// 5. For each row of Table 6, except the header row, in any order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
Handle<Object> resolved_obj;
|
||||
|
||||
// After we move all the data to JSDateTimeFormat, we should just get locale
|
||||
// and numberingSystem from the member data. This is here until we move
|
||||
// everything.
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, resolved_obj,
|
||||
JSReceiver::GetProperty(isolate, format_holder,
|
||||
factory->intl_resolved_symbol()),
|
||||
JSObject);
|
||||
CHECK(resolved_obj->IsJSObject());
|
||||
Handle<JSObject> resolved = Handle<JSObject>::cast(resolved_obj);
|
||||
|
||||
// locale
|
||||
Handle<Object> locale_obj;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, locale_obj,
|
||||
JSReceiver::GetProperty(isolate, resolved, factory->locale_string()),
|
||||
JSObject);
|
||||
CHECK(locale_obj->IsString());
|
||||
Handle<String> locale = Handle<String>::cast(locale_obj);
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->locale_string(), locale, kDontThrow)
|
||||
.FromJust());
|
||||
|
||||
// numberingSystem
|
||||
// replace to factory->numberingSystem_string(), after +/1168518 landed.
|
||||
Handle<String> numberingSystem_string =
|
||||
factory->NewStringFromStaticChars("numberingSystem");
|
||||
Handle<Object> numbering_system_obj;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, numbering_system_obj,
|
||||
JSReceiver::GetProperty(isolate, resolved, numberingSystem_string),
|
||||
JSObject);
|
||||
if (numbering_system_obj->IsString()) {
|
||||
Handle<String> numbering_system =
|
||||
Handle<String>::cast(numbering_system_obj);
|
||||
CHECK(JSReceiver::CreateDataProperty(isolate, options,
|
||||
numberingSystem_string,
|
||||
numbering_system, kDontThrow)
|
||||
.FromJust());
|
||||
}
|
||||
|
||||
icu::UnicodeString pattern_unicode;
|
||||
icu_simple_date_format->toPattern(pattern_unicode);
|
||||
std::string pattern;
|
||||
pattern_unicode.toUTF8String(pattern);
|
||||
SetPropertyFromPattern(isolate, pattern, options);
|
||||
|
||||
// calendar
|
||||
const icu::Calendar* calendar = icu_simple_date_format->getCalendar();
|
||||
// getType() returns legacy calendar type name instead of LDML/BCP47 calendar
|
||||
// key values. intl.js maps them to BCP47 values for key "ca".
|
||||
// TODO(jshin): Consider doing it here, instead.
|
||||
std::string calendar_str = calendar->getType();
|
||||
|
||||
// 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
|
||||
if (calendar_str == "gregorian") {
|
||||
calendar_str = "gregory";
|
||||
} else if (calendar_str == "ethiopic-amete-alem") {
|
||||
calendar_str = "ethioaa";
|
||||
}
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->NewStringFromStaticChars("calendar"),
|
||||
factory->NewStringFromAsciiChecked(calendar_str.c_str()),
|
||||
kDontThrow)
|
||||
.FromJust());
|
||||
|
||||
// timezone
|
||||
const icu::TimeZone& tz = calendar->getTimeZone();
|
||||
icu::UnicodeString time_zone;
|
||||
tz.getID(time_zone);
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
icu::UnicodeString canonical_time_zone;
|
||||
icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, error);
|
||||
if (U_SUCCESS(error)) {
|
||||
Handle<String> timezone_value;
|
||||
// In CLDR (http://unicode.org/cldr/trac/ticket/9943), Etc/UTC is made
|
||||
// a separate timezone ID from Etc/GMT even though they're still the same
|
||||
// timezone. We have Etc/UTC because 'UTC', 'Etc/Universal',
|
||||
// 'Etc/Zulu' and others are turned to 'Etc/UTC' by ICU. Etc/GMT comes
|
||||
// from Etc/GMT0, Etc/GMT+0, Etc/GMT-0, Etc/Greenwich.
|
||||
// ecma402##sec-canonicalizetimezonename step 3
|
||||
if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/UTC") ||
|
||||
canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) {
|
||||
timezone_value = factory->NewStringFromAsciiChecked("UTC");
|
||||
} else {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, timezone_value,
|
||||
factory->NewStringFromTwoByte(
|
||||
Vector<const uint16_t>(reinterpret_cast<const uint16_t*>(
|
||||
canonical_time_zone.getBuffer()),
|
||||
canonical_time_zone.length())),
|
||||
JSObject);
|
||||
}
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->NewStringFromStaticChars("timeZone"),
|
||||
timezone_value, kDontThrow)
|
||||
.FromJust());
|
||||
} else {
|
||||
// Somehow on Windows we will reach here.
|
||||
CHECK(JSReceiver::CreateDataProperty(
|
||||
isolate, options, factory->NewStringFromStaticChars("timeZone"),
|
||||
factory->undefined_value(), kDontThrow)
|
||||
.FromJust());
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
52
src/objects/js-date-time-format.h
Normal file
52
src/objects/js-date-time-format.h
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
#ifndef V8_INTL_SUPPORT
|
||||
#error Internationalization is expected to be enabled.
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#ifndef V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
|
||||
#define V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
|
||||
|
||||
#include "src/isolate.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace U_ICU_NAMESPACE {
|
||||
class SimpleDateFormat;
|
||||
}
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class JSDateTimeFormat : public JSObject {
|
||||
public:
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
|
||||
Isolate* isolate, Handle<JSReceiver> date_time_holder);
|
||||
|
||||
DECL_CAST(JSDateTimeFormat)
|
||||
|
||||
// Layout description.
|
||||
#define JS_DATE_TIME_FORMAT_FIELDS(V) \
|
||||
/* Total size. */ \
|
||||
V(kSize, 0)
|
||||
|
||||
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
|
||||
JS_DATE_TIME_FORMAT_FIELDS)
|
||||
#undef JS_DATE_TIME_FORMAT_FIELDS
|
||||
|
||||
DECL_PRINTER(JSDateTimeFormat)
|
||||
DECL_VERIFIER(JSDateTimeFormat)
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSDateTimeFormat);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_OBJECTS_JS_DATE_TIME_FORMAT_H_
|
@ -22,6 +22,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-list-format.h"
|
||||
#include "src/objects/js-plural-rules-inl.h"
|
||||
@ -217,6 +218,13 @@ RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
|
||||
icu::SimpleDateFormat* date_format =
|
||||
DateFormat::InitializeDateTimeFormat(isolate, locale, options, resolved);
|
||||
CHECK_NOT_NULL(date_format);
|
||||
if (!DateFormat::IsValidTimeZone(date_format)) {
|
||||
delete date_format;
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewRangeError(MessageTemplate::kInvalidTimeZone,
|
||||
isolate->factory()->NewStringFromStaticChars("Etc/GMT")));
|
||||
}
|
||||
|
||||
local_object->SetEmbedderField(DateFormat::kSimpleDateFormatIndex,
|
||||
reinterpret_cast<Smi*>(date_format));
|
||||
@ -229,6 +237,25 @@ RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
|
||||
return *local_object;
|
||||
}
|
||||
|
||||
// ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
|
||||
RUNTIME_FUNCTION(Runtime_DateTimeFormatResolvedOptions) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
// 1. Let dtf be this value.
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, dtf, 0);
|
||||
// 2. If Type(dtf) is not Object, throw a TypeError exception.
|
||||
if (!dtf->IsJSReceiver()) {
|
||||
Handle<String> method_str = isolate->factory()->NewStringFromStaticChars(
|
||||
"Intl.DateTimeFormat.prototype.resolvedOptions");
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
|
||||
method_str, dtf));
|
||||
}
|
||||
Handle<JSReceiver> date_format_holder = Handle<JSReceiver>::cast(dtf);
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_format_holder));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
|
||||
HandleScope scope(isolate);
|
||||
|
||||
|
@ -208,6 +208,7 @@ namespace internal {
|
||||
F(CreateNumberFormat, 3, 1) \
|
||||
F(CurrencyDigits, 1, 1) \
|
||||
F(DateCacheVersion, 0, 1) \
|
||||
F(DateTimeFormatResolvedOptions, 1, 1) \
|
||||
F(DefaultNumberOption, 5, 1) \
|
||||
F(DefineWEProperty, 3, 1) \
|
||||
F(FormatList, 2, 1) \
|
||||
|
@ -159,17 +159,18 @@ INSTANCE_TYPES = {
|
||||
1082: "JS_TYPED_ARRAY_TYPE",
|
||||
1083: "JS_DATA_VIEW_TYPE",
|
||||
1084: "JS_INTL_COLLATOR_TYPE",
|
||||
1085: "JS_INTL_LIST_FORMAT_TYPE",
|
||||
1086: "JS_INTL_LOCALE_TYPE",
|
||||
1087: "JS_INTL_PLURAL_RULES_TYPE",
|
||||
1088: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1089: "WASM_GLOBAL_TYPE",
|
||||
1090: "WASM_INSTANCE_TYPE",
|
||||
1091: "WASM_MEMORY_TYPE",
|
||||
1092: "WASM_MODULE_TYPE",
|
||||
1093: "WASM_TABLE_TYPE",
|
||||
1094: "JS_BOUND_FUNCTION_TYPE",
|
||||
1095: "JS_FUNCTION_TYPE",
|
||||
1085: "JS_INTL_DATE_TIME_FORMAT_TYPE",
|
||||
1086: "JS_INTL_LIST_FORMAT_TYPE",
|
||||
1087: "JS_INTL_LOCALE_TYPE",
|
||||
1088: "JS_INTL_PLURAL_RULES_TYPE",
|
||||
1089: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1090: "WASM_GLOBAL_TYPE",
|
||||
1091: "WASM_INSTANCE_TYPE",
|
||||
1092: "WASM_MEMORY_TYPE",
|
||||
1093: "WASM_MODULE_TYPE",
|
||||
1094: "WASM_TABLE_TYPE",
|
||||
1095: "JS_BOUND_FUNCTION_TYPE",
|
||||
1096: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -284,32 +285,32 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x04811): (173, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x04b01): (161, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x04bf9): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x09aa1): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x09af1): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x09b41): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x09b91): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x09be1): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x09c31): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x09c81): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x09cd1): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09d21): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x09d71): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x09dc1): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x09e11): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09e61): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x09eb1): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x09f01): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x09f51): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x09fa1): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x09ff1): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x0a041): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x0a091): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x0a0e1): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x0a131): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a181): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a1d1): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x0a221): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x0a271): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x09a81): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x09ad1): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x09b21): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x09b71): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x09bc1): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x09c11): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x09c61): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x09cb1): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09d01): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x09d51): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x09da1): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x09df1): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09e41): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x09e91): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x09ee1): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x09f31): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x09f81): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x09fd1): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x0a021): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x0a071): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x0a0c1): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x0a111): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a161): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a1b1): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x0a201): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x0a251): (181, "AllocationSiteMap"),
|
||||
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user