Implementing Intl.Locale proposal.
https://github.com/tc39/proposal-intl-locale Rename locale property to baseName to better reflect the intented use case and the change in spec. TBR: bmeurer@chromium.org Bug: v8:7684 Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng Change-Id: I91b630b49ce73abcebd6040ec968c91d75cff879 Reviewed-on: https://chromium-review.googlesource.com/1014411 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#53193}
This commit is contained in:
parent
aca333123d
commit
ab72273692
6
BUILD.gn
6
BUILD.gn
@ -2087,6 +2087,9 @@ v8_source_set("v8_base") {
|
||||
"src/objects/js-array.h",
|
||||
"src/objects/js-collection-inl.h",
|
||||
"src/objects/js-collection.h",
|
||||
"src/objects/js-locale-inl.h",
|
||||
"src/objects/js-locale.cc",
|
||||
"src/objects/js-locale.h",
|
||||
"src/objects/js-promise-inl.h",
|
||||
"src/objects/js-promise.h",
|
||||
"src/objects/js-regexp-inl.h",
|
||||
@ -2761,6 +2764,9 @@ v8_source_set("v8_base") {
|
||||
"src/intl.h",
|
||||
"src/objects/intl-objects.cc",
|
||||
"src/objects/intl-objects.h",
|
||||
"src/objects/js-locale-inl.h",
|
||||
"src/objects/js-locale.cc",
|
||||
"src/objects/js-locale.h",
|
||||
"src/runtime/runtime-intl.cc",
|
||||
]
|
||||
}
|
||||
|
@ -20,16 +20,16 @@
|
||||
#include "src/heap/heap.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/objects/api-callbacks.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/intl-objects.h"
|
||||
#include "src/objects/js-locale.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-regexp.h"
|
||||
#include "src/objects/templates.h"
|
||||
#include "src/snapshot/natives.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
#include "src/wasm/wasm-js.h"
|
||||
|
||||
#if V8_INTL_SUPPORT
|
||||
#include "src/objects/intl-objects.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -4455,6 +4455,62 @@ void Genesis::InitializeGlobal_harmony_bigint() {
|
||||
Builtins::kDataViewPrototypeSetBigUint64, 2, false);
|
||||
}
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_locale() {
|
||||
if (!FLAG_harmony_locale) return;
|
||||
|
||||
Handle<JSObject> intl = Handle<JSObject>::cast(
|
||||
JSReceiver::GetProperty(
|
||||
Handle<JSReceiver>(native_context()->global_object()),
|
||||
factory()->InternalizeUtf8String("Intl"))
|
||||
.ToHandleChecked());
|
||||
|
||||
Handle<JSFunction> locale_fun = InstallFunction(
|
||||
intl, "Locale", JS_INTL_LOCALE_TYPE, JSLocale::kSize, 0,
|
||||
factory()->the_hole_value(), Builtins::kLocaleConstructor);
|
||||
InstallWithIntrinsicDefaultProto(isolate(), locale_fun,
|
||||
Context::INTL_LOCALE_FUNCTION_INDEX);
|
||||
locale_fun->shared()->set_length(1);
|
||||
locale_fun->shared()->DontAdaptArguments();
|
||||
|
||||
// Setup %LocalePrototype%.
|
||||
Handle<JSObject> prototype(JSObject::cast(locale_fun->instance_prototype()));
|
||||
|
||||
// Install the @@toStringTag property on the {prototype}.
|
||||
JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
|
||||
factory()->NewStringFromAsciiChecked("Locale"),
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
SimpleInstallFunction(prototype, "toString",
|
||||
Builtins::kLocalePrototypeToString, 0, false);
|
||||
// Base locale getters.
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("language"),
|
||||
Builtins::kLocalePrototypeLanguage, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("script"),
|
||||
Builtins::kLocalePrototypeScript, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("region"),
|
||||
Builtins::kLocalePrototypeRegion, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("baseName"),
|
||||
Builtins::kLocalePrototypeBaseName, true);
|
||||
// Unicode extension getters.
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("calendar"),
|
||||
Builtins::kLocalePrototypeCalendar, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("caseFirst"),
|
||||
Builtins::kLocalePrototypeCaseFirst, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("collation"),
|
||||
Builtins::kLocalePrototypeCollation, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("hourCycle"),
|
||||
Builtins::kLocalePrototypeHourCycle, true);
|
||||
SimpleInstallGetter(prototype, factory()->InternalizeUtf8String("numeric"),
|
||||
Builtins::kLocalePrototypeNumeric, true);
|
||||
SimpleInstallGetter(prototype,
|
||||
factory()->InternalizeUtf8String("numberingSystem"),
|
||||
Builtins::kLocalePrototypeNumberingSystem, true);
|
||||
}
|
||||
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
Handle<JSFunction> Genesis::CreateArrayBuffer(
|
||||
Handle<String> name, ArrayBufferKind array_buffer_kind) {
|
||||
// Create the %ArrayBufferPrototype%
|
||||
|
@ -1287,7 +1287,20 @@ namespace internal {
|
||||
/* ecma402 #sec-intl.numberformat.prototype.formattoparts */ \
|
||||
CPP(NumberFormatPrototypeFormatToParts) \
|
||||
/* ecma402 #sec-intl.datetimeformat.prototype.formattoparts */ \
|
||||
CPP(DateTimeFormatPrototypeFormatToParts)
|
||||
CPP(DateTimeFormatPrototypeFormatToParts) \
|
||||
/* ecma402 #new proposal */ \
|
||||
CPP(LocaleConstructor) \
|
||||
CPP(LocalePrototypeLanguage) \
|
||||
CPP(LocalePrototypeScript) \
|
||||
CPP(LocalePrototypeRegion) \
|
||||
CPP(LocalePrototypeBaseName) \
|
||||
CPP(LocalePrototypeCalendar) \
|
||||
CPP(LocalePrototypeCaseFirst) \
|
||||
CPP(LocalePrototypeCollation) \
|
||||
CPP(LocalePrototypeHourCycle) \
|
||||
CPP(LocalePrototypeNumeric) \
|
||||
CPP(LocalePrototypeNumberingSystem) \
|
||||
CPP(LocalePrototypeToString)
|
||||
#else
|
||||
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
|
||||
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/intl.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/intl-objects.h"
|
||||
#include "src/objects/js-locale-inl.h"
|
||||
|
||||
#include "unicode/datefmt.h"
|
||||
#include "unicode/decimfmt.h"
|
||||
@ -505,5 +506,138 @@ BUILTIN(DateTimeFormatPrototypeFormatToParts) {
|
||||
return FormatDateToParts(isolate, date_format, date_value);
|
||||
}
|
||||
|
||||
// Intl.Locale implementation
|
||||
BUILTIN(LocaleConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
"Intl.Locale")));
|
||||
} else { // [[Construct]]
|
||||
Handle<JSFunction> target = args.target();
|
||||
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
|
||||
Handle<JSObject> result;
|
||||
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
|
||||
JSObject::New(target, new_target));
|
||||
|
||||
Handle<Object> tag = args.atOrUndefined(isolate, 1);
|
||||
Handle<Object> options = args.atOrUndefined(isolate, 2);
|
||||
|
||||
// First parameter is a locale, as a string/object. Can't be empty.
|
||||
if (!tag->IsName() && !tag->IsJSReceiver()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty));
|
||||
}
|
||||
|
||||
Handle<String> locale_string;
|
||||
if (tag->IsJSLocale() &&
|
||||
Handle<JSLocale>::cast(tag)->locale()->IsString()) {
|
||||
locale_string = Handle<String>(Handle<JSLocale>::cast(tag)->locale());
|
||||
} else {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_string,
|
||||
Object::ToString(isolate, tag));
|
||||
}
|
||||
|
||||
Handle<JSReceiver> options_object;
|
||||
if (options->IsNullOrUndefined(isolate)) {
|
||||
// Make empty options bag.
|
||||
options_object = isolate->factory()->NewJSObjectWithNullProto();
|
||||
} else {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, options_object,
|
||||
Object::ToObject(isolate, options));
|
||||
}
|
||||
|
||||
if (!JSLocale::InitializeLocale(isolate, Handle<JSLocale>::cast(result),
|
||||
locale_string, options_object)) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kLocaleBadParameters));
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
}
|
||||
|
||||
// Locale getters.
|
||||
BUILTIN(LocalePrototypeLanguage) {
|
||||
HandleScope scope(isolate);
|
||||
// CHECK_RECEIVER will case locale_holder to JSLocale.
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.language");
|
||||
|
||||
return locale_holder->language();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeScript) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.script");
|
||||
|
||||
return locale_holder->script();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeRegion) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.region");
|
||||
|
||||
return locale_holder->region();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeBaseName) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.baseName");
|
||||
|
||||
return locale_holder->base_name();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeCalendar) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.calendar");
|
||||
|
||||
return locale_holder->calendar();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeCaseFirst) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.caseFirst");
|
||||
|
||||
return locale_holder->case_first();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeCollation) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.collation");
|
||||
|
||||
return locale_holder->collation();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeHourCycle) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.hourCycle");
|
||||
|
||||
return locale_holder->hour_cycle();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeNumeric) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.numeric");
|
||||
|
||||
return locale_holder->numeric();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeNumberingSystem) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder,
|
||||
"Intl.Locale.prototype.numberingSystem");
|
||||
|
||||
return locale_holder->numbering_system();
|
||||
}
|
||||
|
||||
BUILTIN(LocalePrototypeToString) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.toString");
|
||||
|
||||
return locale_holder->locale();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -216,6 +216,9 @@ Type::bitset BitsetType::Lub(i::Map* map) {
|
||||
case JS_VALUE_TYPE:
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
case JS_DATE_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
#endif // V8_INTL_SUPPORT
|
||||
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
|
||||
case JS_GENERATOR_OBJECT_TYPE:
|
||||
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
|
||||
|
@ -22,7 +22,6 @@ enum ContextLookupFlags {
|
||||
FOLLOW_CHAINS = FOLLOW_CONTEXT_CHAIN | FOLLOW_PROTOTYPE_CHAIN,
|
||||
};
|
||||
|
||||
|
||||
// Heap-allocated activation contexts.
|
||||
//
|
||||
// Contexts are implemented as FixedArray objects; the Context
|
||||
@ -203,6 +202,7 @@ enum ContextLookupFlags {
|
||||
intl_date_time_format_function) \
|
||||
V(INTL_NUMBER_FORMAT_FUNCTION_INDEX, JSFunction, \
|
||||
intl_number_format_function) \
|
||||
V(INTL_LOCALE_FUNCTION_INDEX, JSFunction, intl_locale_function) \
|
||||
V(INTL_COLLATOR_FUNCTION_INDEX, JSFunction, intl_collator_function) \
|
||||
V(INTL_PLURAL_RULES_FUNCTION_INDEX, JSFunction, intl_plural_rules_function) \
|
||||
V(INTL_V8_BREAK_ITERATOR_FUNCTION_INDEX, JSFunction, \
|
||||
@ -434,7 +434,7 @@ class ScriptContextTable : public FixedArray {
|
||||
// Script contexts from all top-level scripts are gathered in
|
||||
// ScriptContextTable.
|
||||
|
||||
class Context: public FixedArray {
|
||||
class Context : public FixedArray {
|
||||
public:
|
||||
// Conversions.
|
||||
static inline Context* cast(Object* context);
|
||||
@ -451,7 +451,7 @@ class Context: public FixedArray {
|
||||
EXTENSION_INDEX,
|
||||
NATIVE_CONTEXT_INDEX,
|
||||
|
||||
// These slots are only in native contexts.
|
||||
// These slots are only in native contexts.
|
||||
#define NATIVE_CONTEXT_SLOT(index, type, name) index,
|
||||
NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_SLOT)
|
||||
#undef NATIVE_CONTEXT_SLOT
|
||||
|
@ -208,12 +208,20 @@ DEFINE_IMPLICATION(harmony_class_fields, harmony_private_fields)
|
||||
// Update bootstrapper.cc whenever adding a new feature flag.
|
||||
|
||||
// Features that are still work in progress (behind individual flags).
|
||||
#define HARMONY_INPROGRESS(V) \
|
||||
#define HARMONY_INPROGRESS_BASE(V) \
|
||||
V(harmony_do_expressions, "harmony do-expressions") \
|
||||
V(harmony_class_fields, "harmony fields in class literals") \
|
||||
V(harmony_static_fields, "harmony static fields in class literals") \
|
||||
V(harmony_array_flatten, "harmony Array.prototype.flat{ten,Map}")
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define HARMONY_INPROGRESS(V) \
|
||||
HARMONY_INPROGRESS_BASE(V) \
|
||||
V(harmony_locale, "Intl.Locale")
|
||||
#else
|
||||
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
|
||||
#endif
|
||||
|
||||
// Features that are complete (but still behind --harmony/es-staging flag).
|
||||
#define HARMONY_STAGED(V) \
|
||||
V(harmony_restrict_constructor_return, \
|
||||
|
@ -341,6 +341,9 @@ class ErrorUtils : public AllStatic {
|
||||
T(IteratorSymbolNonCallable, "Found non-callable @@iterator") \
|
||||
T(IteratorValueNotAnObject, "Iterator value % is not an entry object") \
|
||||
T(LanguageID, "Language ID should be string or object.") \
|
||||
T(LocaleNotEmpty, \
|
||||
"First argument to Intl.Locale constructor can't be empty or missing") \
|
||||
T(LocaleBadParameters, "Incorrect locale information provided") \
|
||||
T(MapperFunctionNonCallable, "flatMap mapper function is not callable") \
|
||||
T(MethodCalledOnWrongObject, \
|
||||
"Method % called on a non-object or on a wrong type of object.") \
|
||||
|
@ -620,6 +620,9 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
#endif // V8_INTL_SUPPORT
|
||||
case WASM_GLOBAL_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include "src/objects/data-handler-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/literal-objects.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-locale-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/maybe-object.h"
|
||||
#include "src/objects/microtask-inl.h"
|
||||
#include "src/objects/module.h"
|
||||
@ -314,6 +317,11 @@ void HeapObject::HeapObjectVerify() {
|
||||
case CODE_DATA_CONTAINER_TYPE:
|
||||
CodeDataContainer::cast(this)->CodeDataContainerVerify();
|
||||
break;
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
JSLocale::cast(this)->JSLocaleVerify();
|
||||
break;
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#define MAKE_STRUCT_CASE(NAME, Name, name) \
|
||||
case NAME##_TYPE: \
|
||||
@ -1771,6 +1779,23 @@ void InterpreterData::InterpreterDataVerify() {
|
||||
CHECK(interpreter_trampoline()->IsCode());
|
||||
}
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
void JSLocale::JSLocaleVerify() {
|
||||
VerifyObjectField(kLanguageOffset);
|
||||
VerifyObjectField(kScriptOffset);
|
||||
VerifyObjectField(kRegionOffset);
|
||||
VerifyObjectField(kBaseNameOffset);
|
||||
VerifyObjectField(kLocaleOffset);
|
||||
// Unicode extension fields.
|
||||
VerifyObjectField(kCalendarOffset);
|
||||
VerifyObjectField(kCaseFirstOffset);
|
||||
VerifyObjectField(kCollationOffset);
|
||||
VerifyObjectField(kHourCycleOffset);
|
||||
VerifyObjectField(kNumericOffset);
|
||||
VerifyObjectField(kNumberingSystemOffset);
|
||||
}
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#endif // VERIFY_HEAP
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -103,6 +103,9 @@ TYPE_CHECKER(JSDate, JS_DATE_TYPE)
|
||||
TYPE_CHECKER(JSError, JS_ERROR_TYPE)
|
||||
TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
|
||||
TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
TYPE_CHECKER(JSLocale, JS_INTL_LOCALE_TYPE)
|
||||
#endif // V8_INTL_SUPPORT
|
||||
TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
|
||||
TYPE_CHECKER(JSStringIterator, JS_STRING_ITERATOR_TYPE)
|
||||
TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-locale-inl.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/microtask-inl.h"
|
||||
#include "src/objects/promise-inl.h"
|
||||
#include "src/ostreams.h"
|
||||
@ -257,6 +260,11 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case JS_DATA_VIEW_TYPE:
|
||||
JSDataView::cast(this)->JSDataViewPrint(os);
|
||||
break;
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
JSLocale::cast(this)->JSLocalePrint(os);
|
||||
break;
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#define MAKE_STRUCT_CASE(NAME, Name, name) \
|
||||
case NAME##_TYPE: \
|
||||
Name::cast(this)->Name##Print(os); \
|
||||
@ -1840,6 +1848,24 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
void JSLocale::JSLocalePrint(std::ostream& os) { // NOLINT
|
||||
HeapObject::PrintHeader(os, "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: " << Brief(case_first());
|
||||
os << "\n - collation: " << Brief(collation());
|
||||
os << "\n - hourCycle: " << Brief(hour_cycle());
|
||||
os << "\n - numeric: " << Brief(numeric());
|
||||
os << "\n - numberingSystem: " << Brief(numbering_system());
|
||||
os << "\n";
|
||||
}
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
namespace {
|
||||
void PrintScopeInfoList(ScopeInfo* scope_info, std::ostream& os,
|
||||
const char* list_name, int nof_internal_slots,
|
||||
|
@ -60,6 +60,9 @@
|
||||
#include "src/objects/debug-objects-inl.h"
|
||||
#include "src/objects/frame-array-inl.h"
|
||||
#include "src/objects/hash-table.h"
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#include "src/objects/js-locale.h"
|
||||
#endif // V8_INTL_SUPPORT
|
||||
#include "src/objects/js-regexp-string-iterator.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/microtask-inl.h"
|
||||
@ -1394,6 +1397,10 @@ int JSObject::GetHeaderSize(InstanceType type,
|
||||
return JSStringIterator::kSize;
|
||||
case JS_MODULE_NAMESPACE_TYPE:
|
||||
return JSModuleNamespace::kHeaderSize;
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
return JSLocale::kSize;
|
||||
#endif // V8_INTL_SUPPORT
|
||||
case WASM_GLOBAL_TYPE:
|
||||
return WasmGlobalObject::kSize;
|
||||
case WASM_INSTANCE_TYPE:
|
||||
@ -3078,6 +3085,9 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
case JS_PROMISE_TYPE:
|
||||
case JS_REGEXP_TYPE:
|
||||
case JS_REGEXP_STRING_ITERATOR_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_INTL_LOCALE_TYPE:
|
||||
#endif // V8_INTL_SUPPORT
|
||||
case WASM_GLOBAL_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
|
365
src/objects.h
365
src/objects.h
@ -69,6 +69,7 @@
|
||||
// - JSDate
|
||||
// - JSMessageObject
|
||||
// - JSModuleNamespace
|
||||
// - JSLocale // If V8_INTL_SUPPORT enabled.
|
||||
// - WasmGlobalObject
|
||||
// - WasmInstanceObject
|
||||
// - WasmMemoryObject
|
||||
@ -319,7 +320,11 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
// NOTE: Everything following JS_VALUE_TYPE is considered a
|
||||
// JSObject for GC purposes. The first four entries here have typeof
|
||||
// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
|
||||
#define INSTANCE_TYPE_LIST(V) \
|
||||
//
|
||||
// NOTE: List had to be split into two, because of conditional item(s) from
|
||||
// INTL namespace. They can't just be appended to the end, because of the
|
||||
// checks we do in tests (expecting JS_FUNCTION_TYPE to be last).
|
||||
#define INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
|
||||
V(INTERNALIZED_STRING_TYPE) \
|
||||
V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
|
||||
V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
|
||||
@ -471,18 +476,29 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(JS_STRING_ITERATOR_TYPE) \
|
||||
V(JS_WEAK_MAP_TYPE) \
|
||||
V(JS_WEAK_SET_TYPE) \
|
||||
\
|
||||
V(JS_TYPED_ARRAY_TYPE) \
|
||||
V(JS_DATA_VIEW_TYPE) \
|
||||
\
|
||||
V(WASM_GLOBAL_TYPE) \
|
||||
V(WASM_INSTANCE_TYPE) \
|
||||
V(WASM_MEMORY_TYPE) \
|
||||
V(WASM_MODULE_TYPE) \
|
||||
V(WASM_TABLE_TYPE) \
|
||||
V(JS_BOUND_FUNCTION_TYPE) \
|
||||
V(JS_DATA_VIEW_TYPE)
|
||||
|
||||
#define INSTANCE_TYPE_LIST_AFTER_INTL(V) \
|
||||
V(WASM_GLOBAL_TYPE) \
|
||||
V(WASM_INSTANCE_TYPE) \
|
||||
V(WASM_MEMORY_TYPE) \
|
||||
V(WASM_MODULE_TYPE) \
|
||||
V(WASM_TABLE_TYPE) \
|
||||
V(JS_BOUND_FUNCTION_TYPE) \
|
||||
V(JS_FUNCTION_TYPE)
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define INSTANCE_TYPE_LIST(V) \
|
||||
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
|
||||
V(JS_INTL_LOCALE_TYPE) \
|
||||
INSTANCE_TYPE_LIST_AFTER_INTL(V)
|
||||
#else
|
||||
#define INSTANCE_TYPE_LIST(V) \
|
||||
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
|
||||
INSTANCE_TYPE_LIST_AFTER_INTL(V)
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
// Since string types are not consecutive, this macro is used to
|
||||
// iterate over them.
|
||||
#define STRING_TYPE_LIST(V) \
|
||||
@ -856,6 +872,10 @@ enum InstanceType : uint16_t {
|
||||
JS_TYPED_ARRAY_TYPE,
|
||||
JS_DATA_VIEW_TYPE,
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
JS_INTL_LOCALE_TYPE,
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
WASM_GLOBAL_TYPE,
|
||||
WASM_INSTANCE_TYPE,
|
||||
WASM_MEMORY_TYPE,
|
||||
@ -955,6 +975,9 @@ class PropertyArray;
|
||||
class FunctionLiteral;
|
||||
class FunctionTemplateInfo;
|
||||
class JSGlobalObject;
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
class JSLocale;
|
||||
#endif // V8_INTL_SUPPORT
|
||||
class JSPromise;
|
||||
class KeyAccumulator;
|
||||
class LayoutDescriptor;
|
||||
@ -998,165 +1021,173 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(Number) \
|
||||
V(Numeric)
|
||||
|
||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
|
||||
V(AbstractCode) \
|
||||
V(AccessCheckNeeded) \
|
||||
V(ArrayList) \
|
||||
V(BigInt) \
|
||||
V(BigIntWrapper) \
|
||||
V(BoilerplateDescription) \
|
||||
V(Boolean) \
|
||||
V(BooleanWrapper) \
|
||||
V(BreakPoint) \
|
||||
V(BreakPointInfo) \
|
||||
V(ByteArray) \
|
||||
V(BytecodeArray) \
|
||||
V(CallHandlerInfo) \
|
||||
V(Callable) \
|
||||
V(Cell) \
|
||||
V(ClassBoilerplate) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(CompilationCacheTable) \
|
||||
V(ConsString) \
|
||||
V(ConstantElementsPair) \
|
||||
V(Constructor) \
|
||||
V(Context) \
|
||||
V(CoverageInfo) \
|
||||
V(DataHandler) \
|
||||
V(DeoptimizationData) \
|
||||
V(DependentCode) \
|
||||
V(DescriptorArray) \
|
||||
V(EnumCache) \
|
||||
V(External) \
|
||||
V(ExternalOneByteString) \
|
||||
V(ExternalString) \
|
||||
V(ExternalTwoByteString) \
|
||||
V(FeedbackCell) \
|
||||
V(FeedbackMetadata) \
|
||||
V(FeedbackVector) \
|
||||
V(Filler) \
|
||||
V(FixedArray) \
|
||||
V(FixedArrayBase) \
|
||||
V(FixedArrayExact) \
|
||||
V(FixedArrayOfWeakCells) \
|
||||
V(FixedBigInt64Array) \
|
||||
V(FixedBigUint64Array) \
|
||||
V(FixedDoubleArray) \
|
||||
V(FixedFloat32Array) \
|
||||
V(FixedFloat64Array) \
|
||||
V(FixedInt16Array) \
|
||||
V(FixedInt32Array) \
|
||||
V(FixedInt8Array) \
|
||||
V(FixedTypedArrayBase) \
|
||||
V(FixedUint16Array) \
|
||||
V(FixedUint32Array) \
|
||||
V(FixedUint8Array) \
|
||||
V(FixedUint8ClampedArray) \
|
||||
V(Foreign) \
|
||||
V(FrameArray) \
|
||||
V(FreeSpace) \
|
||||
V(Function) \
|
||||
V(GlobalDictionary) \
|
||||
V(HandlerTable) \
|
||||
V(HeapNumber) \
|
||||
V(InternalizedString) \
|
||||
V(JSArgumentsObject) \
|
||||
V(JSArray) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSArrayBufferView) \
|
||||
V(JSArrayIterator) \
|
||||
V(JSAsyncFromSyncIterator) \
|
||||
V(JSAsyncGeneratorObject) \
|
||||
V(JSBoundFunction) \
|
||||
V(JSCollection) \
|
||||
V(JSContextExtensionObject) \
|
||||
V(JSDataView) \
|
||||
V(JSDate) \
|
||||
V(JSError) \
|
||||
V(JSFunction) \
|
||||
V(JSGeneratorObject) \
|
||||
V(JSGlobalObject) \
|
||||
V(JSGlobalProxy) \
|
||||
V(JSMap) \
|
||||
V(JSMapIterator) \
|
||||
V(JSMessageObject) \
|
||||
V(JSModuleNamespace) \
|
||||
V(JSObject) \
|
||||
V(JSPromise) \
|
||||
V(JSProxy) \
|
||||
V(JSReceiver) \
|
||||
V(JSRegExp) \
|
||||
V(JSRegExpStringIterator) \
|
||||
V(JSSet) \
|
||||
V(JSSetIterator) \
|
||||
V(JSSloppyArgumentsObject) \
|
||||
V(JSStringIterator) \
|
||||
V(JSTypedArray) \
|
||||
V(JSValue) \
|
||||
V(JSWeakCollection) \
|
||||
V(JSWeakMap) \
|
||||
V(JSWeakSet) \
|
||||
V(LoadHandler) \
|
||||
V(Map) \
|
||||
V(MapCache) \
|
||||
V(Microtask) \
|
||||
V(ModuleInfo) \
|
||||
V(MutableHeapNumber) \
|
||||
V(Name) \
|
||||
V(NameDictionary) \
|
||||
V(NativeContext) \
|
||||
V(NormalizedMapCache) \
|
||||
V(NumberDictionary) \
|
||||
V(NumberWrapper) \
|
||||
V(ObjectHashSet) \
|
||||
V(ObjectHashTable) \
|
||||
V(Oddball) \
|
||||
V(OrderedHashMap) \
|
||||
V(OrderedHashSet) \
|
||||
V(PreParsedScopeData) \
|
||||
V(PromiseReactionJobTask) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PropertyDescriptorObject) \
|
||||
V(RegExpMatchInfo) \
|
||||
V(ScopeInfo) \
|
||||
V(ScriptContextTable) \
|
||||
V(ScriptWrapper) \
|
||||
V(SeqOneByteString) \
|
||||
V(SeqString) \
|
||||
V(SeqTwoByteString) \
|
||||
V(SharedFunctionInfo) \
|
||||
V(SimpleNumberDictionary) \
|
||||
V(SlicedString) \
|
||||
V(SloppyArgumentsElements) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SourcePositionTableWithFrameCache) \
|
||||
V(StoreHandler) \
|
||||
V(String) \
|
||||
V(StringSet) \
|
||||
V(StringTable) \
|
||||
V(StringWrapper) \
|
||||
V(Struct) \
|
||||
V(Symbol) \
|
||||
V(SymbolWrapper) \
|
||||
V(TemplateInfo) \
|
||||
V(TemplateList) \
|
||||
V(TemplateObjectDescription) \
|
||||
V(ThinString) \
|
||||
V(TransitionArray) \
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
V(WasmGlobalObject) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmMemoryObject) \
|
||||
V(WasmModuleObject) \
|
||||
V(WasmTableObject) \
|
||||
V(WeakCell) \
|
||||
V(WeakFixedArray) \
|
||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
|
||||
V(AbstractCode) \
|
||||
V(AccessCheckNeeded) \
|
||||
V(ArrayList) \
|
||||
V(BigInt) \
|
||||
V(BigIntWrapper) \
|
||||
V(BoilerplateDescription) \
|
||||
V(Boolean) \
|
||||
V(BooleanWrapper) \
|
||||
V(BreakPoint) \
|
||||
V(BreakPointInfo) \
|
||||
V(ByteArray) \
|
||||
V(BytecodeArray) \
|
||||
V(CallHandlerInfo) \
|
||||
V(Callable) \
|
||||
V(Cell) \
|
||||
V(ClassBoilerplate) \
|
||||
V(Code) \
|
||||
V(CodeDataContainer) \
|
||||
V(CompilationCacheTable) \
|
||||
V(ConsString) \
|
||||
V(ConstantElementsPair) \
|
||||
V(Constructor) \
|
||||
V(Context) \
|
||||
V(CoverageInfo) \
|
||||
V(DataHandler) \
|
||||
V(DeoptimizationData) \
|
||||
V(DependentCode) \
|
||||
V(DescriptorArray) \
|
||||
V(EnumCache) \
|
||||
V(External) \
|
||||
V(ExternalOneByteString) \
|
||||
V(ExternalString) \
|
||||
V(ExternalTwoByteString) \
|
||||
V(FeedbackCell) \
|
||||
V(FeedbackMetadata) \
|
||||
V(FeedbackVector) \
|
||||
V(Filler) \
|
||||
V(FixedArray) \
|
||||
V(FixedArrayBase) \
|
||||
V(FixedArrayExact) \
|
||||
V(FixedArrayOfWeakCells) \
|
||||
V(FixedBigInt64Array) \
|
||||
V(FixedBigUint64Array) \
|
||||
V(FixedDoubleArray) \
|
||||
V(FixedFloat32Array) \
|
||||
V(FixedFloat64Array) \
|
||||
V(FixedInt16Array) \
|
||||
V(FixedInt32Array) \
|
||||
V(FixedInt8Array) \
|
||||
V(FixedTypedArrayBase) \
|
||||
V(FixedUint16Array) \
|
||||
V(FixedUint32Array) \
|
||||
V(FixedUint8Array) \
|
||||
V(FixedUint8ClampedArray) \
|
||||
V(Foreign) \
|
||||
V(FrameArray) \
|
||||
V(FreeSpace) \
|
||||
V(Function) \
|
||||
V(GlobalDictionary) \
|
||||
V(HandlerTable) \
|
||||
V(HeapNumber) \
|
||||
V(InternalizedString) \
|
||||
V(JSArgumentsObject) \
|
||||
V(JSArray) \
|
||||
V(JSArrayBuffer) \
|
||||
V(JSArrayBufferView) \
|
||||
V(JSArrayIterator) \
|
||||
V(JSAsyncFromSyncIterator) \
|
||||
V(JSAsyncGeneratorObject) \
|
||||
V(JSBoundFunction) \
|
||||
V(JSCollection) \
|
||||
V(JSContextExtensionObject) \
|
||||
V(JSDataView) \
|
||||
V(JSDate) \
|
||||
V(JSError) \
|
||||
V(JSFunction) \
|
||||
V(JSGeneratorObject) \
|
||||
V(JSGlobalObject) \
|
||||
V(JSGlobalProxy) \
|
||||
V(JSMap) \
|
||||
V(JSMapIterator) \
|
||||
V(JSMessageObject) \
|
||||
V(JSModuleNamespace) \
|
||||
V(JSObject) \
|
||||
V(JSPromise) \
|
||||
V(JSProxy) \
|
||||
V(JSReceiver) \
|
||||
V(JSRegExp) \
|
||||
V(JSRegExpStringIterator) \
|
||||
V(JSSet) \
|
||||
V(JSSetIterator) \
|
||||
V(JSSloppyArgumentsObject) \
|
||||
V(JSStringIterator) \
|
||||
V(JSTypedArray) \
|
||||
V(JSValue) \
|
||||
V(JSWeakCollection) \
|
||||
V(JSWeakMap) \
|
||||
V(JSWeakSet) \
|
||||
V(LoadHandler) \
|
||||
V(Map) \
|
||||
V(MapCache) \
|
||||
V(Microtask) \
|
||||
V(ModuleInfo) \
|
||||
V(MutableHeapNumber) \
|
||||
V(Name) \
|
||||
V(NameDictionary) \
|
||||
V(NativeContext) \
|
||||
V(NormalizedMapCache) \
|
||||
V(NumberDictionary) \
|
||||
V(NumberWrapper) \
|
||||
V(ObjectHashSet) \
|
||||
V(ObjectHashTable) \
|
||||
V(Oddball) \
|
||||
V(OrderedHashMap) \
|
||||
V(OrderedHashSet) \
|
||||
V(PreParsedScopeData) \
|
||||
V(PromiseReactionJobTask) \
|
||||
V(PropertyArray) \
|
||||
V(PropertyCell) \
|
||||
V(PropertyDescriptorObject) \
|
||||
V(RegExpMatchInfo) \
|
||||
V(ScopeInfo) \
|
||||
V(ScriptContextTable) \
|
||||
V(ScriptWrapper) \
|
||||
V(SeqOneByteString) \
|
||||
V(SeqString) \
|
||||
V(SeqTwoByteString) \
|
||||
V(SharedFunctionInfo) \
|
||||
V(SimpleNumberDictionary) \
|
||||
V(SlicedString) \
|
||||
V(SloppyArgumentsElements) \
|
||||
V(SmallOrderedHashMap) \
|
||||
V(SmallOrderedHashSet) \
|
||||
V(SourcePositionTableWithFrameCache) \
|
||||
V(StoreHandler) \
|
||||
V(String) \
|
||||
V(StringSet) \
|
||||
V(StringTable) \
|
||||
V(StringWrapper) \
|
||||
V(Struct) \
|
||||
V(Symbol) \
|
||||
V(SymbolWrapper) \
|
||||
V(TemplateInfo) \
|
||||
V(TemplateList) \
|
||||
V(TemplateObjectDescription) \
|
||||
V(ThinString) \
|
||||
V(TransitionArray) \
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
V(WasmGlobalObject) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmMemoryObject) \
|
||||
V(WasmModuleObject) \
|
||||
V(WasmTableObject) \
|
||||
V(WeakCell) \
|
||||
V(WeakFixedArray) \
|
||||
V(WeakArrayList)
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
|
||||
HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
|
||||
V(JSLocale)
|
||||
#else
|
||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V)
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
#define HEAP_OBJECT_TEMPLATE_TYPE_LIST(V) \
|
||||
V(Dictionary) \
|
||||
V(HashTable)
|
||||
|
41
src/objects/js-locale-inl.h
Normal file
41
src/objects/js-locale-inl.h
Normal file
@ -0,0 +1,41 @@
|
||||
// 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_LOCALE_INL_H_
|
||||
#define V8_OBJECTS_JS_LOCALE_INL_H_
|
||||
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/js-locale.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Base locale accessors.
|
||||
ACCESSORS(JSLocale, language, Object, kLanguageOffset);
|
||||
ACCESSORS(JSLocale, script, Object, kScriptOffset);
|
||||
ACCESSORS(JSLocale, region, Object, kRegionOffset);
|
||||
ACCESSORS(JSLocale, base_name, Object, kBaseNameOffset);
|
||||
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);
|
||||
|
||||
CAST_ACCESSOR(JSLocale);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_OBJECTS_JS_LOCALE_INL_H_
|
275
src/objects/js-locale.cc
Normal file
275
src/objects/js-locale.cc
Normal file
@ -0,0 +1,275 @@
|
||||
// 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-locale.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "src/api.h"
|
||||
#include "src/global-handles.h"
|
||||
#include "src/heap/factory.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/js-locale-inl.h"
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/uvernum.h"
|
||||
#include "unicode/uversion.h"
|
||||
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 59
|
||||
#include "unicode/char16ptr.h"
|
||||
#endif
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
// gcc has problem with constexpr here, so falling back to const.
|
||||
const std::array<std::pair<const char*, const char*>, 6>
|
||||
kOptionToUnicodeTagMap = {{{"calendar", "ca"},
|
||||
{"collation", "co"},
|
||||
{"hourCycle", "hc"},
|
||||
{"caseFirst", "kf"},
|
||||
{"numeric", "kn"},
|
||||
{"numberingSystem", "nu"}}};
|
||||
|
||||
// Extracts value of a given property key in the Object.
|
||||
Maybe<bool> ExtractStringSetting(Isolate* isolate, Handle<JSReceiver> options,
|
||||
const char* key, icu::UnicodeString* setting) {
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
|
||||
|
||||
// JSReceiver::GetProperty could throw an exception and return an empty
|
||||
// MaybeHandle<Object>().
|
||||
// Returns Nothing<bool> on exception.
|
||||
Handle<Object> object;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, object, JSReceiver::GetProperty(options, str), Nothing<bool>());
|
||||
|
||||
if (object->IsString()) {
|
||||
v8::String::Utf8Value utf8_string(
|
||||
v8_isolate, v8::Utils::ToLocal(Handle<String>::cast(object)));
|
||||
*setting = icu::UnicodeString::fromUTF8(*utf8_string);
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
return Just(false);
|
||||
}
|
||||
|
||||
// Inserts tags from options into locale string.
|
||||
Maybe<bool> InsertOptionsIntoLocale(Isolate* isolate,
|
||||
Handle<JSReceiver> options,
|
||||
char* icu_locale) {
|
||||
CHECK(isolate);
|
||||
CHECK(icu_locale);
|
||||
|
||||
for (const auto& option_to_bcp47 : kOptionToUnicodeTagMap) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
icu::UnicodeString value_unicode;
|
||||
|
||||
Maybe<bool> found = ExtractStringSetting(
|
||||
isolate, options, option_to_bcp47.first, &value_unicode);
|
||||
// Return on exception.
|
||||
MAYBE_RETURN(found, Nothing<bool>());
|
||||
if (!found.FromJust()) {
|
||||
// Skip this key, user didn't specify it in options.
|
||||
continue;
|
||||
}
|
||||
DCHECK(found.FromJust());
|
||||
|
||||
std::string value_string;
|
||||
value_unicode.toUTF8String(value_string);
|
||||
|
||||
// Convert bcp47 key and value into legacy ICU format so we can use
|
||||
// uloc_setKeywordValue.
|
||||
const char* key = uloc_toLegacyKey(option_to_bcp47.second);
|
||||
if (!key) return Just(false);
|
||||
|
||||
// Overwrite existing, or insert new key-value to the locale string.
|
||||
const char* value = uloc_toLegacyType(key, value_string.c_str());
|
||||
if (value) {
|
||||
// TODO(cira): ICU puts artificial limit on locale length, while BCP47
|
||||
// doesn't. Switch to C++ API when it's ready.
|
||||
// Related ICU bug - https://ssl.icu-project.org/trac/ticket/13417.
|
||||
uloc_setKeywordValue(key, value, icu_locale, ULOC_FULLNAME_CAPACITY,
|
||||
&status);
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
return Just(false);
|
||||
}
|
||||
} else {
|
||||
return Just(false);
|
||||
}
|
||||
}
|
||||
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
// Fills in the JSLocale object slots with Unicode tag/values.
|
||||
bool PopulateLocaleWithUnicodeTags(Isolate* isolate, const char* icu_locale,
|
||||
Handle<JSLocale> locale_holder) {
|
||||
CHECK(isolate);
|
||||
CHECK(icu_locale);
|
||||
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
static std::map<std::string, std::string> bcp47_to_option_map;
|
||||
for (const auto& option_to_bcp47 : kOptionToUnicodeTagMap) {
|
||||
bcp47_to_option_map.emplace(option_to_bcp47.second, option_to_bcp47.first);
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UEnumeration* keywords = uloc_openKeywords(icu_locale, &status);
|
||||
if (!keywords) return true;
|
||||
|
||||
char value[ULOC_FULLNAME_CAPACITY];
|
||||
while (const char* keyword = uenum_next(keywords, nullptr, &status)) {
|
||||
uloc_getKeywordValue(icu_locale, keyword, value, ULOC_FULLNAME_CAPACITY,
|
||||
&status);
|
||||
if (U_FAILURE(status)) {
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore those we don't recognize - spec allows that.
|
||||
const char* bcp47_key = uloc_toUnicodeLocaleKey(keyword);
|
||||
if (bcp47_key) {
|
||||
const char* bcp47_value = uloc_toUnicodeLocaleType(bcp47_key, value);
|
||||
if (bcp47_value) {
|
||||
auto iterator = bcp47_to_option_map.find(bcp47_key);
|
||||
if (iterator != bcp47_to_option_map.end()) {
|
||||
// It's either Boolean value.
|
||||
if (iterator->second == "numeric") {
|
||||
bool numeric = strcmp(bcp47_value, "true") == 0 ? true : false;
|
||||
Handle<Object> numeric_handle = factory->ToBoolean(numeric);
|
||||
locale_holder->set_numeric(*numeric_handle);
|
||||
continue;
|
||||
}
|
||||
// Or a string.
|
||||
Handle<String> bcp47_handle =
|
||||
factory->NewStringFromAsciiChecked(bcp47_value);
|
||||
if (iterator->second == "calendar") {
|
||||
locale_holder->set_calendar(*bcp47_handle);
|
||||
} else if (iterator->second == "caseFirst") {
|
||||
locale_holder->set_case_first(*bcp47_handle);
|
||||
} else if (iterator->second == "collation") {
|
||||
locale_holder->set_collation(*bcp47_handle);
|
||||
} else if (iterator->second == "hourCycle") {
|
||||
locale_holder->set_hour_cycle(*bcp47_handle);
|
||||
} else if (iterator->second == "numberingSystem") {
|
||||
locale_holder->set_numbering_system(*bcp47_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uenum_close(keywords);
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool JSLocale::InitializeLocale(Isolate* isolate,
|
||||
Handle<JSLocale> locale_holder,
|
||||
Handle<String> locale,
|
||||
Handle<JSReceiver> options) {
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
// Get ICU locale format, and canonicalize it.
|
||||
char icu_result[ULOC_FULLNAME_CAPACITY];
|
||||
char icu_canonical[ULOC_FULLNAME_CAPACITY];
|
||||
|
||||
v8::String::Utf8Value bcp47_locale(v8_isolate, v8::Utils::ToLocal(locale));
|
||||
if (bcp47_locale.length() == 0) return false;
|
||||
|
||||
int icu_length = uloc_forLanguageTag(
|
||||
*bcp47_locale, icu_result, ULOC_FULLNAME_CAPACITY, nullptr, &status);
|
||||
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING ||
|
||||
icu_length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Maybe<bool> error = InsertOptionsIntoLocale(isolate, options, icu_result);
|
||||
if (error.IsNothing() || !error.FromJust()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uloc_canonicalize(icu_result, icu_canonical, ULOC_FULLNAME_CAPACITY, &status);
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PopulateLocaleWithUnicodeTags(isolate, icu_canonical, locale_holder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract language, script and region parts.
|
||||
char icu_language[ULOC_LANG_CAPACITY];
|
||||
uloc_getLanguage(icu_canonical, icu_language, ULOC_LANG_CAPACITY, &status);
|
||||
|
||||
char icu_script[ULOC_SCRIPT_CAPACITY];
|
||||
uloc_getScript(icu_canonical, icu_script, ULOC_SCRIPT_CAPACITY, &status);
|
||||
|
||||
char icu_region[ULOC_COUNTRY_CAPACITY];
|
||||
uloc_getCountry(icu_canonical, icu_region, ULOC_COUNTRY_CAPACITY, &status);
|
||||
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
// NOTE: One shouldn't use temporary handles, because they can go out of
|
||||
// scope and be garbage collected before properly assigned.
|
||||
// DON'T DO THIS: locale_holder->set_language(*f->NewStringAscii...);
|
||||
Handle<String> language = factory->NewStringFromAsciiChecked(icu_language);
|
||||
locale_holder->set_language(*language);
|
||||
|
||||
if (strlen(icu_script) != 0) {
|
||||
Handle<String> script = factory->NewStringFromAsciiChecked(icu_script);
|
||||
locale_holder->set_script(*script);
|
||||
}
|
||||
|
||||
if (strlen(icu_region) != 0) {
|
||||
Handle<String> region = factory->NewStringFromAsciiChecked(icu_region);
|
||||
locale_holder->set_region(*region);
|
||||
}
|
||||
|
||||
char icu_base_name[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_getBaseName(icu_canonical, icu_base_name, ULOC_FULLNAME_CAPACITY,
|
||||
&status);
|
||||
// We need to convert it back to BCP47.
|
||||
char bcp47_result[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_toLanguageTag(icu_base_name, bcp47_result, ULOC_FULLNAME_CAPACITY, true,
|
||||
&status);
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
return false;
|
||||
}
|
||||
Handle<String> base_name = factory->NewStringFromAsciiChecked(bcp47_result);
|
||||
locale_holder->set_base_name(*base_name);
|
||||
|
||||
// Produce final representation of the locale string, for toString().
|
||||
uloc_toLanguageTag(icu_canonical, bcp47_result, ULOC_FULLNAME_CAPACITY, true,
|
||||
&status);
|
||||
if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
|
||||
return false;
|
||||
}
|
||||
Handle<String> locale_handle =
|
||||
factory->NewStringFromAsciiChecked(bcp47_result);
|
||||
locale_holder->set_locale(*locale_handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
78
src/objects/js-locale.h
Normal file
78
src/objects/js-locale.h
Normal file
@ -0,0 +1,78 @@
|
||||
// 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_LOCALE_H_
|
||||
#define V8_OBJECTS_JS_LOCALE_H_
|
||||
|
||||
#include "src/api.h"
|
||||
#include "src/global-handles.h"
|
||||
#include "src/heap/factory.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects.h"
|
||||
#include "unicode/unistr.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class JSLocale : public JSObject {
|
||||
public:
|
||||
// Initializes locale object with properties derived from input locale string
|
||||
// and options.
|
||||
static bool InitializeLocale(Isolate* isolate, Handle<JSLocale> locale_holder,
|
||||
Handle<String> locale,
|
||||
Handle<JSReceiver> options);
|
||||
|
||||
DECL_CAST(JSLocale)
|
||||
|
||||
// Locale accessors.
|
||||
DECL_ACCESSORS(language, Object)
|
||||
DECL_ACCESSORS(script, Object)
|
||||
DECL_ACCESSORS(region, Object)
|
||||
DECL_ACCESSORS(base_name, Object)
|
||||
DECL_ACCESSORS(locale, String)
|
||||
|
||||
// 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)
|
||||
|
||||
DECL_PRINTER(JSLocale)
|
||||
DECL_VERIFIER(JSLocale)
|
||||
|
||||
// Layout description.
|
||||
static const int kJSLocaleOffset = JSObject::kHeaderSize;
|
||||
// Locale fields.
|
||||
static const int kLanguageOffset = kJSLocaleOffset + kPointerSize;
|
||||
static const int kScriptOffset = kLanguageOffset + kPointerSize;
|
||||
static const int kRegionOffset = kScriptOffset + kPointerSize;
|
||||
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;
|
||||
// Final size.
|
||||
static const int kSize = kNumberingSystemOffset + kPointerSize;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSLocale);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_OBJECTS_JS_LOCALE_H_
|
@ -362,7 +362,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(18),
|
||||
B(LdaConstant), U8(14),
|
||||
B(Star), R(19),
|
||||
|
@ -123,7 +123,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(19),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(20),
|
||||
@ -374,7 +374,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(19),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(20),
|
||||
@ -647,7 +647,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(19),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(20),
|
||||
@ -876,7 +876,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(17),
|
||||
B(LdaConstant), U8(9),
|
||||
B(Star), R(18),
|
||||
|
@ -85,7 +85,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(13),
|
||||
@ -217,7 +217,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(13),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(14),
|
||||
@ -361,7 +361,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(13),
|
||||
@ -495,7 +495,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(9),
|
||||
B(Star), R(12),
|
||||
|
@ -89,7 +89,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(14),
|
||||
B(LdaConstant), U8(6),
|
||||
B(Star), R(15),
|
||||
@ -256,7 +256,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(14),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(15),
|
||||
@ -401,7 +401,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(13),
|
||||
@ -495,7 +495,7 @@ bytecodes: [
|
||||
B(JumpIfUndefined), U8(6),
|
||||
B(Ldar), R(6),
|
||||
B(JumpIfNotNull), U8(16),
|
||||
B(LdaSmi), I8(75),
|
||||
B(LdaSmi), I8(77),
|
||||
B(Star), R(18),
|
||||
B(LdaConstant), U8(4),
|
||||
B(Star), R(19),
|
||||
@ -550,7 +550,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(17),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(18),
|
||||
@ -702,7 +702,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(16),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(17),
|
||||
@ -870,7 +870,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(15),
|
||||
B(LdaConstant), U8(13),
|
||||
B(Star), R(16),
|
||||
@ -1024,7 +1024,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(21),
|
||||
B(LdaConstant), U8(7),
|
||||
B(Star), R(22),
|
||||
@ -1238,7 +1238,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(20),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(21),
|
||||
|
@ -203,7 +203,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(6),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(145),
|
||||
B(Wide), B(LdaSmi), I16(147),
|
||||
B(Star), R(14),
|
||||
B(LdaConstant), U8(13),
|
||||
B(Star), R(15),
|
||||
|
@ -229,7 +229,7 @@ bytecodes: [
|
||||
B(JumpIfUndefined), U8(6),
|
||||
B(Ldar), R(3),
|
||||
B(JumpIfNotNull), U8(16),
|
||||
B(LdaSmi), I8(75),
|
||||
B(LdaSmi), I8(77),
|
||||
B(Star), R(4),
|
||||
B(LdaConstant), U8(1),
|
||||
B(Star), R(5),
|
||||
|
24
test/intl/locale/locale-canonicalization.js
Normal file
24
test/intl/locale/locale-canonicalization.js
Normal file
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
// Flags: --harmony-locale
|
||||
|
||||
// Make sure that locale string got canonicalized by the spec,
|
||||
// keys are sorted and unique, region upper cased, script title cased and
|
||||
// language lower cased.
|
||||
|
||||
let locale = new Intl.Locale('sr-cyrl-rs-t-ja-u-ca-islamic-x-whatever', {
|
||||
calendar: 'buddhist',
|
||||
caseFirst: 'true',
|
||||
collation: 'phonebk',
|
||||
hourCycle: 'h23',
|
||||
caseFirst: 'upper',
|
||||
numeric: 'true',
|
||||
numberingSystem: 'roman'
|
||||
});
|
||||
|
||||
let expected =
|
||||
'sr-Cyrl-RS-t-ja-u-ca-buddhist-co-phonebk-hc-h23-kf-upper-kn-true-nu-roman-x-whatever';
|
||||
|
||||
assertEquals(expected, locale.toString());
|
32
test/intl/locale/locale-constructor.js
Normal file
32
test/intl/locale/locale-constructor.js
Normal file
@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
// Flags: --harmony-locale
|
||||
|
||||
// Locale constructor can't be called as function.
|
||||
assertThrows(() => Intl.Locale('sr'), TypeError);
|
||||
|
||||
// Non-string locale.
|
||||
assertThrows(() => new Intl.Locale(5), TypeError);
|
||||
|
||||
// Invalid locale.
|
||||
assertThrows(() => new Intl.Locale('abcdefghi'), TypeError);
|
||||
|
||||
// Options will be force converted into Object.
|
||||
assertDoesNotThrow(() => new Intl.Locale('sr', 5));
|
||||
|
||||
// ICU problem - locale length is limited.
|
||||
// http://bugs.icu-project.org/trac/ticket/13417.
|
||||
assertThrows(
|
||||
() => new Intl.Locale(
|
||||
'sr-cyrl-rs-t-ja-u-ca-islamic-cu-rsd-tz-uslax-x-whatever', {
|
||||
calendar: 'buddhist',
|
||||
caseFirst: 'true',
|
||||
collation: 'phonebk',
|
||||
hourCycle: 'h23',
|
||||
caseFirst: 'upper',
|
||||
numeric: 'true',
|
||||
numberingSystem: 'roman',
|
||||
}),
|
||||
TypeError);
|
35
test/intl/locale/locale-properties.js
Normal file
35
test/intl/locale/locale-properties.js
Normal file
@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// Flags: --harmony-locale
|
||||
|
||||
// Make sure that locale exposes all required properties. Those not specified
|
||||
// should have undefined value.
|
||||
|
||||
let locale = new Intl.Locale('sr-cyrl-rs-t-ja-u-ca-islamic-x-whatever', {
|
||||
calendar: 'buddhist',
|
||||
caseFirst: 'true',
|
||||
collation: 'phonebk',
|
||||
hourCycle: 'h23',
|
||||
caseFirst: 'upper',
|
||||
numeric: 'true',
|
||||
numberingSystem: 'roman'
|
||||
});
|
||||
assertEquals('sr', locale.language);
|
||||
assertEquals('Cyrl', locale.script);
|
||||
assertEquals('RS', locale.region);
|
||||
assertEquals('sr-Cyrl-RS', locale.baseName);
|
||||
assertEquals('buddhist', locale.calendar);
|
||||
assertEquals('phonebk', locale.collation);
|
||||
assertEquals('h23', locale.hourCycle);
|
||||
assertEquals('upper', locale.caseFirst);
|
||||
assertEquals(true, locale.numeric);
|
||||
assertEquals('roman', locale.numberingSystem);
|
||||
// Not defined, expected to undefined.
|
||||
assertEquals(undefined, locale.currency);
|
||||
assertEquals(undefined, locale.timeZone);
|
||||
|
||||
// Test property defined in spec, but not specified in locale.
|
||||
let missing_property = new Intl.Locale('sr');
|
||||
assertEquals(undefined, missing_property.script);
|
@ -148,13 +148,14 @@ INSTANCE_TYPES = {
|
||||
1081: "JS_WEAK_SET_TYPE",
|
||||
1082: "JS_TYPED_ARRAY_TYPE",
|
||||
1083: "JS_DATA_VIEW_TYPE",
|
||||
1084: "WASM_GLOBAL_TYPE",
|
||||
1085: "WASM_INSTANCE_TYPE",
|
||||
1086: "WASM_MEMORY_TYPE",
|
||||
1087: "WASM_MODULE_TYPE",
|
||||
1088: "WASM_TABLE_TYPE",
|
||||
1089: "JS_BOUND_FUNCTION_TYPE",
|
||||
1090: "JS_FUNCTION_TYPE",
|
||||
1084: "JS_INTL_LOCALE_TYPE",
|
||||
1085: "WASM_GLOBAL_TYPE",
|
||||
1086: "WASM_INSTANCE_TYPE",
|
||||
1087: "WASM_MEMORY_TYPE",
|
||||
1088: "WASM_MODULE_TYPE",
|
||||
1089: "WASM_TABLE_TYPE",
|
||||
1090: "JS_BOUND_FUNCTION_TYPE",
|
||||
1091: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
|
Loading…
Reference in New Issue
Block a user