[Intl] Use flags in Locale

Use bits flag for caseFirst, hourCycle and numeric in Locale.
Also set up macro for V8_INTL_SUPPORT only in heap-symbols.h

Bug: v8:7684, v8:8256
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I3f6956b6dd5782e88676667381a7d8a7b2476bfc
Reviewed-on: https://chromium-review.googlesource.com/c/1262476
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56423}
This commit is contained in:
Frank Tang 2018-10-05 22:44:27 -07:00 committed by Commit Bot
parent ad8d2ed8a8
commit fdfdce1d1e
10 changed files with 236 additions and 62 deletions

View File

@ -722,7 +722,7 @@ BUILTIN(LocalePrototypeCaseFirst) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.caseFirst");
return locale_holder->case_first();
return *(locale_holder->CaseFirstAsString());
}
BUILTIN(LocalePrototypeCollation) {
@ -736,14 +736,23 @@ BUILTIN(LocalePrototypeHourCycle) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.hourCycle");
return locale_holder->hour_cycle();
return *(locale_holder->HourCycleAsString());
}
BUILTIN(LocalePrototypeNumeric) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.numeric");
return locale_holder->numeric();
switch (locale_holder->numeric()) {
case JSLocale::Numeric::TRUE_VALUE:
return *(isolate->factory()->true_value());
case JSLocale::Numeric::FALSE_VALUE:
return *(isolate->factory()->false_value());
case JSLocale::Numeric::NOTSET:
return *(isolate->factory()->undefined_value());
case JSLocale::Numeric::COUNT:
UNREACHABLE();
}
}
BUILTIN(LocalePrototypeNumberingSystem) {

View File

@ -5,7 +5,20 @@
#ifndef V8_HEAP_SYMBOLS_H_
#define V8_HEAP_SYMBOLS_H_
#ifdef V8_INTL_SUPPORT
#define INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _) \
V(_, h11_string, "h11") \
V(_, h12_string, "h12") \
V(_, h23_string, "h23") \
V(_, h24_string, "h24") \
V(_, lower_string, "lower") \
V(_, upper_string, "upper")
#else // V8_INTL_SUPPORT
#define INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _)
#endif // V8_INTL_SUPPORT
#define INTERNALIZED_STRING_LIST_GENERATOR(V, _) \
INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _) \
V(_, add_string, "add") \
V(_, always_string, "always") \
V(_, anonymous_function_string, "(anonymous function)") \

View File

@ -1931,11 +1931,9 @@ void JSLocale::JSLocaleVerify(Isolate* isolate) {
VerifyObjectField(isolate, kBaseNameOffset);
VerifyObjectField(isolate, kLocaleOffset);
// Unicode extension fields.
VerifyObjectField(isolate, kFlagsOffset);
VerifyObjectField(isolate, kCalendarOffset);
VerifyObjectField(isolate, kCaseFirstOffset);
VerifyObjectField(isolate, kCollationOffset);
VerifyObjectField(isolate, kHourCycleOffset);
VerifyObjectField(isolate, kNumericOffset);
VerifyObjectField(isolate, kNumberingSystemOffset);
}

View File

@ -1998,10 +1998,10 @@ void JSLocale::JSLocalePrint(std::ostream& os) { // NOLINT
os << "\n - baseName: " << Brief(base_name());
os << "\n - locale: " << Brief(locale());
os << "\n - calendar: " << Brief(calendar());
os << "\n - caseFirst: " << Brief(case_first());
os << "\n - caseFirst: " << CaseFirstAsString();
os << "\n - collation: " << Brief(collation());
os << "\n - hourCycle: " << Brief(hour_cycle());
os << "\n - numeric: " << Brief(numeric());
os << "\n - hourCycle: " << HourCycleAsString();
os << "\n - numeric: " << NumericAsString();
os << "\n - numberingSystem: " << Brief(numbering_system());
os << "\n";
}

View File

@ -28,14 +28,45 @@ ACCESSORS(JSLocale, locale, String, kLocaleOffset);
// Unicode extension accessors.
ACCESSORS(JSLocale, calendar, Object, kCalendarOffset);
ACCESSORS(JSLocale, case_first, Object, kCaseFirstOffset);
ACCESSORS(JSLocale, collation, Object, kCollationOffset);
ACCESSORS(JSLocale, hour_cycle, Object, kHourCycleOffset);
ACCESSORS(JSLocale, numeric, Object, kNumericOffset);
ACCESSORS(JSLocale, numbering_system, Object, kNumberingSystemOffset);
SMI_ACCESSORS(JSLocale, flags, kFlagsOffset)
CAST_ACCESSOR(JSLocale);
inline void JSLocale::set_case_first(CaseFirst case_first) {
DCHECK_GT(CaseFirst::COUNT, case_first);
int hints = flags();
hints = CaseFirstBits::update(hints, case_first);
set_flags(hints);
}
inline JSLocale::CaseFirst JSLocale::case_first() const {
return CaseFirstBits::decode(flags());
}
inline void JSLocale::set_hour_cycle(HourCycle hour_cycle) {
DCHECK_GT(HourCycle::COUNT, hour_cycle);
int hints = flags();
hints = HourCycleBits::update(hints, hour_cycle);
set_flags(hints);
}
inline JSLocale::HourCycle JSLocale::hour_cycle() const {
return HourCycleBits::decode(flags());
}
inline void JSLocale::set_numeric(Numeric numeric) {
DCHECK_GT(Numeric::COUNT, numeric);
int hints = flags();
hints = NumericBits::update(hints, numeric);
set_flags(hints);
}
inline JSLocale::Numeric JSLocale::numeric() const {
return NumericBits::decode(flags());
}
} // namespace internal
} // namespace v8

View File

@ -35,6 +35,26 @@ namespace internal {
namespace {
JSLocale::CaseFirst GetCaseFirst(const char* str) {
if (strcmp(str, "upper") == 0) return JSLocale::CaseFirst::UPPER;
if (strcmp(str, "lower") == 0) return JSLocale::CaseFirst::LOWER;
if (strcmp(str, "false") == 0) return JSLocale::CaseFirst::FALSE_VALUE;
UNREACHABLE();
}
JSLocale::HourCycle GetHourCycle(const char* str) {
if (strcmp(str, "h11") == 0) return JSLocale::HourCycle::H11;
if (strcmp(str, "h12") == 0) return JSLocale::HourCycle::H12;
if (strcmp(str, "h23") == 0) return JSLocale::HourCycle::H23;
if (strcmp(str, "h24") == 0) return JSLocale::HourCycle::H24;
UNREACHABLE();
}
JSLocale::Numeric GetNumeric(const char* str) {
return strcmp(str, "true") == 0 ? JSLocale::Numeric::TRUE_VALUE
: JSLocale::Numeric::FALSE_VALUE;
}
struct OptionData {
const char* name;
const char* key;
@ -138,19 +158,23 @@ bool PopulateLocaleWithUnicodeTags(Isolate* isolate, const char* icu_locale,
if (bcp47_key) {
const char* bcp47_value = uloc_toUnicodeLocaleType(bcp47_key, value);
if (bcp47_value) {
Handle<String> bcp47_handle =
factory->NewStringFromAsciiChecked(bcp47_value);
if (strcmp(bcp47_key, "kn") == 0) {
locale_holder->set_numeric(*bcp47_handle);
locale_holder->set_numeric(GetNumeric(bcp47_value));
} else if (strcmp(bcp47_key, "ca") == 0) {
Handle<String> bcp47_handle =
factory->NewStringFromAsciiChecked(bcp47_value);
locale_holder->set_calendar(*bcp47_handle);
} else if (strcmp(bcp47_key, "kf") == 0) {
locale_holder->set_case_first(*bcp47_handle);
locale_holder->set_case_first(GetCaseFirst(bcp47_value));
} else if (strcmp(bcp47_key, "co") == 0) {
Handle<String> bcp47_handle =
factory->NewStringFromAsciiChecked(bcp47_value);
locale_holder->set_collation(*bcp47_handle);
} else if (strcmp(bcp47_key, "hc") == 0) {
locale_holder->set_hour_cycle(*bcp47_handle);
locale_holder->set_hour_cycle(GetHourCycle(bcp47_value));
} else if (strcmp(bcp47_key, "nu") == 0) {
Handle<String> bcp47_handle =
factory->NewStringFromAsciiChecked(bcp47_value);
locale_holder->set_numbering_system(*bcp47_handle);
}
}
@ -167,6 +191,7 @@ MaybeHandle<JSLocale> JSLocale::Initialize(Isolate* isolate,
Handle<JSLocale> locale_holder,
Handle<String> locale,
Handle<JSReceiver> options) {
locale_holder->set_flags(0);
static const char* const kMethod = "Intl.Locale";
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
UErrorCode status = U_ZERO_ERROR;
@ -336,5 +361,46 @@ Handle<String> JSLocale::Minimize(Isolate* isolate, String* locale) {
return MorphLocale(isolate, locale, uloc_minimizeSubtags);
}
Handle<String> JSLocale::CaseFirstAsString() const {
switch (case_first()) {
case CaseFirst::UPPER:
return GetReadOnlyRoots().upper_string_handle();
case CaseFirst::LOWER:
return GetReadOnlyRoots().lower_string_handle();
case CaseFirst::FALSE_VALUE:
return GetReadOnlyRoots().false_string_handle();
case CaseFirst::COUNT:
UNREACHABLE();
}
}
Handle<String> JSLocale::HourCycleAsString() const {
switch (hour_cycle()) {
case HourCycle::H11:
return GetReadOnlyRoots().h11_string_handle();
case HourCycle::H12:
return GetReadOnlyRoots().h12_string_handle();
case HourCycle::H23:
return GetReadOnlyRoots().h23_string_handle();
case HourCycle::H24:
return GetReadOnlyRoots().h24_string_handle();
case HourCycle::COUNT:
UNREACHABLE();
}
}
Handle<String> JSLocale::NumericAsString() const {
switch (numeric()) {
case Numeric::NOTSET:
return GetReadOnlyRoots().undefined_string_handle();
case Numeric::TRUE_VALUE:
return GetReadOnlyRoots().true_string_handle();
case Numeric::FALSE_VALUE:
return GetReadOnlyRoots().false_string_handle();
case Numeric::COUNT:
UNREACHABLE();
}
}
} // namespace internal
} // namespace v8

View File

@ -32,6 +32,10 @@ class JSLocale : public JSObject {
static Handle<String> Maximize(Isolate* isolate, String* locale);
static Handle<String> Minimize(Isolate* isolate, String* locale);
Handle<String> CaseFirstAsString() const;
Handle<String> NumericAsString() const;
Handle<String> HourCycleAsString() const;
DECL_CAST(JSLocale)
// Locale accessors.
@ -43,12 +47,64 @@ class JSLocale : public JSObject {
// Unicode extension accessors.
DECL_ACCESSORS(calendar, Object)
DECL_ACCESSORS(case_first, Object)
DECL_ACCESSORS(collation, Object)
DECL_ACCESSORS(hour_cycle, Object)
DECL_ACCESSORS(numeric, Object)
DECL_ACCESSORS(numbering_system, Object)
// CaseFirst: "kf"
//
// ecma402 #sec-Intl.Locale.prototype.caseFirst
enum class CaseFirst {
UPPER, // upper case sorts before lower case
LOWER, // lower case sorts before upper case
// (compiler does not like FALSE so we have to name it FALSE_VALUE)
FALSE_VALUE, // Turn the feature off
COUNT
};
inline void set_case_first(CaseFirst case_first);
inline CaseFirst case_first() const;
// Numeric: 'kn"
//
// ecma402 #sec-Intl.Locale.prototype.numeric
enum class Numeric { NOTSET, TRUE_VALUE, FALSE_VALUE, COUNT };
inline void set_numeric(Numeric numeric);
inline Numeric numeric() const;
// CaseFirst: "hc"
//
// ecma402 #sec-Intl.Locale.prototype.hourCycle
enum class HourCycle {
H11, // 12-hour format start with hour 0 and go up to 11.
H12, // 12-hour format start with hour 1 and go up to 12.
H23, // 24-hour format start with hour 0 and go up to 23.
H24, // 24-hour format start with hour 1 and go up to 24.
COUNT
};
inline void set_hour_cycle(HourCycle hour_cycle);
inline HourCycle hour_cycle() const;
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _) \
V(CaseFirstBits, CaseFirst, 2, _) \
V(NumericBits, Numeric, 2, _) \
V(HourCycleBits, HourCycle, 2, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
STATIC_ASSERT(CaseFirst::UPPER <= CaseFirstBits::kMax);
STATIC_ASSERT(CaseFirst::LOWER <= CaseFirstBits::kMax);
STATIC_ASSERT(CaseFirst::FALSE_VALUE <= CaseFirstBits::kMax);
STATIC_ASSERT(Numeric::NOTSET <= NumericBits::kMax);
STATIC_ASSERT(Numeric::FALSE_VALUE <= NumericBits::kMax);
STATIC_ASSERT(Numeric::TRUE_VALUE <= NumericBits::kMax);
STATIC_ASSERT(HourCycle::H11 <= HourCycleBits::kMax);
STATIC_ASSERT(HourCycle::H12 <= HourCycleBits::kMax);
STATIC_ASSERT(HourCycle::H23 <= HourCycleBits::kMax);
STATIC_ASSERT(HourCycle::H24 <= HourCycleBits::kMax);
// [flags] Bit field containing various flags about the function.
DECL_INT_ACCESSORS(flags)
DECL_PRINTER(JSLocale)
DECL_VERIFIER(JSLocale)
@ -61,12 +117,10 @@ class JSLocale : public JSObject {
static const int kBaseNameOffset = kRegionOffset + kPointerSize;
static const int kLocaleOffset = kBaseNameOffset + kPointerSize;
// Unicode extension fields.
static const int kCalendarOffset = kLocaleOffset + kPointerSize;
static const int kCaseFirstOffset = kCalendarOffset + kPointerSize;
static const int kCollationOffset = kCaseFirstOffset + kPointerSize;
static const int kHourCycleOffset = kCollationOffset + kPointerSize;
static const int kNumericOffset = kHourCycleOffset + kPointerSize;
static const int kNumberingSystemOffset = kNumericOffset + kPointerSize;
static const int kFlagsOffset = kLocaleOffset + kPointerSize;
static const int kCalendarOffset = kFlagsOffset + kPointerSize;
static const int kCollationOffset = kCalendarOffset + kPointerSize;
static const int kNumberingSystemOffset = kCollationOffset + kPointerSize;
// Final size.
static const int kSize = kNumberingSystemOffset + kPointerSize;

View File

@ -24,7 +24,7 @@ assertEquals('buddhist', locale.calendar);
assertEquals('phonebk', locale.collation);
assertEquals('h23', locale.hourCycle);
assertEquals('upper', locale.caseFirst);
assertEquals('true', locale.numeric);
assertEquals(true, locale.numeric);
assertEquals('roman', locale.numberingSystem);
// Not defined, expected to undefined.
assertEquals(undefined, locale.currency);

View File

@ -598,6 +598,9 @@
'intl402/Locale/getters-grandfathered': [FAIL],
'intl402/Locale/likely-subtags-grandfathered': [FAIL],
# Wrong test see https://github.com/tc39/test262/pull/1835
'intl402/Locale/constructor-options-numeric-valid': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=6705
'built-ins/Object/assign/strings-and-symbol-order': [FAIL],

View File

@ -291,41 +291,41 @@ KNOWN_MAPS = {
("RO_SPACE", 0x04761): (171, "Tuple2Map"),
("RO_SPACE", 0x04801): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x04af1): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x06e19): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x06e69): (154, "AccessorInfoMap"),
("RO_SPACE", 0x06eb9): (155, "AccessorPairMap"),
("RO_SPACE", 0x06f09): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x06f59): (157, "AllocationMementoMap"),
("RO_SPACE", 0x06fa9): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x06ff9): (159, "DebugInfoMap"),
("RO_SPACE", 0x07049): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x07099): (162, "InterpreterDataMap"),
("RO_SPACE", 0x070e9): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x07139): (164, "ModuleMap"),
("RO_SPACE", 0x07189): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x071d9): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x07229): (167, "PromiseReactionMap"),
("RO_SPACE", 0x07279): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x072c9): (169, "ScriptMap"),
("RO_SPACE", 0x07319): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x07369): (172, "Tuple3Map"),
("RO_SPACE", 0x073b9): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x07409): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x07459): (176, "CallableTaskMap"),
("RO_SPACE", 0x074a9): (177, "CallbackTaskMap"),
("RO_SPACE", 0x074f9): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x07549): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x07599): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x075e9): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x07639): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x07689): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x076d9): (214, "LoadHandler1Map"),
("RO_SPACE", 0x07729): (214, "LoadHandler2Map"),
("RO_SPACE", 0x07779): (214, "LoadHandler3Map"),
("RO_SPACE", 0x077c9): (221, "StoreHandler0Map"),
("RO_SPACE", 0x07819): (221, "StoreHandler1Map"),
("RO_SPACE", 0x07869): (221, "StoreHandler2Map"),
("RO_SPACE", 0x078b9): (221, "StoreHandler3Map"),
("RO_SPACE", 0x06ea9): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x06ef9): (154, "AccessorInfoMap"),
("RO_SPACE", 0x06f49): (155, "AccessorPairMap"),
("RO_SPACE", 0x06f99): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x06fe9): (157, "AllocationMementoMap"),
("RO_SPACE", 0x07039): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x07089): (159, "DebugInfoMap"),
("RO_SPACE", 0x070d9): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x07129): (162, "InterpreterDataMap"),
("RO_SPACE", 0x07179): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x071c9): (164, "ModuleMap"),
("RO_SPACE", 0x07219): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x07269): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x072b9): (167, "PromiseReactionMap"),
("RO_SPACE", 0x07309): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x07359): (169, "ScriptMap"),
("RO_SPACE", 0x073a9): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x073f9): (172, "Tuple3Map"),
("RO_SPACE", 0x07449): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x07499): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x074e9): (176, "CallableTaskMap"),
("RO_SPACE", 0x07539): (177, "CallbackTaskMap"),
("RO_SPACE", 0x07589): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x075d9): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x07629): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x07679): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x076c9): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x07719): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x07769): (214, "LoadHandler1Map"),
("RO_SPACE", 0x077b9): (214, "LoadHandler2Map"),
("RO_SPACE", 0x07809): (214, "LoadHandler3Map"),
("RO_SPACE", 0x07859): (221, "StoreHandler0Map"),
("RO_SPACE", 0x078a9): (221, "StoreHandler1Map"),
("RO_SPACE", 0x078f9): (221, "StoreHandler2Map"),
("RO_SPACE", 0x07949): (221, "StoreHandler3Map"),
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
}