Commit f2d07ec5 authored by Ujjwal Sharma's avatar Ujjwal Sharma Committed by Commit Bot

[intl] Port BreakIterator to C++

Port CreateBreakIterator and BreakIterator.prototype.resolvedOptions to
C++, refactoring the entire class into another one called
JSV8BreakIterator that would be a subclass of JSObject.

TBR: benedikt@chromium.org
Bug: v8:8111
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I9bd1d82ec34b210c8ed59ea6576548d45a34b8d5
Reviewed-on: https://chromium-review.googlesource.com/1198946
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55627}
parent 41db90b0
......@@ -2175,6 +2175,9 @@ v8_source_set("v8_base") {
"src/objects/js-array-buffer.h",
"src/objects/js-array-inl.h",
"src/objects/js-array.h",
"src/objects/js-break-iterator-inl.h",
"src/objects/js-break-iterator.cc",
"src/objects/js-break-iterator.h",
"src/objects/js-collator-inl.h",
"src/objects/js-collator.cc",
"src/objects/js-collator.h",
......@@ -2896,6 +2899,9 @@ v8_source_set("v8_base") {
"src/objects/intl-objects-inl.h",
"src/objects/intl-objects.cc",
"src/objects/intl-objects.h",
"src/objects/js-break-iterator-inl.h",
"src/objects/js-break-iterator.cc",
"src/objects/js-break-iterator.h",
"src/objects/js-collator-inl.h",
"src/objects/js-collator.cc",
"src/objects/js-collator.h",
......
......@@ -28,6 +28,7 @@
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-break-iterator.h"
#include "src/objects/js-collator.h"
#include "src/objects/js-list-format.h"
#include "src/objects/js-locale.h"
......@@ -2985,15 +2986,17 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
}
{
Handle<JSFunction> v8_break_iterator_constructor =
InstallFunction(isolate_, intl, "v8BreakIterator", JS_OBJECT_TYPE,
V8BreakIterator::kSize, 0, factory->the_hole_value(),
Builtins::kIllegal);
native_context()->set_intl_v8_break_iterator_function(
*v8_break_iterator_constructor);
Handle<JSFunction> v8_break_iterator_constructor = InstallFunction(
isolate_, intl, "v8BreakIterator", JS_INTL_V8_BREAK_ITERATOR_TYPE,
JSV8BreakIterator::kSize, 0, factory->the_hole_value(),
Builtins::kBreakIteratorConstructor);
v8_break_iterator_constructor->shared()->DontAdaptArguments();
InstallWithIntrinsicDefaultProto(
isolate_, v8_break_iterator_constructor,
Context::INTL_V8_BREAK_ITERATOR_FUNCTION_INDEX);
SimpleInstallFunction(
isolate(), v8_break_iterator_constructor, "supportedLocalesOf",
isolate_, v8_break_iterator_constructor, "supportedLocalesOf",
Builtins::kv8BreakIteratorSupportedLocalesOf, 1, false);
Handle<JSObject> prototype(
......@@ -3005,6 +3008,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
factory->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(isolate_, prototype, "resolvedOptions",
Builtins::kBreakIteratorPrototypeResolvedOptions, 0,
false);
SimpleInstallGetter(isolate_, prototype,
factory->InternalizeUtf8String("adoptText"),
Builtins::kBreakIteratorPrototypeAdoptText, false);
......
......@@ -1421,7 +1421,9 @@ namespace internal {
CPP(BreakIteratorInternalCurrent) \
CPP(BreakIteratorPrototypeCurrent) \
CPP(BreakIteratorInternalBreakType) \
CPP(BreakIteratorPrototypeBreakType)
CPP(BreakIteratorPrototypeBreakType) \
CPP(BreakIteratorConstructor) \
CPP(BreakIteratorPrototypeResolvedOptions)
#else
#define BUILTIN_LIST_INTL(CPP, TFJ, TFS) \
/* no-op fallback version */ \
......
This diff is collapsed.
......@@ -207,6 +207,7 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
case JS_MESSAGE_OBJECT_TYPE:
case JS_DATE_TYPE:
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
case JS_INTL_COLLATOR_TYPE:
case JS_INTL_DATE_TIME_FORMAT_TYPE:
case JS_INTL_LIST_FORMAT_TYPE:
......
......@@ -40,6 +40,7 @@
V(caseFirst_string, "caseFirst") \
V(cell_value_string, "%cell_value") \
V(char_at_string, "CharAt") \
V(character_string, "character") \
V(closure_string, "(closure)") \
V(code_string, "code") \
V(collation_string, "collation") \
......@@ -198,6 +199,7 @@
V(second_string, "second") \
V(Set_string, "Set") \
V(sensitivity_string, "sensitivity") \
V(sentence_string, "sentence") \
V(set_space_string, "set ") \
V(set_string, "set") \
V(SetIterator_string, "Set Iterator") \
......@@ -248,6 +250,7 @@
V(WeakSet_string, "WeakSet") \
V(weekday_string, "weekday") \
V(will_handle_string, "willHandle") \
V(word_string, "word") \
V(writable_string, "writable") \
V(year_string, "year") \
V(zero_string, "0")
......
......@@ -598,77 +598,6 @@ DEFINE_METHOD(
}
);
/**
* Initializes the given object so it's a valid BreakIterator instance.
* Useful for subclassing.
*/
function CreateBreakIterator(locales, options) {
if (IS_UNDEFINED(options)) {
options = {__proto__: null};
}
var getOption = getGetOption(options, 'breakiterator');
var internalOptions = {__proto__: null};
%DefineWEProperty(internalOptions, 'type', getOption(
'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
var locale = resolveLocale('breakiterator', locales, options);
var resolved = %object_define_properties({__proto__: null}, {
requestedLocale: {value: locale.locale, writable: true},
type: {value: internalOptions.type, writable: true},
locale: {writable: true}
});
var iterator = %CreateBreakIterator(locale.locale, internalOptions, resolved);
%MarkAsInitializedIntlObjectOfType(iterator, BREAK_ITERATOR_TYPE);
iterator[resolvedSymbol] = resolved;
return iterator;
}
/**
* Constructs Intl.v8BreakIterator object given optional locales and options
* parameters.
*
* @constructor
*/
function v8BreakIteratorConstructor() {
return IntlConstruct(this, GlobalIntlv8BreakIterator, CreateBreakIterator,
new.target, arguments);
}
%SetCode(GlobalIntlv8BreakIterator, v8BreakIteratorConstructor);
/**
* BreakIterator resolvedOptions method.
*/
DEFINE_METHOD(
GlobalIntlv8BreakIterator.prototype,
resolvedOptions() {
if (!IS_UNDEFINED(new.target)) {
throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
}
var methodName = 'resolvedOptions';
if(!IS_RECEIVER(this)) {
throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
}
var segmenter = %IntlUnwrapReceiver(this, BREAK_ITERATOR_TYPE,
GlobalIntlv8BreakIterator, methodName,
false);
return {
locale: segmenter[resolvedSymbol].locale,
type: segmenter[resolvedSymbol].type
};
}
);
// Save references to Intl objects and methods we use, for added security.
var savedObjects = {
__proto__: null,
......
......@@ -726,6 +726,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case JS_MESSAGE_OBJECT_TYPE:
case JS_BOUND_FUNCTION_TYPE:
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
case JS_INTL_COLLATOR_TYPE:
case JS_INTL_DATE_TIME_FORMAT_TYPE:
case JS_INTL_LIST_FORMAT_TYPE:
......
......@@ -20,6 +20,7 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-break-iterator-inl.h"
#include "src/objects/js-collator-inl.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-collection-inl.h"
......@@ -360,6 +361,9 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
CodeDataContainer::cast(this)->CodeDataContainerVerify(isolate);
break;
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
JSV8BreakIterator::cast(this)->JSV8BreakIteratorVerify(isolate);
break;
case JS_INTL_COLLATOR_TYPE:
JSCollator::cast(this)->JSCollatorVerify(isolate);
break;
......@@ -1883,6 +1887,19 @@ void InterpreterData::InterpreterDataVerify(Isolate* isolate) {
}
#ifdef V8_INTL_SUPPORT
void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
VerifyObjectField(isolate, kLocaleOffset);
VerifyObjectField(isolate, kTypeOffset);
VerifyObjectField(isolate, kBreakIteratorOffset);
VerifyObjectField(isolate, kUnicodeStringOffset);
VerifyObjectField(isolate, kBoundAdoptTextOffset);
VerifyObjectField(isolate, kBoundFirstOffset);
VerifyObjectField(isolate, kBoundNextOffset);
VerifyObjectField(isolate, kBoundCurrentOffset);
VerifyObjectField(isolate, kBoundBreakTypeOffset);
}
void JSCollator::JSCollatorVerify(Isolate* isolate) {
CHECK(IsJSCollator());
JSObjectVerify(isolate);
......
......@@ -218,6 +218,7 @@ namespace internal {
#ifdef V8_INTL_SUPPORT
#define INSTANCE_TYPE_LIST(V) \
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
V(JS_INTL_V8_BREAK_ITERATOR_TYPE) \
V(JS_INTL_COLLATOR_TYPE) \
V(JS_INTL_DATE_TIME_FORMAT_TYPE) \
V(JS_INTL_LIST_FORMAT_TYPE) \
......
......@@ -20,6 +20,7 @@
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-break-iterator-inl.h"
#include "src/objects/js-collator-inl.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-collection-inl.h"
......@@ -313,6 +314,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
JSDataView::cast(this)->JSDataViewPrint(os);
break;
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
JSV8BreakIterator::cast(this)->JSV8BreakIteratorPrint(os);
break;
case JS_INTL_COLLATOR_TYPE:
JSCollator::cast(this)->JSCollatorPrint(os);
break;
......@@ -1963,6 +1967,20 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT
}
#ifdef V8_INTL_SUPPORT
void JSV8BreakIterator::JSV8BreakIteratorPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "JSV8BreakIterator");
os << "\n - locale: " << Brief(locale());
os << "\n - type: " << TypeAsString();
os << "\n - break iterator: " << Brief(break_iterator());
os << "\n - unicode string: " << Brief(unicode_string());
os << "\n - bound adopt text: " << Brief(bound_adopt_text());
os << "\n - bound first: " << Brief(bound_first());
os << "\n - bound next: " << Brief(bound_next());
os << "\n - bound current: " << Brief(bound_current());
os << "\n - bound break type: " << Brief(bound_break_type());
os << "\n";
}
void JSCollator::JSCollatorPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "JSCollator");
os << "\n - icu collator: " << Brief(icu_collator());
......
......@@ -61,6 +61,7 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-break-iterator.h"
#include "src/objects/js-collator.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-collection-inl.h"
......@@ -1457,6 +1458,8 @@ int JSObject::GetHeaderSize(InstanceType type,
case JS_MODULE_NAMESPACE_TYPE:
return JSModuleNamespace::kHeaderSize;
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
return JSV8BreakIterator::kSize;
case JS_INTL_COLLATOR_TYPE:
return JSCollator::kSize;
case JS_INTL_DATE_TIME_FORMAT_TYPE:
......@@ -3206,6 +3209,7 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_REGEXP_TYPE:
case JS_REGEXP_STRING_ITERATOR_TYPE:
#ifdef V8_INTL_SUPPORT
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
case JS_INTL_COLLATOR_TYPE:
case JS_INTL_DATE_TIME_FORMAT_TYPE:
case JS_INTL_LIST_FORMAT_TYPE:
......
......@@ -75,6 +75,7 @@
// - JSDate
// - JSMessageObject
// - JSModuleNamespace
// - JSV8BreakIterator // If V8_INTL_SUPPORT enabled.
// - JSCollator // If V8_INTL_SUPPORT enabled.
// - JSDateTimeFormat // If V8_INTL_SUPPORT enabled.
// - JSListFormat // If V8_INTL_SUPPORT enabled.
......@@ -587,6 +588,7 @@ enum InstanceType : uint16_t {
JS_DATA_VIEW_TYPE,
#ifdef V8_INTL_SUPPORT
JS_INTL_V8_BREAK_ITERATOR_TYPE,
JS_INTL_COLLATOR_TYPE,
JS_INTL_DATE_TIME_FORMAT_TYPE,
JS_INTL_LIST_FORMAT_TYPE,
......@@ -707,6 +709,7 @@ class JSAsyncGeneratorObject;
class JSGlobalObject;
class JSGlobalProxy;
#ifdef V8_INTL_SUPPORT
class JSV8BreakIterator;
class JSCollator;
class JSDateTimeFormat;
class JSListFormat;
......@@ -921,6 +924,7 @@ class ZoneForwardList;
#ifdef V8_INTL_SUPPORT
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V) \
V(JSV8BreakIterator) \
V(JSCollator) \
V(JSDateTimeFormat) \
V(JSListFormat) \
......@@ -1041,14 +1045,15 @@ 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(JSDateTimeFormat, JS_INTL_DATE_TIME_FORMAT_TYPE) \
V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE) \
V(JSLocale, JS_INTL_LOCALE_TYPE) \
V(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE) \
V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \
#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \
INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V) \
V(JSV8BreakIterator, JS_INTL_V8_BREAK_ITERATOR_TYPE) \
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(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE) \
V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \
V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE)
#else
......
......@@ -75,21 +75,6 @@ std::string Intl::GetNumberingSystem(const icu::Locale& icu_locale) {
}
namespace {
bool ExtractStringSetting(Isolate* isolate, Handle<JSObject> options,
const char* key, icu::UnicodeString* setting) {
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
Handle<Object> object =
JSReceiver::GetProperty(isolate, options, str).ToHandleChecked();
if (object->IsString()) {
v8::String::Utf8Value utf8_string(
v8_isolate, v8::Utils::ToLocal(Handle<String>::cast(object)));
*setting = icu::UnicodeString::fromUTF8(*utf8_string);
return true;
}
return false;
}
// ecma-402/#sec-isvalidtimezonename
bool IsValidTimeZoneName(const icu::TimeZone& tz) {
UErrorCode status = U_ZERO_ERROR;
......@@ -219,64 +204,6 @@ void SetResolvedDateSettings(Isolate* isolate, const icu::Locale& icu_locale,
.Assert();
}
}
icu::BreakIterator* CreateICUBreakIterator(Isolate* isolate,
const icu::Locale& icu_locale,
Handle<JSObject> options) {
UErrorCode status = U_ZERO_ERROR;
icu::BreakIterator* break_iterator = nullptr;
icu::UnicodeString type;
if (!ExtractStringSetting(isolate, options, "type", &type)) return nullptr;
if (type == UNICODE_STRING_SIMPLE("character")) {
break_iterator =
icu::BreakIterator::createCharacterInstance(icu_locale, status);
} else if (type == UNICODE_STRING_SIMPLE("sentence")) {
break_iterator =
icu::BreakIterator::createSentenceInstance(icu_locale, status);
} else if (type == UNICODE_STRING_SIMPLE("line")) {
break_iterator = icu::BreakIterator::createLineInstance(icu_locale, status);
} else {
// Defualt is word iterator.
break_iterator = icu::BreakIterator::createWordInstance(icu_locale, status);
}
if (U_FAILURE(status)) {
delete break_iterator;
return nullptr;
}
isolate->CountUsage(v8::Isolate::UseCounterFeature::kBreakIterator);
return break_iterator;
}
void SetResolvedBreakIteratorSettings(Isolate* isolate,
const icu::Locale& icu_locale,
icu::BreakIterator* break_iterator,
Handle<JSObject> resolved) {
Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
// Set the locale
char result[ULOC_FULLNAME_CAPACITY];
status = U_ZERO_ERROR;
uloc_toLanguageTag(icu_locale.getName(), result, ULOC_FULLNAME_CAPACITY,
FALSE, &status);
if (U_SUCCESS(status)) {
JSObject::SetProperty(
isolate, resolved, factory->NewStringFromStaticChars("locale"),
factory->NewStringFromAsciiChecked(result), LanguageMode::kSloppy)
.Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
isolate, resolved, factory->NewStringFromStaticChars("locale"),
factory->NewStringFromStaticChars("und"), LanguageMode::kSloppy)
.Assert();
}
}
} // namespace
MaybeHandle<JSObject> Intl::CachedOrNewService(
......@@ -378,73 +305,6 @@ void DateFormat::DeleteDateFormat(const v8::WeakCallbackInfo<void>& data) {
GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter()));
}
icu::BreakIterator* V8BreakIterator::InitializeBreakIterator(
Isolate* isolate, Handle<String> locale, Handle<JSObject> options,
Handle<JSObject> resolved) {
icu::Locale icu_locale = Intl::CreateICULocale(isolate, locale);
DCHECK(!icu_locale.isBogus());
icu::BreakIterator* break_iterator =
CreateICUBreakIterator(isolate, icu_locale, options);
if (!break_iterator) {
// Remove extensions and try again.
icu::Locale no_extension_locale(icu_locale.getBaseName());
break_iterator =
CreateICUBreakIterator(isolate, no_extension_locale, options);
if (!break_iterator) {
FATAL("Failed to create ICU break iterator, are ICU data files missing?");
}
// Set resolved settings (locale).
SetResolvedBreakIteratorSettings(isolate, no_extension_locale,
break_iterator, resolved);
} else {
SetResolvedBreakIteratorSettings(isolate, icu_locale, break_iterator,
resolved);
}
CHECK_NOT_NULL(break_iterator);
return break_iterator;
}
icu::BreakIterator* V8BreakIterator::UnpackBreakIterator(Handle<JSObject> obj) {
return reinterpret_cast<icu::BreakIterator*>(
obj->GetEmbedderField(V8BreakIterator::kBreakIteratorIndex));
}
void V8BreakIterator::DeleteBreakIterator(
const v8::WeakCallbackInfo<void>& data) {
delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0));
delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1));
GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter()));
}
void V8BreakIterator::AdoptText(Isolate* isolate,
Handle<JSObject> break_iterator_holder,
Handle<String> text) {
icu::BreakIterator* break_iterator =
V8BreakIterator::UnpackBreakIterator(break_iterator_holder);
CHECK_NOT_NULL(break_iterator);
icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
break_iterator_holder->GetEmbedderField(
V8BreakIterator::kUnicodeStringIndex));
delete u_text;
int length = text->length();
text = String::Flatten(isolate, text);
DisallowHeapAllocation no_gc;
String::FlatContent flat = text->GetFlatContent();
std::unique_ptr<uc16[]> sap;
const UChar* text_value = GetUCharBufferFromFlat(flat, &sap, length);
u_text = new icu::UnicodeString(text_value, length);
break_iterator_holder->SetEmbedderField(V8BreakIterator::kUnicodeStringIndex,
reinterpret_cast<Smi*>(u_text));
break_iterator->setText(*u_text);
}
MaybeHandle<String> Intl::ToString(Isolate* isolate,
const icu::UnicodeString& string) {
return isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
......
......@@ -67,57 +67,6 @@ class DateFormat {
DateFormat();
};
class V8BreakIterator {
public:
// Create a BreakIterator for the specificied locale and options. Returns the
// resolved settings for the locale / options.
static icu::BreakIterator* InitializeBreakIterator(Isolate* isolate,
Handle<String> locale,
Handle<JSObject> options,
Handle<JSObject> resolved);
// Unpacks break iterator object from corresponding JavaScript object.
static icu::BreakIterator* UnpackBreakIterator(Handle<JSObject> obj);
// Release memory we allocated for the BreakIterator once the JS object that
// holds the pointer gets garbage collected.
static void DeleteBreakIterator(const v8::WeakCallbackInfo<void>& data);
static void AdoptText(Isolate* isolate,
Handle<JSObject> break_iterator_holder,
Handle<String> text);
// Layout description.
#define BREAK_ITERATOR_FIELDS(V) \
/* Pointer fields. */ \
V(kBreakIterator, kPointerSize) \
V(kUnicodeString, kPointerSize) \
V(kBoundAdoptText, kPointerSize) \
V(kBoundFirst, kPointerSize) \
V(kBoundNext, kPointerSize) \
V(kBoundCurrent, kPointerSize) \
V(kBoundBreakType, kPointerSize) \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, BREAK_ITERATOR_FIELDS)
#undef BREAK_ITERATOR_FIELDS
// TODO(ryzokuken): Remove this and use regular accessors once v8BreakIterator
// is a subclass of JSObject
//
// This needs to be consistent with the above Layour Description
static const int kBreakIteratorIndex = 0;
static const int kUnicodeStringIndex = 1;
static const int kBoundAdoptTextIndex = 2;
static const int kBoundFirstIndex = 3;
static const int kBoundNextIndex = 4;
static const int kBoundCurrentIndex = 5;
static const int kBoundBreakTypeIndex = 6;
private:
V8BreakIterator();
};
class Intl {
public:
enum Type {
......
// 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_BREAK_ITERATOR_INL_H_
#define V8_OBJECTS_JS_BREAK_ITERATOR_INL_H_
#include "src/objects-inl.h"
#include "src/objects/js-break-iterator.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
ACCESSORS(JSV8BreakIterator, locale, String, kLocaleOffset)
SMI_ACCESSORS(JSV8BreakIterator, type, kTypeOffset)
ACCESSORS(JSV8BreakIterator, break_iterator, Managed<icu::BreakIterator>,
kBreakIteratorOffset)
ACCESSORS(JSV8BreakIterator, unicode_string, Managed<icu::UnicodeString>,
kUnicodeStringOffset)
ACCESSORS(JSV8BreakIterator, bound_adopt_text, Object, kBoundAdoptTextOffset)
ACCESSORS(JSV8BreakIterator, bound_first, Object, kBoundFirstOffset)
ACCESSORS(JSV8BreakIterator, bound_next, Object, kBoundNextOffset)
ACCESSORS(JSV8BreakIterator, bound_current, Object, kBoundCurrentOffset)
ACCESSORS(JSV8BreakIterator, bound_break_type, Object, kBoundBreakTypeOffset)
CAST_ACCESSOR(JSV8BreakIterator)
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_BREAK_ITERATOR_INL_H_
// 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-break-iterator.h"
#include "src/objects/intl-objects-inl.h"
#include "src/objects/intl-objects.h"
#include "src/objects/js-break-iterator-inl.h"
#include "unicode/brkiter.h"
namespace v8 {
namespace internal {
JSV8BreakIterator::Type JSV8BreakIterator::getType(const char* str) {
if (strcmp(str, "character") == 0) return Type::CHARACTER;
if (strcmp(str, "word") == 0) return Type::WORD;
if (strcmp(str, "sentence") == 0) return Type::SENTENCE;
if (strcmp(str, "line") == 0) return Type::LINE;
UNREACHABLE();
}
MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::InitializeV8BreakIterator(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
Handle<Object> input_locales, Handle<Object> input_options) {
Factory* factory = isolate->factory();
// If no options were provided, fallback to { __proto__: null }
if (input_options->IsUndefined(isolate)) {
input_options = factory->NewJSObjectWithNullProto();
}
// Extract locale string
Handle<JSObject> r;
ASSIGN_RETURN_ON_EXCEPTION(isolate, r,
Intl::ResolveLocale(isolate, "breakiterator",
input_locales, input_options),
JSV8BreakIterator);
Handle<Object> locale_obj =
JSObject::GetDataProperty(r, factory->locale_string());
CHECK(locale_obj->IsString());
Handle<String> locale = Handle<String>::cast(locale_obj);
// Extract type from options
std::unique_ptr<char[]> type_str = nullptr;
std::vector<const char*> type_values = {"character", "word", "sentence",
"line"};
Maybe<bool> maybe_found_type = Intl::GetStringOption(
isolate, Handle<JSReceiver>::cast(input_options), "type", type_values,
"Intl.v8BreakIterator", &type_str);
Type type_enum = Type::WORD;
MAYBE_RETURN(maybe_found_type, MaybeHandle<JSV8BreakIterator>());
if (maybe_found_type.FromJust()) {
DCHECK_NOT_NULL(type_str.get());
type_enum = getType(type_str.get());
}
// Construct icu_locale using the locale string
icu::Locale icu_locale = Intl::CreateICULocale(isolate, locale);
DCHECK(!icu_locale.isBogus());
// Construct break_iterator using icu_locale and type
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::BreakIterator> break_iterator = nullptr;
switch (type_enum) {
case Type::CHARACTER:
break_iterator.reset(
icu::BreakIterator::createCharacterInstance(icu_locale, status));
break;
case Type::SENTENCE:
break_iterator.reset(
icu::BreakIterator::createSentenceInstance(icu_locale, status));
break;
case Type::LINE:
break_iterator.reset(
icu::BreakIterator::createLineInstance(icu_locale, status));
break;
default:
break_iterator.reset(
icu::BreakIterator::createWordInstance(icu_locale, status));
break;
}
// Error handling for break_iterator
if (U_FAILURE(status)) {
FATAL("Failed to create ICU break iterator, are ICU data files missing?");
}
CHECK_NOT_NULL(break_iterator.get());
isolate->CountUsage(v8::Isolate::UseCounterFeature::kBreakIterator);
// Construct managed objects from pointers
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0,
std::move(break_iterator));
Handle<Managed<icu::UnicodeString>> managed_unicode_string =
Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, nullptr);
// Setting fields
break_iterator_holder->set_locale(*locale);
break_iterator_holder->set_type(static_cast<int>(type_enum));
break_iterator_holder->set_break_iterator(*managed_break_iterator);
break_iterator_holder->set_unicode_string(*managed_unicode_string);
// Return break_iterator_holder
return break_iterator_holder;
}
Handle<JSObject> JSV8BreakIterator::ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator) {
Factory* factory = isolate->factory();
Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
Handle<String> locale(break_iterator->locale(), isolate);
JSObject::AddProperty(isolate, result, factory->locale_string(), locale,
NONE);
JSObject::AddProperty(isolate, result, factory->type_string(),
break_iterator->TypeAsString(), NONE);
return result;
}
icu::BreakIterator* JSV8BreakIterator::UnpackBreakIterator(
Handle<JSV8BreakIterator> obj) {
return Managed<icu::BreakIterator>::cast(obj->break_iterator())->raw();
}
void JSV8BreakIterator::AdoptText(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
Handle<String> text) {
icu::UnicodeString* u_text;
int length = text->length();
text = String::Flatten(isolate, text);
{
DisallowHeapAllocation no_gc;
String::FlatContent flat = text->GetFlatContent();
std::unique_ptr<uc16[]> sap;
const UChar* text_value = GetUCharBufferFromFlat(flat, &sap, length);
u_text = new icu::UnicodeString(text_value, length);
}
Handle<Managed<icu::UnicodeString>> new_u_text =
Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, u_text);
break_iterator_holder->set_unicode_string(*new_u_text);
icu::BreakIterator* break_iterator =
break_iterator_holder->break_iterator()->raw();
CHECK_NOT_NULL(break_iterator);
break_iterator->setText(*u_text);
}
Handle<String> JSV8BreakIterator::TypeAsString() const {
switch (static_cast<Type>(type())) {
case Type::CHARACTER:
return GetReadOnlyRoots().character_string_handle();
case Type::WORD:
return GetReadOnlyRoots().word_string_handle();
case Type::SENTENCE:
return GetReadOnlyRoots().sentence_string_handle();
case Type::LINE:
return GetReadOnlyRoots().line_string_handle();
case Type::COUNT:
UNREACHABLE();
}
}
} // namespace internal
} // namespace v8
// 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_BREAK_ITERATOR_H_
#define V8_OBJECTS_JS_BREAK_ITERATOR_H_
#include "src/objects.h"
#include "src/objects/intl-objects.h"
#include "src/objects/managed.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
class JSV8BreakIterator : public JSObject {
public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator>
InitializeV8BreakIterator(Isolate* isolate,
Handle<JSV8BreakIterator> break_iterator_holder,
Handle<Object> input_locales,
Handle<Object> input_options);
static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator);
static icu::BreakIterator* UnpackBreakIterator(Handle<JSV8BreakIterator> obj);
static void AdoptText(Isolate* isolate,
Handle<JSV8BreakIterator> break_iterator_holder,
Handle<String> text);
enum class Type { CHARACTER, WORD, SENTENCE, LINE, COUNT };
Handle<String> TypeAsString() const;
DECL_CAST(JSV8BreakIterator)
DECL_PRINTER(JSV8BreakIterator)
DECL_VERIFIER(JSV8BreakIterator)
DECL_ACCESSORS(locale, String)
// TODO(ryzokuken): Change this to accept and return a Type instead of int.
DECL_INT_ACCESSORS(type)
DECL_ACCESSORS(break_iterator, Managed<icu::BreakIterator>)
DECL_ACCESSORS(unicode_string, Managed<icu::UnicodeString>)
DECL_ACCESSORS(bound_adopt_text, Object)
DECL_ACCESSORS(bound_first, Object)
DECL_ACCESSORS(bound_next, Object)
DECL_ACCESSORS(bound_current, Object)
DECL_ACCESSORS(bound_break_type, Object)
// Layout description.
#define BREAK_ITERATOR_FIELDS(V) \
/* Pointer fields. */ \
V(kLocaleOffset, kPointerSize) \
V(kTypeOffset, kPointerSize) \
V(kBreakIteratorOffset, kPointerSize) \
V(kUnicodeStringOffset, kPointerSize) \
V(kBoundAdoptTextOffset, kPointerSize) \
V(kBoundFirstOffset, kPointerSize) \
V(kBoundNextOffset, kPointerSize) \
V(kBoundCurrentOffset, kPointerSize) \
V(kBoundBreakTypeOffset, kPointerSize) \
/* Total Size */ \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, BREAK_ITERATOR_FIELDS)
#undef BREAK_ITERATOR_FIELDS
private:
static Type getType(const char* str);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSV8BreakIterator)
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_BREAK_ITERATOR_H_
......@@ -324,44 +324,6 @@ RUNTIME_FUNCTION(Runtime_PluralRulesSelect) {
isolate, JSPluralRules::ResolvePlural(isolate, plural_rules, number));
}
RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
Handle<JSFunction> constructor(
isolate->native_context()->intl_v8_break_iterator_function(), isolate);
Handle<JSObject> local_object;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object,
JSObject::New(constructor, constructor));
// Set break iterator as embedder field of the resulting JS object.
icu::BreakIterator* break_iterator = V8BreakIterator::InitializeBreakIterator(
isolate, locale, options, resolved);
CHECK_NOT_NULL(break_iterator);
if (!break_iterator) return isolate->ThrowIllegalOperation();
local_object->SetEmbedderField(V8BreakIterator::kBreakIteratorIndex,
reinterpret_cast<Smi*>(break_iterator));
// Make sure that the pointer to adopted text is nullptr.
local_object->SetEmbedderField(V8BreakIterator::kUnicodeStringIndex,
static_cast<Smi*>(nullptr));
// Make object handle weak so we can delete the break iterator once GC kicks
// in.
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(),
V8BreakIterator::DeleteBreakIterator,
WeakCallbackType::kInternalFields);
return *local_object;
}
RUNTIME_FUNCTION(Runtime_ToDateTimeOptions) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 3);
......
......@@ -203,7 +203,6 @@ namespace internal {
F(AvailableLocalesOf, 1, 1) \
F(CanonicalizeLanguageTag, 1, 1) \
F(CollatorResolvedOptions, 1, 1) \
F(CreateBreakIterator, 3, 1) \
F(CreateDateTimeFormat, 3, 1) \
F(DateCacheVersion, 0, 1) \
F(DateTimeFormatResolvedOptions, 1, 1) \
......@@ -220,8 +219,7 @@ namespace internal {
F(PluralRulesSelect, 2, 1) \
F(ToDateTimeOptions, 3, 1) \
F(StringToLowerCaseIntl, 1, 1) \
F(StringToUpperCaseIntl, 1, 1) \
// End of macro.
F(StringToUpperCaseIntl, 1, 1) // End of macro.
#else
#define FOR_EACH_INTRINSIC_INTL(F)
#endif // V8_INTL_SUPPORT
......
......@@ -159,20 +159,21 @@ INSTANCE_TYPES = {
1081: "JS_WEAK_SET_TYPE",
1082: "JS_TYPED_ARRAY_TYPE",
1083: "JS_DATA_VIEW_TYPE",
1084: "JS_INTL_COLLATOR_TYPE",
1085: "JS_INTL_DATE_TIME_FORMAT_TYPE",
1086: "JS_INTL_LIST_FORMAT_TYPE",
1087: "JS_INTL_LOCALE_TYPE",
1088: "JS_INTL_NUMBER_FORMAT_TYPE",
1089: "JS_INTL_PLURAL_RULES_TYPE",
1090: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
1091: "WASM_GLOBAL_TYPE",
1092: "WASM_INSTANCE_TYPE",
1093: "WASM_MEMORY_TYPE",
1094: "WASM_MODULE_TYPE",
1095: "WASM_TABLE_TYPE",
1096: "JS_BOUND_FUNCTION_TYPE",
1097: "JS_FUNCTION_TYPE",
1084: "JS_INTL_V8_BREAK_ITERATOR_TYPE",
1085: "JS_INTL_COLLATOR_TYPE",
1086: "JS_INTL_DATE_TIME_FORMAT_TYPE",
1087: "JS_INTL_LIST_FORMAT_TYPE",
1088: "JS_INTL_LOCALE_TYPE",
1089: "JS_INTL_NUMBER_FORMAT_TYPE",
1090: "JS_INTL_PLURAL_RULES_TYPE",
1091: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
1092: "WASM_GLOBAL_TYPE",
1093: "WASM_INSTANCE_TYPE",
1094: "WASM_MEMORY_TYPE",
1095: "WASM_MODULE_TYPE",
1096: "WASM_TABLE_TYPE",
1097: "JS_BOUND_FUNCTION_TYPE",
1098: "JS_FUNCTION_TYPE",
}
# List of known V8 maps.
......@@ -287,33 +288,33 @@ KNOWN_MAPS = {
("RO_SPACE", 0x04811): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x04b01): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04bf9): (169, "ScriptMap"),
("RO_SPACE", 0x09c69): (154, "AccessorInfoMap"),
("RO_SPACE", 0x09cb9): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x09d09): (155, "AccessorPairMap"),
("RO_SPACE", 0x09d59): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x09da9): (157, "AllocationMementoMap"),
("RO_SPACE", 0x09df9): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x09e49): (159, "DebugInfoMap"),
("RO_SPACE", 0x09e99): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x09ee9): (162, "InterpreterDataMap"),
("RO_SPACE", 0x09f39): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09f89): (164, "ModuleMap"),
("RO_SPACE", 0x09fd9): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x0a029): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x0a079): (167, "PromiseReactionMap"),
("RO_SPACE", 0x0a0c9): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x0a119): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x0a169): (172, "Tuple3Map"),
("RO_SPACE", 0x0a1b9): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x0a209): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x0a259): (176, "CallableTaskMap"),
("RO_SPACE", 0x0a2a9): (177, "CallbackTaskMap"),
("RO_SPACE", 0x0a2f9): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x0a349): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x0a399): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x0a3e9): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x0a439): (182, "AllocationSiteMap"),
("RO_SPACE", 0x0a489): (182, "AllocationSiteMap"),
("RO_SPACE", 0x09cd1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x09d21): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x09d71): (155, "AccessorPairMap"),
("RO_SPACE", 0x09dc1): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x09e11): (157, "AllocationMementoMap"),
("RO_SPACE", 0x09e61): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x09eb1): (159, "DebugInfoMap"),
("RO_SPACE", 0x09f01): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x09f51): (162, "InterpreterDataMap"),
("RO_SPACE", 0x09fa1): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09ff1): (164, "ModuleMap"),
("RO_SPACE", 0x0a041): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x0a091): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x0a0e1): (167, "PromiseReactionMap"),
("RO_SPACE", 0x0a131): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x0a181): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x0a1d1): (172, "Tuple3Map"),
("RO_SPACE", 0x0a221): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x0a271): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x0a2c1): (176, "CallableTaskMap"),
("RO_SPACE", 0x0a311): (177, "CallbackTaskMap"),
("RO_SPACE", 0x0a361): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x0a3b1): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x0a401): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x0a451): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x0a4a1): (182, "AllocationSiteMap"),
("RO_SPACE", 0x0a4f1): (182, "AllocationSiteMap"),
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
}
......
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