Commit 12f04d81 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Use icu::Locale as storage in JSLocale

Remove flags and all string in JSLocale
This does not change the logic of Intl.Locale constructor
but only the way we store the information.
Preparation for logic rewrite that sync with latest spec.

Bug: v8:7684
Change-Id: Ib61705eaf00e5bcf63443c55c29f0b0b61f8e4c9
Reviewed-on: https://chromium-review.googlesource.com/c/1377996
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58386}
parent 5b607f19
......@@ -537,10 +537,9 @@ MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
Handle<String> locale_string;
// 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal
// slot, then
if (tag->IsJSLocale() && Handle<JSLocale>::cast(tag)->locale()->IsString()) {
if (tag->IsJSLocale()) {
// a. Let tag be tag.[[Locale]].
locale_string =
Handle<String>(Handle<JSLocale>::cast(tag)->locale(), isolate);
locale_string = JSLocale::ToString(isolate, Handle<JSLocale>::cast(tag));
} else { // 9. Else,
// a. Let tag be ? ToString(tag).
ASSIGN_RETURN_ON_EXCEPTION(isolate, locale_string,
......@@ -589,26 +588,26 @@ BUILTIN(LocaleConstructor) {
BUILTIN(LocalePrototypeMaximize) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.maximize");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize");
Handle<JSFunction> constructor(
isolate->native_context()->intl_locale_function(), isolate);
Handle<String> locale_str = JSLocale::ToString(isolate, locale);
RETURN_RESULT_OR_FAILURE(
isolate,
CreateLocale(isolate, constructor, constructor,
JSLocale::Maximize(isolate, locale_holder->locale()),
isolate->factory()->NewJSObjectWithNullProto()));
isolate, CreateLocale(isolate, constructor, constructor,
JSLocale::Maximize(isolate, *locale_str),
isolate->factory()->NewJSObjectWithNullProto()));
}
BUILTIN(LocalePrototypeMinimize) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.minimize");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize");
Handle<JSFunction> constructor(
isolate->native_context()->intl_locale_function(), isolate);
Handle<String> locale_str = JSLocale::ToString(isolate, locale);
RETURN_RESULT_OR_FAILURE(
isolate,
CreateLocale(isolate, constructor, constructor,
JSLocale::Minimize(isolate, locale_holder->locale()),
isolate->factory()->NewJSObjectWithNullProto()));
isolate, CreateLocale(isolate, constructor, constructor,
JSLocale::Minimize(isolate, *locale_str),
isolate->factory()->NewJSObjectWithNullProto()));
}
BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
......@@ -658,89 +657,79 @@ BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
BUILTIN(LocalePrototypeLanguage) {
HandleScope scope(isolate);
// CHECK_RECEIVER will case locale_holder to JSLocale.
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.language");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.language");
return locale_holder->language();
return *JSLocale::Language(isolate, locale);
}
BUILTIN(LocalePrototypeScript) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.script");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.script");
return locale_holder->script();
return *JSLocale::Script(isolate, locale);
}
BUILTIN(LocalePrototypeRegion) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.region");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.region");
return locale_holder->region();
return *JSLocale::Region(isolate, locale);
}
BUILTIN(LocalePrototypeBaseName) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.baseName");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.baseName");
return locale_holder->base_name();
return *JSLocale::BaseName(isolate, locale);
}
BUILTIN(LocalePrototypeCalendar) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.calendar");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendar");
return locale_holder->calendar();
return *JSLocale::Calendar(isolate, locale);
}
BUILTIN(LocalePrototypeCaseFirst) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.caseFirst");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.caseFirst");
return *(locale_holder->CaseFirstAsString());
return *JSLocale::CaseFirst(isolate, locale);
}
BUILTIN(LocalePrototypeCollation) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.collation");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collation");
return locale_holder->collation();
return *JSLocale::Collation(isolate, locale);
}
BUILTIN(LocalePrototypeHourCycle) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.hourCycle");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycle");
return *(locale_holder->HourCycleAsString());
return *JSLocale::HourCycle(isolate, locale);
}
BUILTIN(LocalePrototypeNumeric) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.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();
}
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numeric");
return *JSLocale::Numeric(isolate, locale);
}
BUILTIN(LocalePrototypeNumberingSystem) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder,
"Intl.Locale.prototype.numberingSystem");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystem");
return locale_holder->numbering_system();
return *JSLocale::NumberingSystem(isolate, locale);
}
BUILTIN(LocalePrototypeToString) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.toString");
CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.toString");
return locale_holder->locale();
return *JSLocale::ToString(isolate, locale);
}
BUILTIN(RelativeTimeFormatConstructor) {
......
......@@ -2089,16 +2089,7 @@ void JSListFormat::JSListFormatVerify(Isolate* isolate) {
void JSLocale::JSLocaleVerify(Isolate* isolate) {
JSObjectVerify(isolate);
VerifyObjectField(isolate, kLanguageOffset);
VerifyObjectField(isolate, kScriptOffset);
VerifyObjectField(isolate, kRegionOffset);
VerifyObjectField(isolate, kBaseNameOffset);
VerifyObjectField(isolate, kLocaleOffset);
// Unicode extension fields.
VerifyObjectField(isolate, kFlagsOffset);
VerifyObjectField(isolate, kCalendarOffset);
VerifyObjectField(isolate, kCollationOffset);
VerifyObjectField(isolate, kNumberingSystemOffset);
VerifyObjectField(isolate, kICULocaleOffset);
}
void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
......
......@@ -2065,18 +2065,8 @@ void JSListFormat::JSListFormatPrint(std::ostream& os) { // NOLINT
void JSLocale::JSLocalePrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, *this, "JSLocale");
os << "\n - language: " << Brief(language());
os << "\n - script: " << Brief(script());
os << "\n - region: " << Brief(region());
os << "\n - baseName: " << Brief(base_name());
os << "\n - locale: " << Brief(locale());
os << "\n - calendar: " << Brief(calendar());
os << "\n - caseFirst: " << CaseFirstAsString();
os << "\n - collation: " << Brief(collation());
os << "\n - hourCycle: " << HourCycleAsString();
os << "\n - numeric: " << NumericAsString();
os << "\n - numberingSystem: " << Brief(numbering_system());
os << "\n";
os << "\n - icu locale: " << Brief(icu_locale());
JSObjectPrintBody(os, *this);
}
void JSNumberFormat::JSNumberFormatPrint(std::ostream& os) { // NOLINT
......
......@@ -21,54 +21,10 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSLocale, JSObject)
// Base locale accessors.
ACCESSORS(JSLocale, language, Object, kLanguageOffset);
ACCESSORS(JSLocale, script, Object, kScriptOffset);
ACCESSORS(JSLocale, region, Object, kRegionOffset);
ACCESSORS(JSLocale, base_name, Object, kBaseNameOffset);
ACCESSORS2(JSLocale, locale, String, kLocaleOffset);
// Unicode extension accessors.
ACCESSORS(JSLocale, calendar, Object, kCalendarOffset);
ACCESSORS(JSLocale, collation, Object, kCollationOffset);
ACCESSORS(JSLocale, numbering_system, Object, kNumberingSystemOffset);
SMI_ACCESSORS(JSLocale, flags, kFlagsOffset)
ACCESSORS2(JSLocale, icu_locale, Managed<icu::Locale>, kICULocaleOffset);
CAST_ACCESSOR2(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
......
This diff is collapsed.
......@@ -13,11 +13,15 @@
#include "src/heap/factory.h"
#include "src/isolate.h"
#include "src/objects.h"
#include "unicode/unistr.h"
#include "src/objects/managed.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
class Locale;
}
namespace v8 {
namespace internal {
......@@ -32,97 +36,29 @@ 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;
static Handle<Object> Language(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Script(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Region(Isolate* isolate, Handle<JSLocale> locale);
static Handle<String> BaseName(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Calendar(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> CaseFirst(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Collation(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> HourCycle(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> Numeric(Isolate* isolate, Handle<JSLocale> locale);
static Handle<Object> NumberingSystem(Isolate* isolate,
Handle<JSLocale> locale);
static Handle<String> ToString(Isolate* isolate, Handle<JSLocale> locale);
DECL_CAST2(JSLocale)
// Locale accessors.
DECL_ACCESSORS(language, Object)
DECL_ACCESSORS(script, Object)
DECL_ACCESSORS(region, Object)
DECL_ACCESSORS(base_name, Object)
DECL_ACCESSORS2(locale, String)
// Unicode extension accessors.
DECL_ACCESSORS(calendar, Object)
DECL_ACCESSORS(collation, 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_ACCESSORS2(icu_locale, Managed<icu::Locale>)
DECL_PRINTER(JSLocale)
DECL_VERIFIER(JSLocale)
// Layout description.
#define JS_LOCALE_FIELDS(V) \
V(kJSLocaleOffset, kTaggedSize) \
/* Locale fields. */ \
V(kLanguageOffset, kTaggedSize) \
V(kScriptOffset, kTaggedSize) \
V(kRegionOffset, kTaggedSize) \
V(kBaseNameOffset, kTaggedSize) \
V(kLocaleOffset, kTaggedSize) \
/* Unicode extension fields. */ \
V(kFlagsOffset, kTaggedSize) \
V(kCalendarOffset, kTaggedSize) \
V(kCollationOffset, kTaggedSize) \
V(kNumberingSystemOffset, kTaggedSize) \
/* Header size. */ \
#define JS_LOCALE_FIELDS(V) \
V(kICULocaleOffset, kTaggedSize) \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_LOCALE_FIELDS)
......
......@@ -19,6 +19,6 @@ let locale = new Intl.Locale('sr-cyrl-rs-t-ja-u-ca-islamic-x-whatever', {
});
let expected =
'sr-Cyrl-RS-t-ja-u-ca-buddhist-co-phonebk-hc-h23-kf-upper-kn-true-nu-roman-x-whatever';
'sr-Cyrl-RS-t-ja-u-ca-buddhist-co-phonebk-hc-h23-kf-upper-kn-nu-roman-x-whatever';
assertEquals(expected, locale.toString());
......@@ -618,10 +618,6 @@
'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],
'intl402/Locale/constructor-options-numeric-undefined': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=6705
'built-ins/Object/assign/strings-and-symbol-order': [FAIL],
......
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