Commit bf95c6fa authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Add Intl.Segmenter.prototype.segment

Design doc https://goo.gl/fgc2Cp

Bug: v8:6891

Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I8bc5ea3137fd1b66213403ae9ea3461f40efc977
Reviewed-on: https://chromium-review.googlesource.com/c/1257923
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56757}
parent 829760a5
......@@ -2265,6 +2265,9 @@ v8_source_set("v8_base") {
"src/objects/js-relative-time-format-inl.h",
"src/objects/js-relative-time-format.cc",
"src/objects/js-relative-time-format.h",
"src/objects/js-segment-iterator-inl.h",
"src/objects/js-segment-iterator.cc",
"src/objects/js-segment-iterator.h",
"src/objects/js-segmenter-inl.h",
"src/objects/js-segmenter.cc",
"src/objects/js-segmenter.h",
......@@ -2999,6 +3002,9 @@ v8_source_set("v8_base") {
"src/objects/js-relative-time-format-inl.h",
"src/objects/js-relative-time-format.cc",
"src/objects/js-relative-time-format.h",
"src/objects/js-segment-iterator-inl.h",
"src/objects/js-segment-iterator.cc",
"src/objects/js-segment-iterator.h",
"src/objects/js-segmenter-inl.h",
"src/objects/js-segmenter.cc",
"src/objects/js-segmenter.h",
......
......@@ -42,6 +42,7 @@
#include "src/objects/js-regexp.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format.h"
#include "src/objects/js-segment-iterator.h"
#include "src/objects/js-segmenter.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-weak-refs.h"
......@@ -4766,17 +4767,69 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() {
SimpleInstallFunction(isolate(), segmenter_fun, "supportedLocalesOf",
Builtins::kSegmenterSupportedLocalesOf, 1, false);
{
// Setup %SegmenterPrototype%.
Handle<JSObject> prototype(
JSObject::cast(segmenter_fun->instance_prototype()), isolate());
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(isolate(), prototype, factory()->to_string_tag_symbol(),
JSObject::AddProperty(
isolate(), prototype, factory()->to_string_tag_symbol(),
factory()->NewStringFromStaticChars("Intl.Segmenter"),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(isolate(), prototype, "resolvedOptions",
Builtins::kSegmenterPrototypeResolvedOptions, 0, false);
Builtins::kSegmenterPrototypeResolvedOptions, 0,
false);
SimpleInstallFunction(isolate(), prototype, "segment",
Builtins::kSegmenterPrototypeSegment, 1, false);
}
{
// Setup %SegmentIteratorPrototype%.
Handle<String> name = factory()->SegmentIterator_string();
Handle<JSObject> iterator_prototype(
native_context()->initial_iterator_prototype(), isolate());
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
JSObject::ForceSetPrototype(prototype, iterator_prototype);
// Install the @@toStringTag property on the {prototype}.
JSObject::AddProperty(
isolate(), prototype, factory()->to_string_tag_symbol(), name,
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(isolate(), prototype, "next",
Builtins::kSegmentIteratorPrototypeNext, 0, false);
SimpleInstallFunction(isolate(), prototype, "following",
Builtins::kSegmentIteratorPrototypeFollowing, 0,
false);
SimpleInstallFunction(isolate(), prototype, "preceding",
Builtins::kSegmentIteratorPrototypePreceding, 0,
false);
SimpleInstallGetter(isolate(), prototype,
factory()->InternalizeUtf8String("position"),
Builtins::kSegmentIteratorPrototypePosition, false);
SimpleInstallGetter(isolate(), prototype,
factory()->InternalizeUtf8String("breakType"),
Builtins::kSegmentIteratorPrototypeBreakType, false);
// Setup SegmentIterator constructor.
Handle<JSFunction> segment_iterator_fun = InstallFunction(
isolate(), intl, "SegmentIterator", JS_INTL_SEGMENT_ITERATOR_TYPE,
JSSegmentIterator::kSize, 0, prototype, Builtins::kIllegal);
segment_iterator_fun->shared()->set_native(false);
Handle<Map> segment_iterator_map(segment_iterator_fun->initial_map(),
isolate());
native_context()->set_intl_segment_iterator_map(*segment_iterator_map);
}
}
#endif // V8_INTL_SUPPORT
......
......@@ -1429,6 +1429,24 @@ namespace internal {
CPP(RelativeTimeFormatPrototypeResolvedOptions) \
/* ecma402 #sec-intl.RelativeTimeFormat.supportedlocalesof */ \
CPP(RelativeTimeFormatSupportedLocalesOf) \
/* ecma402 #sec-Intl.Segmenter */ \
CPP(SegmenterConstructor) \
/* ecma402 #sec-Intl.Segmenter.prototype.resolvedOptions */ \
CPP(SegmenterPrototypeResolvedOptions) \
/* ecma402 #sec-Intl.Segmenter.prototype.segment */ \
CPP(SegmenterPrototypeSegment) \
/* ecma402 #sec-Intl.Segmenter.supportedLocalesOf */ \
CPP(SegmenterSupportedLocalesOf) \
/* ecma402 #sec-segment-iterator-prototype-breakType */ \
CPP(SegmentIteratorPrototypeBreakType) \
/* ecma402 #sec-segment-iterator-prototype-following */ \
CPP(SegmentIteratorPrototypeFollowing) \
/* ecma402 #sec-segment-iterator-prototype-preceding */ \
CPP(SegmentIteratorPrototypePreceding) \
/* ecma402 #sec-segment-iterator-prototype-position */ \
CPP(SegmentIteratorPrototypePosition) \
/* ecma402 #sec-segment-iterator-prototype-next */ \
CPP(SegmentIteratorPrototypeNext) \
/* ES #sec-string.prototype.normalize */ \
CPP(StringPrototypeNormalizeIntl) \
/* ecma402 #sup-string.prototype.tolocalelowercase */ \
......@@ -1440,12 +1458,6 @@ namespace internal {
/* ES #sec-string.prototype.touppercase */ \
CPP(StringPrototypeToUpperCaseIntl) \
TFS(StringToLowerCaseIntl, kString) \
/* ecma402 #sec-Intl.Segmenter */ \
CPP(SegmenterConstructor) \
/* ecma402 #sec-Intl.Segmenter.prototype.resolvedOptions */ \
CPP(SegmenterPrototypeResolvedOptions) \
/* ecma402 #sec-Intl.Segmenter.supportedLocalesOf */ \
CPP(SegmenterSupportedLocalesOf) \
CPP(V8BreakIteratorConstructor) \
CPP(V8BreakIteratorInternalAdoptText) \
CPP(V8BreakIteratorInternalBreakType) \
......
......@@ -26,6 +26,7 @@
#include "src/objects/js-number-format-inl.h"
#include "src/objects/js-plural-rules-inl.h"
#include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segmenter-inl.h"
#include "src/property-descriptor.h"
......@@ -1014,6 +1015,62 @@ BUILTIN(CollatorInternalCompare) {
return *Intl::CompareStrings(isolate, collator_holder, string_x, string_y);
}
// ecma402 #sec-segment-iterator-prototype-breakType
BUILTIN(SegmentIteratorPrototypeBreakType) {
const char* const method = "get %SegmentIteratorPrototype%.breakType";
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
return *segment_iterator->BreakType();
}
// ecma402 #sec-segment-iterator-prototype-following
BUILTIN(SegmentIteratorPrototypeFollowing) {
const char* const method = "%SegmentIteratorPrototype%.following";
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
Handle<Object> from = args.atOrUndefined(isolate, 1);
Maybe<bool> success =
JSSegmentIterator::Following(isolate, segment_iterator, from);
MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
return *isolate->factory()->ToBoolean(success.FromJust());
}
// ecma402 #sec-segment-iterator-prototype-next
BUILTIN(SegmentIteratorPrototypeNext) {
const char* const method = "%SegmentIteratorPrototype%.next";
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
RETURN_RESULT_OR_FAILURE(isolate,
JSSegmentIterator::Next(isolate, segment_iterator));
}
// ecma402 #sec-segment-iterator-prototype-preceding
BUILTIN(SegmentIteratorPrototypePreceding) {
const char* const method = "%SegmentIteratorPrototype%.preceding";
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
Handle<Object> from = args.atOrUndefined(isolate, 1);
Maybe<bool> success =
JSSegmentIterator::Preceding(isolate, segment_iterator, from);
MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
return *isolate->factory()->ToBoolean(success.FromJust());
}
// ecma402 #sec-segment-iterator-prototype-position
BUILTIN(SegmentIteratorPrototypePosition) {
const char* const method = "get %SegmentIteratorPrototype%.position";
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
return *JSSegmentIterator::Position(isolate, segment_iterator);
}
BUILTIN(SegmenterConstructor) {
HandleScope scope(isolate);
......@@ -1063,6 +1120,25 @@ BUILTIN(SegmenterPrototypeResolvedOptions) {
return *JSSegmenter::ResolvedOptions(isolate, segmenter_holder);
}
// ecma402 #sec-Intl.Segmenter.prototype.segment
BUILTIN(SegmenterPrototypeSegment) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegmenter, segmenter_holder,
"Intl.Segmenter.prototype.segment");
Handle<Object> input_text = args.atOrUndefined(isolate, 1);
// 3. Let string be ? ToString(string).
Handle<String> text;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
Object::ToString(isolate, input_text));
// 4. Return ? CreateSegmentIterator(segment, string).
RETURN_RESULT_OR_FAILURE(
isolate,
JSSegmentIterator::Create(
isolate, segmenter_holder->icu_break_iterator()->raw()->clone(),
segmenter_holder->granularity(), text));
}
BUILTIN(V8BreakIteratorConstructor) {
HandleScope scope(isolate);
Handle<JSReceiver> new_target;
......
......@@ -44,6 +44,7 @@ class JSNumberFormat;
class JSPluralRules;
class JSRegExpStringIterator;
class JSRelativeTimeFormat;
class JSSegmentIterator;
class JSSegmenter;
class JSV8BreakIterator;
class JSWeakCell;
......
......@@ -218,6 +218,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
case JS_INTL_SEGMENT_ITERATOR_TYPE:
case JS_INTL_SEGMENTER_TYPE:
#endif // V8_INTL_SUPPORT
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
......
......@@ -208,6 +208,7 @@ enum ContextLookupFlags {
V(INTL_NUMBER_FORMAT_FUNCTION_INDEX, JSFunction, \
intl_number_format_function) \
V(INTL_LOCALE_FUNCTION_INDEX, JSFunction, intl_locale_function) \
V(INTL_SEGMENT_ITERATOR_MAP_INDEX, Map, intl_segment_iterator_map) \
V(JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, Map, \
js_array_packed_smi_elements_map) \
V(JS_ARRAY_HOLEY_SMI_ELEMENTS_MAP_INDEX, Map, \
......
......@@ -7,6 +7,7 @@
#ifdef V8_INTL_SUPPORT
#define INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _) \
V(_, breakType_string, "breakType") \
V(_, calendar_string, "calendar") \
V(_, caseFirst_string, "caseFirst") \
V(_, day_string, "day") \
......@@ -14,11 +15,14 @@
V(_, decimal_string, "decimal") \
V(_, era_string, "era") \
V(_, fraction_string, "fraction") \
V(_, granularity_string, "granularity") \
V(_, grapheme_string, "grapheme") \
V(_, group_string, "group") \
V(_, h11_string, "h11") \
V(_, h12_string, "h12") \
V(_, h23_string, "h23") \
V(_, h24_string, "h24") \
V(_, hard_string, "hard") \
V(_, hour_string, "hour") \
V(_, hour12_string, "hour12") \
V(_, hourCycle_string, "hourCycle") \
......@@ -28,9 +32,11 @@
V(_, ignorePunctuation_string, "ignorePunctuation") \
V(_, Invalid_Date_string, "Invalid Date") \
V(_, integer_string, "integer") \
V(_, lineBreakStyle_string, "lineBreakStyle") \
V(_, literal_string, "literal") \
V(_, locale_string, "locale") \
V(_, localeWithExtension_string, "localeWithExtension") \
V(_, loose_string, "loose") \
V(_, lower_string, "lower") \
V(_, maximumFractionDigits_string, "maximumFractionDigits") \
V(_, maximumSignificantDigits_string, "maximumSignificantDigits") \
......@@ -41,14 +47,22 @@
V(_, minusSign_string, "minusSign") \
V(_, minute_string, "minute") \
V(_, month_string, "month") \
V(_, none_string, "none") \
V(_, normal_string, "normal") \
V(_, numberingSystem_string, "numberingSystem") \
V(_, numeric_string, "numeric") \
V(_, percentSign_string, "percentSign") \
V(_, plusSign_string, "plusSign") \
V(_, quarter_string, "quarter") \
V(_, second_string, "second") \
V(_, segment_string, "segment") \
V(_, SegmentIterator_string, "Segment Iterator") \
V(_, sensitivity_string, "sensitivity") \
V(_, sep_string, "sep") \
V(_, soft_string, "soft") \
V(_, strict_string, "strict") \
V(_, style_string, "style") \
V(_, term_string, "term") \
V(_, timeZone_string, "timeZone") \
V(_, timeZoneName_string, "timeZoneName") \
V(_, type_string, "type") \
......@@ -151,8 +165,6 @@
V(_, getPrototypeOf_string, "getPrototypeOf") \
V(_, global_string, "global") \
V(_, globalThis_string, "globalThis") \
V(_, granularity_string, "granularity") \
V(_, grapheme_string, "grapheme") \
V(_, groups_string, "groups") \
V(_, has_string, "has") \
V(_, holdings_string, "holdings") \
......@@ -174,11 +186,9 @@
V(_, lastIndex_string, "lastIndex") \
V(_, length_string, "length") \
V(_, let_string, "let") \
V(_, lineBreakStyle_string, "lineBreakStyle") \
V(_, line_string, "line") \
V(_, LinkError_string, "LinkError") \
V(_, long_string, "long") \
V(_, loose_string, "loose") \
V(_, makeCell_string, "makeCell") \
V(_, Map_string, "Map") \
V(_, MapIterator_string, "Map Iterator") \
......@@ -198,7 +208,6 @@
V(_, NFKC_string, "NFKC") \
V(_, NFKD_string, "NFKD") \
V(_, not_equal, "not-equal") \
V(_, normal_string, "normal") \
V(_, null_string, "null") \
V(_, null_to_string, "[object Null]") \
V(_, Number_string, "Number") \
......@@ -248,7 +257,6 @@
V(_, stackTraceLimit_string, "stackTraceLimit") \
V(_, star_default_star_string, "*default*") \
V(_, sticky_string, "sticky") \
V(_, strict_string, "strict") \
V(_, String_string, "String") \
V(_, string_string, "string") \
V(_, string_to_string, "[object String]") \
......
......@@ -326,6 +326,8 @@ namespace internal {
T(LetInLexicalBinding, "let is disallowed as a lexically bound name") \
T(LocaleMatcher, "Illegal value for localeMatcher:%") \
T(NormalizationForm, "The normalization form should be one of %.") \
T(ParameterOfFunctionOutOfRange, \
"Paramenter % of function %() is % and out of range") \
T(ZeroDigitNumericSeparator, \
"Numeric separator can not be used after leading 0.") \
T(NumberFormatRange, "% argument must be between 0 and 100") \
......
......@@ -833,6 +833,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
case JS_INTL_SEGMENT_ITERATOR_TYPE:
case JS_INTL_SEGMENTER_TYPE:
#endif // V8_INTL_SUPPORT
case WASM_EXCEPTION_TYPE:
......
......@@ -38,6 +38,7 @@
#include "src/objects/js-regexp-string-iterator-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segmenter-inl.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-weak-refs-inl.h"
......@@ -404,6 +405,9 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
JSRelativeTimeFormat::cast(this)->JSRelativeTimeFormatVerify(isolate);
break;
case JS_INTL_SEGMENT_ITERATOR_TYPE:
JSSegmentIterator::cast(this)->JSSegmentIteratorVerify(isolate);
break;
case JS_INTL_SEGMENTER_TYPE:
JSSegmenter::cast(this)->JSSegmenterVerify(isolate);
break;
......@@ -2023,6 +2027,13 @@ void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
VerifyObjectField(isolate, kFlagsOffset);
}
void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
VerifyObjectField(isolate, kICUBreakIteratorOffset);
VerifyObjectField(isolate, kUnicodeStringOffset);
VerifyObjectField(isolate, kFlagsOffset);
}
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
JSObjectVerify(isolate);
VerifyObjectField(isolate, kLocaleOffset);
......
......@@ -232,6 +232,7 @@ namespace internal {
V(JS_INTL_NUMBER_FORMAT_TYPE) \
V(JS_INTL_PLURAL_RULES_TYPE) \
V(JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \
V(JS_INTL_SEGMENT_ITERATOR_TYPE) \
V(JS_INTL_SEGMENTER_TYPE) \
INSTANCE_TYPE_LIST_AFTER_INTL(V)
#else
......
......@@ -38,6 +38,7 @@
#include "src/objects/js-regexp-string-iterator-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segmenter-inl.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-weak-refs-inl.h"
......@@ -355,6 +356,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
JSRelativeTimeFormat::cast(this)->JSRelativeTimeFormatPrint(os);
break;
case JS_INTL_SEGMENT_ITERATOR_TYPE:
JSSegmentIterator::cast(this)->JSSegmentIteratorPrint(os);
break;
case JS_INTL_SEGMENTER_TYPE:
JSSegmenter::cast(this)->JSSegmenterPrint(os);
break;
......@@ -2071,12 +2075,20 @@ void JSRelativeTimeFormat::JSRelativeTimeFormatPrint(
os << "\n";
}
void JSSegmentIterator::JSSegmentIteratorPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "JSSegmentIterator");
os << "\n - icu break iterator: " << Brief(icu_break_iterator());
os << "\n - unicode string: " << Brief(unicode_string());
os << "\n - granularity: " << GranularityAsString();
os << "\n";
}
void JSSegmenter::JSSegmenterPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "JSSegmenter");
os << "\n - locale: " << Brief(locale());
os << "\n - granularity: " << GranularityAsString();
os << "\n - lineBreakStyle: " << LineBreakStyleAsString();
os << "\n - icubreak iterator: " << Brief(icu_break_iterator());
os << "\n - icu break iterator: " << Brief(icu_break_iterator());
os << "\n";
}
#endif // V8_INTL_SUPPORT
......
......@@ -79,6 +79,7 @@
#include "src/objects/js-regexp-string-iterator.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format.h"
#include "src/objects/js-segment-iterator.h"
#include "src/objects/js-segmenter.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-weak-refs-inl.h"
......@@ -1484,6 +1485,8 @@ int JSObject::GetHeaderSize(InstanceType type,
return JSPluralRules::kSize;
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
return JSRelativeTimeFormat::kSize;
case JS_INTL_SEGMENT_ITERATOR_TYPE:
return JSSegmentIterator::kSize;
case JS_INTL_SEGMENTER_TYPE:
return JSSegmenter::kSize;
#endif // V8_INTL_SUPPORT
......@@ -3242,6 +3245,7 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
case JS_INTL_SEGMENT_ITERATOR_TYPE:
case JS_INTL_SEGMENTER_TYPE:
#endif // V8_INTL_SUPPORT
case WASM_EXCEPTION_TYPE:
......@@ -13118,6 +13122,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
case JS_INTL_SEGMENT_ITERATOR_TYPE:
case JS_INTL_SEGMENTER_TYPE:
case JS_INTL_V8_BREAK_ITERATOR_TYPE:
#endif
......
......@@ -84,6 +84,7 @@
// - JSNumberFormat // If V8_INTL_SUPPORT enabled.
// - JSPluralRules // If V8_INTL_SUPPORT enabled.
// - JSRelativeTimeFormat // If V8_INTL_SUPPORT enabled.
// - JSSegmentIterator // If V8_INTL_SUPPORT enabled.
// - JSSegmenter // If V8_INTL_SUPPORT enabled.
// - WasmExceptionObject
// - WasmGlobalObject
......@@ -537,6 +538,7 @@ enum InstanceType : uint16_t {
JS_INTL_NUMBER_FORMAT_TYPE,
JS_INTL_PLURAL_RULES_TYPE,
JS_INTL_RELATIVE_TIME_FORMAT_TYPE,
JS_INTL_SEGMENT_ITERATOR_TYPE,
JS_INTL_SEGMENTER_TYPE,
#endif // V8_INTL_SUPPORT
......@@ -865,6 +867,7 @@ class ZoneForwardList;
V(JSNumberFormat) \
V(JSPluralRules) \
V(JSRelativeTimeFormat) \
V(JSSegmentIterator) \
V(JSSegmenter)
#else
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) HEAP_OBJECT_ORDINARY_TYPE_LIST_BASE(V)
......@@ -995,6 +998,7 @@ class ZoneForwardList;
V(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE) \
V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \
V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \
V(JSSegmentIterator, JS_INTL_SEGMENT_ITERATOR_TYPE) \
V(JSSegmenter, JS_INTL_SEGMENTER_TYPE)
#else
......
......@@ -1557,5 +1557,25 @@ Intl::ResolvedLocale Intl::ResolveLocale(
return Intl::ResolvedLocale{locale, icu_locale, extensions};
}
Managed<icu::UnicodeString>* Intl::SetTextToBreakIterator(
Isolate* isolate, Handle<String> text, icu::BreakIterator* break_iterator) {
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->setText(*u_text);
return *new_u_text;
}
} // namespace internal
} // namespace v8
......@@ -16,10 +16,12 @@
#include "src/contexts.h"
#include "src/intl.h"
#include "src/objects.h"
#include "src/objects/managed.h"
#include "unicode/locid.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class BreakIterator;
class DecimalFormat;
class SimpleDateFormat;
class UnicodeString;
......@@ -218,6 +220,11 @@ class Intl {
Isolate* isolate, const std::set<std::string>& available_locales,
const std::vector<std::string>& requested_locales, MatcherOption options,
const std::set<std::string>& relevant_extension_keys);
// Utility function to set text to BreakIterator.
static Managed<icu::UnicodeString>* SetTextToBreakIterator(
Isolate* isolate, Handle<String> text,
icu::BreakIterator* break_iterator);
};
} // namespace internal
......
......@@ -146,25 +146,12 @@ Handle<JSObject> JSV8BreakIterator::ResolvedOptions(
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);
Managed<icu::UnicodeString>* unicode_string =
Intl::SetTextToBreakIterator(isolate, text, break_iterator);
break_iterator_holder->set_unicode_string(unicode_string);
}
Handle<String> JSV8BreakIterator::TypeAsString() const {
......
// 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_SEGMENT_ITERATOR_INL_H_
#define V8_OBJECTS_JS_SEGMENT_ITERATOR_INL_H_
#include "src/objects-inl.h"
#include "src/objects/js-segment-iterator.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
// Base segment iterator accessors.
ACCESSORS(JSSegmentIterator, icu_break_iterator, Managed<icu::BreakIterator>,
kICUBreakIteratorOffset)
ACCESSORS(JSSegmentIterator, unicode_string, Managed<icu::UnicodeString>,
kUnicodeStringOffset)
SMI_ACCESSORS(JSSegmentIterator, flags, kFlagsOffset)
CAST_ACCESSOR(JSSegmentIterator);
inline void JSSegmentIterator::set_granularity(
JSSegmenter::Granularity granularity) {
DCHECK_GT(JSSegmenter::Granularity::COUNT, granularity);
int hints = flags();
hints = GranularityBits::update(hints, granularity);
set_flags(hints);
}
inline JSSegmenter::Granularity JSSegmentIterator::granularity() const {
return GranularityBits::decode(flags());
}
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_SEGMENT_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-segment-iterator.h"
#include <map>
#include <memory>
#include <string>
#include "src/heap/factory.h"
#include "src/intl.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/intl-objects.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/managed.h"
#include "unicode/brkiter.h"
namespace v8 {
namespace internal {
MaybeHandle<String> JSSegmentIterator::GetSegment(Isolate* isolate,
int32_t start,
int32_t end) const {
return Intl::ToString(isolate, *(unicode_string()->raw()), start, end);
}
Handle<String> JSSegmentIterator::GranularityAsString() const {
switch (granularity()) {
case JSSegmenter::Granularity::GRAPHEME:
return GetReadOnlyRoots().grapheme_string_handle();
case JSSegmenter::Granularity::WORD:
return GetReadOnlyRoots().word_string_handle();
case JSSegmenter::Granularity::SENTENCE:
return GetReadOnlyRoots().sentence_string_handle();
case JSSegmenter::Granularity::LINE:
return GetReadOnlyRoots().line_string_handle();
case JSSegmenter::Granularity::COUNT:
UNREACHABLE();
}
}
MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
Isolate* isolate, icu::BreakIterator* break_iterator,
JSSegmenter::Granularity granularity, Handle<String> text) {
CHECK_NOT_NULL(break_iterator);
// 1. Let iterator be ObjectCreate(%SegmentIteratorPrototype%).
Handle<Map> map = Handle<Map>(
isolate->native_context()->intl_segment_iterator_map(), isolate);
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
Handle<JSSegmentIterator> segment_iterator =
Handle<JSSegmentIterator>::cast(result);
segment_iterator->set_flags(0);
segment_iterator->set_granularity(granularity);
// 2. Let iterator.[[SegmentIteratorSegmenter]] be segmenter.
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
segment_iterator->set_icu_break_iterator(*managed_break_iterator);
// 3. Let iterator.[[SegmentIteratorString]] be string.
Managed<icu::UnicodeString>* unicode_string =
Intl::SetTextToBreakIterator(isolate, text, break_iterator);
segment_iterator->set_unicode_string(unicode_string);
// 4. Let iterator.[[SegmentIteratorPosition]] be 0.
// 5. Let iterator.[[SegmentIteratorBreakType]] be an implementation-dependent
// string representing a break at the edge of a string.
// step 4 and 5 are stored inside break_iterator.
return segment_iterator;
}
// ecma402 #sec-segment-iterator-prototype-breakType
Handle<Object> JSSegmentIterator::BreakType() const {
icu::BreakIterator* break_iterator = icu_break_iterator()->raw();
int32_t rule_status = break_iterator->getRuleStatus();
switch (granularity()) {
case JSSegmenter::Granularity::GRAPHEME:
return GetReadOnlyRoots().undefined_value_handle();
case JSSegmenter::Granularity::WORD:
if (rule_status >= UBRK_WORD_NONE && rule_status < UBRK_WORD_NONE_LIMIT) {
// "words" that do not fit into any of other categories. Includes spaces
// and most punctuation.
return GetReadOnlyRoots().none_string_handle();
}
if ((rule_status >= UBRK_WORD_NUMBER &&
rule_status < UBRK_WORD_NUMBER_LIMIT) ||
(rule_status >= UBRK_WORD_LETTER &&
rule_status < UBRK_WORD_LETTER_LIMIT) ||
(rule_status >= UBRK_WORD_KANA &&
rule_status < UBRK_WORD_KANA_LIMIT) ||
(rule_status >= UBRK_WORD_IDEO &&
rule_status < UBRK_WORD_IDEO_LIMIT)) {
// words that appear to be numbers, letters, kana characters,
// ideographic characters, etc
return GetReadOnlyRoots().word_string_handle();
}
return GetReadOnlyRoots().undefined_value_handle();
case JSSegmenter::Granularity::LINE:
if (rule_status >= UBRK_LINE_SOFT && rule_status < UBRK_LINE_SOFT_LIMIT) {
// soft line breaks, positions at which a line break is acceptable but
// not required
return GetReadOnlyRoots().soft_string_handle();
}
if ((rule_status >= UBRK_LINE_HARD &&
rule_status < UBRK_LINE_HARD_LIMIT)) {
// hard, or mandatory line breaks
return GetReadOnlyRoots().hard_string_handle();
}
return GetReadOnlyRoots().undefined_value_handle();
case JSSegmenter::Granularity::SENTENCE:
if (rule_status >= UBRK_SENTENCE_TERM &&
rule_status < UBRK_SENTENCE_TERM_LIMIT) {
// sentences ending with a sentence terminator ('.', '?', '!', etc.)
// character, possibly followed by a hard separator (CR, LF, PS, etc.)
return GetReadOnlyRoots().term_string_handle();
}
if ((rule_status >= UBRK_SENTENCE_SEP &&
rule_status < UBRK_SENTENCE_SEP_LIMIT)) {
// sentences that do not contain an ending sentence terminator ('.',
// '?', '!', etc.) character, but are ended only by a hard separator
// (CR, LF, PS, etc.) hard, or mandatory line breaks
return GetReadOnlyRoots().sep_string_handle();
}
return GetReadOnlyRoots().undefined_value_handle();
case JSSegmenter::Granularity::COUNT:
UNREACHABLE();
}
}
// ecma402 #sec-segment-iterator-prototype-position
Handle<Object> JSSegmentIterator::Position(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
icu::BreakIterator* icu_break_iterator =
segment_iterator->icu_break_iterator()->raw();
CHECK_NOT_NULL(icu_break_iterator);
return isolate->factory()->NewNumberFromInt(icu_break_iterator->current());
}
namespace {
Handle<JSReceiver> CreateResultForNext(Isolate* isolate, Handle<String> segment,
Handle<Object> break_type) {
Factory* factory = isolate->factory();
// Step 10-13 of %SegmentIteratorPrototype%.next( )
// ecma402 #sec-segment-iterator-prototype-next
// 10. Let result be ! ObjectCreate(%ObjectPrototype%).
Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
// 11. Perform ! CreateDataProperty(result "segment", segment).
CHECK(JSReceiver::CreateDataProperty(
isolate, result, factory->segment_string(), segment, kDontThrow)
.FromJust());
// 12. Perform ! CreateDataProperty(result, "breakType", breakType).
CHECK(JSReceiver::CreateDataProperty(isolate, result,
factory->breakType_string(), break_type,
kDontThrow)
.FromJust());
// 13. Return CreateIterResultObject(result, false).
return factory->NewJSIteratorResult(result, false);
}
} // namespace
// ecma402 #sec-segment-iterator-prototype-next
MaybeHandle<JSReceiver> JSSegmentIterator::Next(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
Factory* factory = isolate->factory();
icu::BreakIterator* icu_break_iterator =
segment_iterator->icu_break_iterator()->raw();
// 3. Let _previousPosition be iterator.[[SegmentIteratorPosition]].
int32_t prev = icu_break_iterator->current();
// 4. Let done be AdvanceSegmentIterator(iterator, forwards).
int32_t position = icu_break_iterator->next();
if (position == icu::BreakIterator::DONE) {
// 5. If done is true, return CreateIterResultObject(undefined, true).
return factory->NewJSIteratorResult(isolate->factory()->undefined_value(),
true);
}
// 8. Let segment be the substring of string from previousPosition to
// newPosition, inclusive of previousPosition and exclusive of newPosition.
Handle<String> segment;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, segment, segment_iterator->GetSegment(isolate, prev, position),
JSReceiver);
Handle<Object> break_type = segment_iterator->BreakType();
return CreateResultForNext(isolate, segment, break_type);
}
// ecma402 #sec-segment-iterator-prototype-following
Maybe<bool> JSSegmentIterator::Following(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator,
Handle<Object> from_obj) {
Factory* factory = isolate->factory();
icu::BreakIterator* icu_break_iterator =
segment_iterator->icu_break_iterator()->raw();
// 3. If from is not undefined,
if (!from_obj->IsUndefined()) {
// a. Let from be ? ToIndex(from).
uint32_t from;
if (!from_obj->ToArrayIndex(&from)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
factory->NewStringFromStaticChars("from"),
factory->NewStringFromStaticChars("following"),
from_obj),
Nothing<bool>());
}
// b. If from ≥ iterator.[[SegmentIteratorString]], throw a RangeError
// exception.
// c. Let iterator.[[SegmentIteratorPosition]] be from.
if (icu_break_iterator->following(from) == icu::BreakIterator::DONE) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
factory->NewStringFromStaticChars("from"),
factory->NewStringFromStaticChars("following"),
from_obj),
Nothing<bool>());
}
return Just(false);
}
// 4. return AdvanceSegmentIterator(iterator, forward).
// 4. .... or if direction is backwards and position is 0, return true.
// 4. If direction is forwards and position is the length of string ... return
// true.
return Just(icu_break_iterator->next() == icu::BreakIterator::DONE);
}
// ecma402 #sec-segment-iterator-prototype-preceding
Maybe<bool> JSSegmentIterator::Preceding(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator,
Handle<Object> from_obj) {
Factory* factory = isolate->factory();
icu::BreakIterator* icu_break_iterator =
segment_iterator->icu_break_iterator()->raw();
// 3. If from is not undefined,
if (!from_obj->IsUndefined()) {
// a. Let from be ? ToIndex(from).
uint32_t from;
if (!from_obj->ToArrayIndex(&from)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
factory->NewStringFromStaticChars("from"),
factory->NewStringFromStaticChars("following"),
from_obj),
Nothing<bool>());
}
// b. If from > iterator.[[SegmentIteratorString]] or from = 0, throw a
// RangeError exception.
// c. Let iterator.[[SegmentIteratorPosition]] be from.
uint32_t text_len =
static_cast<uint32_t>(icu_break_iterator->getText().getLength());
if (from > text_len ||
icu_break_iterator->preceding(from) == icu::BreakIterator::DONE) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
factory->NewStringFromStaticChars("from"),
factory->NewStringFromStaticChars("preceding"),
from_obj),
Nothing<bool>());
}
return Just(false);
}
// 4. return AdvanceSegmentIterator(iterator, backwards).
// 4. .... or if direction is backwards and position is 0, return true.
return Just(icu_break_iterator->previous() == icu::BreakIterator::DONE);
}
} // 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_SEGMENT_ITERATOR_H_
#define V8_OBJECTS_JS_SEGMENT_ITERATOR_H_
#include "src/heap/factory.h"
#include "src/isolate.h"
#include "src/objects.h"
#include "src/objects/js-segmenter.h"
#include "src/objects/managed.h"
#include "unicode/uversion.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
class BreakIterator;
class UnicodeString;
} // namespace U_ICU_NAMESPACE
namespace v8 {
namespace internal {
class JSSegmentIterator : public JSObject {
public:
// ecma402 #sec-CreateSegmentIterator
V8_WARN_UNUSED_RESULT static MaybeHandle<JSSegmentIterator> Create(
Isolate* isolate, icu::BreakIterator* icu_break_iterator,
JSSegmenter::Granularity granularity, Handle<String> string);
// ecma402 #sec-segment-iterator-prototype-next
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> Next(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator_holder);
// ecma402 #sec-segment-iterator-prototype-following
static Maybe<bool> Following(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator_holder,
Handle<Object> from);
// ecma402 #sec-segment-iterator-prototype-preceding
static Maybe<bool> Preceding(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator_holder,
Handle<Object> from);
// ecma402 #sec-segment-iterator-prototype-position
static Handle<Object> Position(
Isolate* isolate, Handle<JSSegmentIterator> segment_iterator_holder);
Handle<String> GranularityAsString() const;
// ecma402 #sec-segment-iterator-prototype-breakType
Handle<Object> BreakType() const;
V8_WARN_UNUSED_RESULT MaybeHandle<String> GetSegment(Isolate* isolate,
int32_t start,
int32_t end) const;
DECL_CAST(JSSegmentIterator)
// SegmentIterator accessors.
DECL_ACCESSORS(icu_break_iterator, Managed<icu::BreakIterator>)
DECL_ACCESSORS(unicode_string, Managed<icu::UnicodeString>)
DECL_PRINTER(JSSegmentIterator)
DECL_VERIFIER(JSSegmentIterator)
inline void set_granularity(JSSegmenter::Granularity granularity);
inline JSSegmenter::Granularity granularity() const;
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _) \
V(GranularityBits, JSSegmenter::Granularity, 3, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
STATIC_ASSERT(JSSegmenter::Granularity::GRAPHEME <= GranularityBits::kMax);
STATIC_ASSERT(JSSegmenter::Granularity::WORD <= GranularityBits::kMax);
STATIC_ASSERT(JSSegmenter::Granularity::SENTENCE <= GranularityBits::kMax);
STATIC_ASSERT(JSSegmenter::Granularity::LINE <= GranularityBits::kMax);
// [flags] Bit field containing various flags about the function.
DECL_INT_ACCESSORS(flags)
// Layout description.
#define SEGMENTER_FIELDS(V) \
/* Pointer fields. */ \
V(kICUBreakIteratorOffset, kPointerSize) \
V(kUnicodeStringOffset, kPointerSize) \
V(kFlagsOffset, kPointerSize) \
/* Total Size */ \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, SEGMENTER_FIELDS)
#undef SEGMENTER_FIELDS
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSSegmentIterator);
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_SEGMENT_ITERATOR_H_
......@@ -156,13 +156,21 @@ MaybeHandle<JSSegmenter> JSSegmenter::Initialize(
icu_break_iterator.reset(
icu::BreakIterator::createSentenceInstance(icu_locale, status));
break;
case Granularity::LINE:
icu_break_iterator.reset(
icu::BreakIterator::createLineInstance(icu_locale, status));
case Granularity::LINE: {
// 15. If granularity is "line",
// a. Set segmenter.[[SegmenterLineBreakStyle]] to r.[[lb]].
// TBW
const char* key = uloc_toLegacyKey("lb");
CHECK_NOT_NULL(key);
const char* value =
uloc_toLegacyType(key, segmenter_holder->LineBreakStyleAsCString());
CHECK_NOT_NULL(value);
UErrorCode status = U_ZERO_ERROR;
icu_locale.setKeywordValue(key, value, status);
CHECK(U_SUCCESS(status));
icu_break_iterator.reset(
icu::BreakIterator::createLineInstance(icu_locale, status));
break;
}
case Granularity::COUNT:
UNREACHABLE();
}
......@@ -194,6 +202,20 @@ Handle<JSObject> JSSegmenter::ResolvedOptions(
return result;
}
const char* JSSegmenter::LineBreakStyleAsCString() const {
switch (line_break_style()) {
case LineBreakStyle::STRICT:
return "strict";
case LineBreakStyle::NORMAL:
return "normal";
case LineBreakStyle::LOOSE:
return "loose";
case LineBreakStyle::COUNT:
case LineBreakStyle::NOTSET:
UNREACHABLE();
}
}
Handle<String> JSSegmenter::LineBreakStyleAsString() const {
switch (line_break_style()) {
case LineBreakStyle::STRICT:
......
......@@ -37,6 +37,7 @@ class JSSegmenter : public JSObject {
Isolate* isolate, Handle<JSSegmenter> segmenter_holder);
Handle<String> LineBreakStyleAsString() const;
const char* LineBreakStyleAsCString() const;
Handle<String> GranularityAsString() const;
DECL_CAST(JSSegmenter)
......
......@@ -29,36 +29,6 @@
[ALWAYS, {
# TODO(jochen): The following test is flaky.
'overrides/caching': [PASS, FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=6891
'segmenter/segment': [FAIL],
'segmenter/segment-grapheme': [FAIL],
'segmenter/segment-grapheme-following': [FAIL],
'segmenter/segment-grapheme-iterable': [FAIL],
'segmenter/segment-grapheme-next': [FAIL],
'segmenter/segment-grapheme-preceding': [FAIL],
'segmenter/segment-iterator': [FAIL],
'segmenter/segment-iterator-breakType': [FAIL],
'segmenter/segment-iterator-following': [FAIL],
'segmenter/segment-iterator-next': [FAIL],
'segmenter/segment-iterator-position': [FAIL],
'segmenter/segment-iterator-preceding': [FAIL],
'segmenter/segment-line': [FAIL],
'segmenter/segment-line-following': [FAIL],
'segmenter/segment-line-following-modes': [FAIL],
'segmenter/segment-line-iterable': [FAIL],
'segmenter/segment-line-next': [FAIL],
'segmenter/segment-line-preceding': [FAIL],
'segmenter/segment-sentence': [FAIL],
'segmenter/segment-sentence-following': [FAIL],
'segmenter/segment-sentence-iterable': [FAIL],
'segmenter/segment-sentence-next': [FAIL],
'segmenter/segment-sentence-preceding': [FAIL],
'segmenter/segment-word': [FAIL],
'segmenter/segment-word-following': [FAIL],
'segmenter/segment-word-iterable': [FAIL],
'segmenter/segment-word-next': [FAIL],
'segmenter/segment-word-preceding': [FAIL],
}], # ALWAYS
['variant == no_wasm_traps', {
......
......@@ -10,6 +10,11 @@ const iter = segmenter.segment(text);
assertEquals("function", typeof iter.following);
assertThrows(() => iter.following("ABC"), RangeError);
assertThrows(() => iter.following(null), RangeError);
assertThrows(() => iter.following(1.4), RangeError);
assertThrows(() => iter.following(-3), RangeError);
// 1.5.3.2 %SegmentIteratorPrototype%.following( [ from ] )
// 3.b If from >= iterator.[[SegmentIteratorString]], throw a RangeError exception.
assertDoesNotThrow(() => iter.following(text.length - 1));
......
// 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-intl-segmenter
let seg = new Intl.Segmenter();
let descriptor = Object.getOwnPropertyDescriptor(
Intl.Segmenter, "supportedLocalesOf");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
// ecma402 #sec-Intl.Segmenter.prototype
// Intl.Segmenter.prototype
// The value of Intl.Segmenter.prototype is %SegmenterPrototype%.
// This property has the attributes
// { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
descriptor = Object.getOwnPropertyDescriptor(Intl.Segmenter, "prototype");
assertFalse(descriptor.writable);
assertFalse(descriptor.enumerable);
assertFalse(descriptor.configurable);
for (let func of ["segment", "resolvedOptions"]) {
let descriptor = Object.getOwnPropertyDescriptor(
Intl.Segmenter.prototype, func);
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
}
let prototype = Object.getPrototypeOf(seg.segment('text'));
for (let func of ["next", "following", "preceding"]) {
let descriptor = Object.getOwnPropertyDescriptor(prototype, func);
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
}
......@@ -10,6 +10,11 @@ const iter = segmenter.segment(text);
assertEquals("function", typeof iter.preceding);
assertThrows(() => iter.preceding("ABC"), RangeError);
assertThrows(() => iter.preceding(null), RangeError);
assertThrows(() => iter.preceding(1.4), RangeError);
assertThrows(() => iter.preceding(-3), RangeError);
// 1.5.3.3 %SegmentIteratorPrototype%.preceding( [ from ] )
// 3.b If ... from = 0, throw a RangeError exception.
assertThrows(() => iter.preceding(0), RangeError);
......
......@@ -4,7 +4,6 @@
// Flags: --harmony-intl-segmenter
let descriptor;
const text = "Hello World, Test 123! Foo Bar. How are you?";
for (const granularity of ["grapheme", "word", "sentence", "line"]) {
const segmenter = new Intl.Segmenter("en", { granularity });
......
......@@ -5,3 +5,35 @@
// Flags: --harmony-intl-segmenter
assertEquals("function", typeof Intl.Segmenter.prototype.segment);
assertEquals(1, Intl.Segmenter.prototype.segment.length);
let seg = new Intl.Segmenter("en", {granularity: "word"})
let res;
// test with 0 args
assertDoesNotThrow(() => res = seg.segment())
// test with 1 arg
assertDoesNotThrow(() => res = seg.segment("hello"))
assertEquals("hello", res.next().value.segment);
// test with 2 args
assertDoesNotThrow(() => res = seg.segment("hello world"))
assertEquals("hello", res.next().value.segment);
// test with other types
assertDoesNotThrow(() => res = seg.segment(undefined))
assertEquals("undefined", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(null))
assertEquals("null", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(true))
assertEquals("true", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(false))
assertEquals("false", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(1234))
assertEquals("1234", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(3.1415926))
assertEquals("3.1415926", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment(["hello","world"]))
assertEquals("hello", res.next().value.segment);
assertDoesNotThrow(() => res = seg.segment({k: 'v'}))
assertEquals("[", res.next().value.segment);
assertThrows(() => res = seg.segment(Symbol()), TypeError)
......@@ -172,15 +172,16 @@ INSTANCE_TYPES = {
1093: "JS_INTL_NUMBER_FORMAT_TYPE",
1094: "JS_INTL_PLURAL_RULES_TYPE",
1095: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
1096: "JS_INTL_SEGMENTER_TYPE",
1097: "WASM_EXCEPTION_TYPE",
1098: "WASM_GLOBAL_TYPE",
1099: "WASM_INSTANCE_TYPE",
1100: "WASM_MEMORY_TYPE",
1101: "WASM_MODULE_TYPE",
1102: "WASM_TABLE_TYPE",
1103: "JS_BOUND_FUNCTION_TYPE",
1104: "JS_FUNCTION_TYPE",
1096: "JS_INTL_SEGMENT_ITERATOR_TYPE",
1097: "JS_INTL_SEGMENTER_TYPE",
1098: "WASM_EXCEPTION_TYPE",
1099: "WASM_GLOBAL_TYPE",
1100: "WASM_INSTANCE_TYPE",
1101: "WASM_MEMORY_TYPE",
1102: "WASM_MODULE_TYPE",
1103: "WASM_TABLE_TYPE",
1104: "JS_BOUND_FUNCTION_TYPE",
1105: "JS_FUNCTION_TYPE",
}
# List of known V8 maps.
......@@ -295,41 +296,41 @@ KNOWN_MAPS = {
("RO_SPACE", 0x02699): (171, "Tuple2Map"),
("RO_SPACE", 0x02739): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x02a79): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04f61): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x04fb1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05001): (155, "AccessorPairMap"),
("RO_SPACE", 0x05051): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x050a1): (157, "AllocationMementoMap"),
("RO_SPACE", 0x050f1): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05141): (159, "DebugInfoMap"),
("RO_SPACE", 0x05191): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x051e1): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05231): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x05281): (164, "ModuleMap"),
("RO_SPACE", 0x052d1): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05321): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x05371): (167, "PromiseReactionMap"),
("RO_SPACE", 0x053c1): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x05411): (169, "ScriptMap"),
("RO_SPACE", 0x05461): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x054b1): (172, "Tuple3Map"),
("RO_SPACE", 0x05501): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x05551): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x055a1): (176, "CallableTaskMap"),
("RO_SPACE", 0x055f1): (177, "CallbackTaskMap"),
("RO_SPACE", 0x05641): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x05691): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x056e1): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05731): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x05781): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x057d1): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x05821): (214, "LoadHandler1Map"),
("RO_SPACE", 0x05871): (214, "LoadHandler2Map"),
("RO_SPACE", 0x058c1): (214, "LoadHandler3Map"),
("RO_SPACE", 0x05911): (221, "StoreHandler0Map"),
("RO_SPACE", 0x05961): (221, "StoreHandler1Map"),
("RO_SPACE", 0x059b1): (221, "StoreHandler2Map"),
("RO_SPACE", 0x05a01): (221, "StoreHandler3Map"),
("RO_SPACE", 0x05031): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x05081): (154, "AccessorInfoMap"),
("RO_SPACE", 0x050d1): (155, "AccessorPairMap"),
("RO_SPACE", 0x05121): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x05171): (157, "AllocationMementoMap"),
("RO_SPACE", 0x051c1): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05211): (159, "DebugInfoMap"),
("RO_SPACE", 0x05261): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x052b1): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05301): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x05351): (164, "ModuleMap"),
("RO_SPACE", 0x053a1): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x053f1): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x05441): (167, "PromiseReactionMap"),
("RO_SPACE", 0x05491): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x054e1): (169, "ScriptMap"),
("RO_SPACE", 0x05531): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x05581): (172, "Tuple3Map"),
("RO_SPACE", 0x055d1): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x05621): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x05671): (176, "CallableTaskMap"),
("RO_SPACE", 0x056c1): (177, "CallbackTaskMap"),
("RO_SPACE", 0x05711): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x05761): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x057b1): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05801): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x05851): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x058a1): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x058f1): (214, "LoadHandler1Map"),
("RO_SPACE", 0x05941): (214, "LoadHandler2Map"),
("RO_SPACE", 0x05991): (214, "LoadHandler3Map"),
("RO_SPACE", 0x059e1): (221, "StoreHandler0Map"),
("RO_SPACE", 0x05a31): (221, "StoreHandler1Map"),
("RO_SPACE", 0x05a81): (221, "StoreHandler2Map"),
("RO_SPACE", 0x05ad1): (221, "StoreHandler3Map"),
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
("MAP_SPACE", 0x00189): (1073, "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