v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-break-iterator.cc
Go to the documentation of this file.
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_INTL_SUPPORT
6#error Internationalization is expected to be enabled.
7#endif // V8_INTL_SUPPORT
8
10
15#include "unicode/brkiter.h"
16
17namespace v8 {
18namespace internal {
19
21 Isolate* isolate, DirectHandle<Map> map, DirectHandle<Object> locales,
22 DirectHandle<Object> options_obj, const char* service) {
23 Factory* factory = isolate->factory();
24
25 // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
26 Maybe<std::vector<std::string>> maybe_requested_locales =
27 Intl::CanonicalizeLocaleList(isolate, locales);
28 MAYBE_RETURN(maybe_requested_locales, MaybeDirectHandle<JSV8BreakIterator>());
29 std::vector<std::string> requested_locales =
30 maybe_requested_locales.FromJust();
31
33 if (IsUndefined(*options_obj, isolate)) {
34 options = factory->NewJSObjectWithNullProto();
35 } else {
36 ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
37 Object::ToObject(isolate, options_obj, service));
38 }
39
40 // Extract locale string
41 Maybe<Intl::MatcherOption> maybe_locale_matcher =
42 Intl::GetLocaleMatcher(isolate, options, service);
44 Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
45
46 Maybe<Intl::ResolvedLocale> maybe_resolve_locale =
48 requested_locales, matcher, {});
49 if (maybe_resolve_locale.IsNothing()) {
50 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
51 }
52 Intl::ResolvedLocale r = maybe_resolve_locale.FromJust();
53
54 // Extract type from options
55 enum class Type { CHARACTER, WORD, SENTENCE, LINE };
57 isolate, options, "type", service,
58 {"word", "character", "sentence", "line"},
59 {Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD);
61 Type type_enum = maybe_type.FromJust();
62
63 icu::Locale icu_locale = r.icu_locale;
64 DCHECK(!icu_locale.isBogus());
65
66 // Construct break_iterator using icu_locale and type
67 UErrorCode status = U_ZERO_ERROR;
68 std::unique_ptr<icu::BreakIterator> break_iterator = nullptr;
69 switch (type_enum) {
70 case Type::CHARACTER:
71 break_iterator.reset(
72 icu::BreakIterator::createCharacterInstance(icu_locale, status));
73 break;
74 case Type::SENTENCE:
75 break_iterator.reset(
76 icu::BreakIterator::createSentenceInstance(icu_locale, status));
77 break;
78 case Type::LINE:
79 isolate->CountUsage(
81 break_iterator.reset(
82 icu::BreakIterator::createLineInstance(icu_locale, status));
83 break;
84 default:
85 isolate->CountUsage(
87 break_iterator.reset(
88 icu::BreakIterator::createWordInstance(icu_locale, status));
89 break;
90 }
91
92 // Error handling for break_iterator
93 if (U_FAILURE(status) || break_iterator == nullptr) {
94 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
95 }
97
98 // Construct managed objects from pointers
99 DirectHandle<Managed<icu::BreakIterator>> managed_break_iterator =
100 Managed<icu::BreakIterator>::From(isolate, 0, std::move(break_iterator));
101 DirectHandle<Managed<icu::UnicodeString>> managed_unicode_string =
102 Managed<icu::UnicodeString>::From(isolate, 0, nullptr);
103
104 DirectHandle<String> locale_str =
105 isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
106
107 // Now all properties are ready, so we can allocate the result object.
108 DirectHandle<JSV8BreakIterator> break_iterator_holder =
110 isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
112 break_iterator_holder->set_locale(*locale_str);
113 break_iterator_holder->set_break_iterator(*managed_break_iterator);
114 break_iterator_holder->set_unicode_string(*managed_unicode_string);
115
116 // Return break_iterator_holder
117 return break_iterator_holder;
118}
119
121 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator) {
122 Factory* factory = isolate->factory();
123 const auto as_string = [isolate](icu::BreakIterator* break_iterator) {
124 // Since the developer calling the Intl.v8BreakIterator already know the
125 // type, we usually do not need to know the type unless the
126 // resolvedOptions() is called, we use the following trick to figure out the
127 // type instead of storing it with the JSV8BreakIterator object to save
128 // memory. This routine is not fast but should be seldom used only.
129
130 // We need to clone a copy of break iterator because we need to setText to
131 // it.
132 std::unique_ptr<icu::BreakIterator> cloned_break_iterator(
133 break_iterator->clone());
134 // Use a magic string "He is." to call next().
135 // character type: will return 1 for "H"
136 // word type: will return 2 for "He"
137 // line type: will return 3 for "He "
138 // sentence type: will return 6 for "He is."
139 icu::UnicodeString data("He is.");
140 cloned_break_iterator->setText(data);
141 switch (cloned_break_iterator->next()) {
142 case 1: // After "H"
143 return isolate->factory()->character_string();
144 case 2: // After "He"
145 return isolate->factory()->word_string();
146 case 3: // After "He "
147 return isolate->factory()->line_string();
148 case 6: // After "He is."
149 return isolate->factory()->sentence_string();
150 default:
151 UNREACHABLE();
152 }
153 };
154
156 factory->NewJSObject(isolate->object_function());
157 DirectHandle<String> locale(break_iterator->locale(), isolate);
158
159 JSObject::AddProperty(isolate, result, factory->locale_string(), locale,
160 NONE);
161 JSObject::AddProperty(isolate, result, factory->type_string(),
162 as_string(break_iterator->break_iterator()->raw()),
163 NONE);
164 return result;
165}
166
168 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator_holder,
170 icu::BreakIterator* break_iterator =
171 break_iterator_holder->break_iterator()->raw();
172 DCHECK_NOT_NULL(break_iterator);
174 Intl::SetTextToBreakIterator(isolate, text, break_iterator);
175 break_iterator_holder->set_unicode_string(*unicode_string);
176}
177
179 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator) {
180 return isolate->factory()->NewNumberFromInt(
181 break_iterator->break_iterator()->raw()->current());
182}
183
185 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator) {
186 return isolate->factory()->NewNumberFromInt(
187 break_iterator->break_iterator()->raw()->first());
188}
189
191 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator) {
192 return isolate->factory()->NewNumberFromInt(
193 break_iterator->break_iterator()->raw()->next());
194}
195
197 Isolate* isolate, DirectHandle<JSV8BreakIterator> break_iterator) {
198 int32_t status = break_iterator->break_iterator()->raw()->getRuleStatus();
199 // Keep return values in sync with JavaScript BreakType enum.
200 if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
201 return ReadOnlyRoots(isolate).none_string();
202 }
203 if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
204 return ReadOnlyRoots(isolate).number_string();
205 }
206 if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
207 return ReadOnlyRoots(isolate).letter_string();
208 }
209 if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
210 return ReadOnlyRoots(isolate).kana_string();
211 }
212 if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
213 return ReadOnlyRoots(isolate).ideo_string();
214 }
215 return ReadOnlyRoots(isolate).unknown_string();
216}
217
218const std::set<std::string>& JSV8BreakIterator::GetAvailableLocales() {
220}
221
222} // namespace internal
223} // namespace v8
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
@ kBreakIteratorTypeLine
Definition v8-isolate.h:558
@ kBreakIteratorTypeWord
Definition v8-isolate.h:557
V8_INLINE T FromJust() const &
Definition v8-maybe.h:64
V8_INLINE bool IsNothing() const
Definition v8-maybe.h:35
Handle< JSObject > NewJSObjectWithNullProto()
Definition factory.cc:3004
Handle< JSObject > NewJSObject(DirectHandle< JSFunction > constructor, AllocationType allocation=AllocationType::kYoung, NewJSObjectType=NewJSObjectType::kNoAPIWrapper)
Definition factory.cc:2985
static const std::set< std::string > & GetAvailableLocales()
static Maybe< std::vector< std::string > > CanonicalizeLocaleList(Isolate *isolate, DirectHandle< Object > locales, bool only_return_one_result=false)
static Maybe< ResolvedLocale > ResolveLocale(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)
static V8_WARN_UNUSED_RESULT Maybe< MatcherOption > GetLocaleMatcher(Isolate *isolate, DirectHandle< JSReceiver > options, const char *method_name)
static DirectHandle< Managed< icu::UnicodeString > > SetTextToBreakIterator(Isolate *isolate, DirectHandle< String > text, icu::BreakIterator *break_iterator)
static V8_EXPORT_PRIVATE void AddProperty(Isolate *isolate, DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attributes)
static Tagged< String > BreakType(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator)
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator)
static DirectHandle< Object > Current(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSV8BreakIterator > New(Isolate *isolate, DirectHandle< Map > map, DirectHandle< Object > input_locales, DirectHandle< Object > input_options, const char *service)
static DirectHandle< Object > Next(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator)
static DirectHandle< Object > First(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator)
static void AdoptText(Isolate *isolate, DirectHandle< JSV8BreakIterator > break_iterator, DirectHandle< String > text)
static DirectHandle< Managed< CppType > > From(Isolate *isolate, size_t estimated_size, std::shared_ptr< CppType > shared_ptr, AllocationType allocation_type=AllocationType::kYoung)
Definition managed-inl.h:27
static V8_WARN_UNUSED_RESULT HandleType< JSReceiver >::MaybeType ToObject(Isolate *isolate, HandleType< T > object, const char *method_name=nullptr)
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define THROW_NEW_ERROR(isolate, call)
Definition isolate.h:307
#define MAYBE_RETURN(call, value)
Definition isolate.h:408
Isolate * isolate
DirectHandle< JSReceiver > options
ZoneVector< RpoNumber > & result
int r
Definition mul-fft.cc:298
Maybe< bool > GetStringOption(Isolate *isolate, DirectHandle< JSReceiver > options, const char *property, const std::vector< const char * > &values, const char *method_name, std::unique_ptr< char[]> *result)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK(condition)
Definition logging.h:482