Line data Source code
1 : // Copyright 2017 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 :
9 : #include <cmath>
10 : #include <list>
11 : #include <memory>
12 :
13 : #include "src/builtins/builtins-utils-inl.h"
14 : #include "src/builtins/builtins.h"
15 : #include "src/counters.h"
16 : #include "src/date.h"
17 : #include "src/elements.h"
18 : #include "src/objects-inl.h"
19 : #include "src/objects/intl-objects.h"
20 : #include "src/objects/js-array-inl.h"
21 : #include "src/objects/js-break-iterator-inl.h"
22 : #include "src/objects/js-collator-inl.h"
23 : #include "src/objects/js-date-time-format-inl.h"
24 : #include "src/objects/js-list-format-inl.h"
25 : #include "src/objects/js-locale-inl.h"
26 : #include "src/objects/js-number-format-inl.h"
27 : #include "src/objects/js-plural-rules-inl.h"
28 : #include "src/objects/js-relative-time-format-inl.h"
29 : #include "src/objects/js-segment-iterator-inl.h"
30 : #include "src/objects/js-segmenter-inl.h"
31 : #include "src/objects/smi.h"
32 : #include "src/property-descriptor.h"
33 :
34 : #include "unicode/brkiter.h"
35 :
36 : namespace v8 {
37 : namespace internal {
38 :
39 24350 : BUILTIN(StringPrototypeToUpperCaseIntl) {
40 : HandleScope scope(isolate);
41 10064 : TO_THIS_STRING(string, "String.prototype.toUpperCase");
42 4708 : string = String::Flatten(isolate, string);
43 9416 : RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string));
44 : }
45 :
46 11565 : BUILTIN(StringPrototypeNormalizeIntl) {
47 : HandleScope handle_scope(isolate);
48 2313 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringNormalize);
49 4626 : TO_THIS_STRING(string, "String.prototype.normalize");
50 :
51 2313 : Handle<Object> form_input = args.atOrUndefined(isolate, 1);
52 :
53 4725 : RETURN_RESULT_OR_FAILURE(isolate,
54 : Intl::Normalize(isolate, string, form_input));
55 : }
56 :
57 0 : BUILTIN(V8BreakIteratorSupportedLocalesOf) {
58 : HandleScope scope(isolate);
59 0 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
60 0 : Handle<Object> options = args.atOrUndefined(isolate, 2);
61 :
62 0 : RETURN_RESULT_OR_FAILURE(
63 : isolate, Intl::SupportedLocalesOf(
64 : isolate, "Intl.v8BreakIterator.supportedLocalesOf",
65 : JSV8BreakIterator::GetAvailableLocales(), locales, options));
66 : }
67 :
68 630 : BUILTIN(NumberFormatSupportedLocalesOf) {
69 : HandleScope scope(isolate);
70 126 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
71 126 : Handle<Object> options = args.atOrUndefined(isolate, 2);
72 :
73 261 : RETURN_RESULT_OR_FAILURE(
74 : isolate, Intl::SupportedLocalesOf(
75 : isolate, "Intl.NumberFormat.supportedLocalesOf",
76 : JSNumberFormat::GetAvailableLocales(), locales, options));
77 : }
78 :
79 5670 : BUILTIN(NumberFormatPrototypeFormatToParts) {
80 : const char* const method = "Intl.NumberFormat.prototype.formatToParts";
81 : HandleScope handle_scope(isolate);
82 1134 : CHECK_RECEIVER(JSNumberFormat, number_format, method);
83 :
84 : Handle<Object> x;
85 1134 : if (args.length() >= 2) {
86 1134 : if (FLAG_harmony_intl_bigint) {
87 1728 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
88 : isolate, x, Object::ToNumeric(isolate, args.at(1)));
89 : } else {
90 540 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
91 : Object::ToNumber(isolate, args.at(1)));
92 : }
93 : } else {
94 0 : x = isolate->factory()->nan_value();
95 : }
96 :
97 2268 : RETURN_RESULT_OR_FAILURE(
98 : isolate, JSNumberFormat::FormatToParts(isolate, number_format, x));
99 : }
100 :
101 12645 : BUILTIN(DateTimeFormatPrototypeResolvedOptions) {
102 : const char* const method = "Intl.DateTimeFormat.prototype.resolvedOptions";
103 : HandleScope scope(isolate);
104 2529 : CHECK_RECEIVER(JSReceiver, format_holder, method);
105 :
106 : // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
107 : Handle<JSDateTimeFormat> date_time_format;
108 5058 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
109 : isolate, date_time_format,
110 : JSDateTimeFormat::UnwrapDateTimeFormat(isolate, format_holder));
111 :
112 5058 : RETURN_RESULT_OR_FAILURE(
113 : isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_time_format));
114 : }
115 :
116 630 : BUILTIN(DateTimeFormatSupportedLocalesOf) {
117 : HandleScope scope(isolate);
118 126 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
119 126 : Handle<Object> options = args.atOrUndefined(isolate, 2);
120 :
121 261 : RETURN_RESULT_OR_FAILURE(
122 : isolate, Intl::SupportedLocalesOf(
123 : isolate, "Intl.DateTimeFormat.supportedLocalesOf",
124 : JSDateTimeFormat::GetAvailableLocales(), locales, options));
125 : }
126 :
127 990 : BUILTIN(DateTimeFormatPrototypeFormatToParts) {
128 : const char* const method = "Intl.DateTimeFormat.prototype.formatToParts";
129 : HandleScope handle_scope(isolate);
130 225 : CHECK_RECEIVER(JSObject, date_format_holder, method);
131 : Factory* factory = isolate->factory();
132 :
133 189 : if (!date_format_holder->IsJSDateTimeFormat()) {
134 27 : THROW_NEW_ERROR_RETURN_FAILURE(
135 : isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
136 : factory->NewStringFromAsciiChecked(method),
137 : date_format_holder));
138 : }
139 : Handle<JSDateTimeFormat> dtf =
140 180 : Handle<JSDateTimeFormat>::cast(date_format_holder);
141 :
142 : Handle<Object> x = args.atOrUndefined(isolate, 1);
143 180 : if (x->IsUndefined(isolate)) {
144 18 : x = factory->NewNumber(JSDate::CurrentTimeValue(isolate));
145 : } else {
146 324 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
147 : Object::ToNumber(isolate, args.at(1)));
148 : }
149 :
150 180 : double date_value = DateCache::TimeClip(x->Number());
151 180 : if (std::isnan(date_value)) {
152 54 : THROW_NEW_ERROR_RETURN_FAILURE(
153 : isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
154 : }
155 :
156 306 : RETURN_RESULT_OR_FAILURE(
157 : isolate, JSDateTimeFormat::FormatToParts(isolate, dtf, date_value));
158 : }
159 :
160 : namespace {
161 1140 : Handle<JSFunction> CreateBoundFunction(Isolate* isolate,
162 : Handle<JSObject> object,
163 : Builtins::Name builtin_id, int len) {
164 2280 : Handle<NativeContext> native_context(isolate->context()->native_context(),
165 1140 : isolate);
166 : Handle<Context> context = isolate->factory()->NewBuiltinContext(
167 : native_context,
168 1140 : static_cast<int>(Intl::BoundFunctionContextSlot::kLength));
169 :
170 : context->set(static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction),
171 : *object);
172 :
173 : Handle<SharedFunctionInfo> info =
174 : isolate->factory()->NewSharedFunctionInfoForBuiltin(
175 1140 : isolate->factory()->empty_string(), builtin_id, kNormalFunction);
176 : info->set_internal_formal_parameter_count(len);
177 : info->set_length(len);
178 :
179 1140 : Handle<Map> map = isolate->strict_function_without_prototype_map();
180 :
181 : Handle<JSFunction> new_bound_function =
182 1140 : isolate->factory()->NewFunctionFromSharedFunctionInfo(map, info, context);
183 1140 : return new_bound_function;
184 : }
185 :
186 : /**
187 : * Common code shared between DateTimeFormatConstructor and
188 : * NumberFormatConstrutor
189 : */
190 : template <class T>
191 5076 : Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
192 : v8::Isolate::UseCounterFeature feature,
193 : Handle<Object> constructor, const char* method) {
194 5076 : isolate->CountUsage(feature);
195 : Handle<JSReceiver> new_target;
196 : // 1. If NewTarget is undefined, let newTarget be the active
197 : // function object, else let newTarget be NewTarget.
198 5076 : if (args.new_target()->IsUndefined(isolate)) {
199 954 : new_target = args.target();
200 : } else {
201 4122 : new_target = Handle<JSReceiver>::cast(args.new_target());
202 : }
203 :
204 : // [[Construct]]
205 5076 : Handle<JSFunction> target = args.target();
206 :
207 5076 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
208 5076 : Handle<Object> options = args.atOrUndefined(isolate, 2);
209 :
210 : // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget,
211 : // "%<T>Prototype%", ...).
212 :
213 : Handle<JSObject> obj;
214 10152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
215 : isolate, obj,
216 : JSObject::New(target, new_target, Handle<AllocationSite>::null()));
217 : Handle<T> format = Handle<T>::cast(obj);
218 :
219 : // 3. Perform ? Initialize<T>(Format, locales, options).
220 10710 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
221 : isolate, format, T::Initialize(isolate, format, locales, options));
222 : // 4. Let this be the this value.
223 : Handle<Object> receiver = args.receiver();
224 :
225 : // 5. If NewTarget is undefined and ? InstanceofOperator(this, %<T>%)
226 : // is true, then
227 : //
228 : // Look up the intrinsic value that has been stored on the context.
229 : // Call the instanceof function
230 : Handle<Object> is_instance_of_obj;
231 9036 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
232 : isolate, is_instance_of_obj,
233 : Object::InstanceOf(isolate, receiver, constructor));
234 :
235 : // Get the boolean value of the result
236 4518 : bool is_instance_of = is_instance_of_obj->BooleanValue(isolate);
237 :
238 4518 : if (args.new_target()->IsUndefined(isolate) && is_instance_of) {
239 72 : if (!receiver->IsJSReceiver()) {
240 54 : THROW_NEW_ERROR_RETURN_FAILURE(
241 : isolate,
242 : NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
243 : isolate->factory()->NewStringFromAsciiChecked(method),
244 : receiver));
245 : }
246 54 : Handle<JSReceiver> rec = Handle<JSReceiver>::cast(receiver);
247 : // a. Perform ? DefinePropertyOrThrow(this,
248 : // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format,
249 : // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
250 : PropertyDescriptor desc;
251 : desc.set_value(format);
252 : desc.set_writable(false);
253 : desc.set_enumerable(false);
254 : desc.set_configurable(false);
255 54 : Maybe<bool> success = JSReceiver::DefineOwnProperty(
256 : isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc,
257 54 : Just(kThrowOnError));
258 72 : MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
259 36 : CHECK(success.FromJust());
260 : // b. b. Return this.
261 : return *receiver;
262 : }
263 : // 6. Return format.
264 4446 : return *format;
265 : }
266 :
267 : /**
268 : * Common code shared by ListFormat, RelativeTimeFormat, PluralRules, and
269 : * Segmenter
270 : */
271 : template <class T>
272 2498 : Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
273 : v8::Isolate::UseCounterFeature feature,
274 : const char* method) {
275 2498 : isolate->CountUsage(feature);
276 :
277 : // 1. If NewTarget is undefined, throw a TypeError exception.
278 2498 : if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
279 81 : THROW_NEW_ERROR_RETURN_FAILURE(
280 : isolate,
281 : NewTypeError(MessageTemplate::kConstructorNotFunction,
282 : isolate->factory()->NewStringFromAsciiChecked(method)));
283 : }
284 : // [[Construct]]
285 2471 : Handle<JSFunction> target = args.target();
286 2471 : Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
287 :
288 : Handle<JSObject> obj;
289 : // 2. Let result be OrdinaryCreateFromConstructor(NewTarget,
290 : // "%<T>Prototype%").
291 4942 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
292 : isolate, obj,
293 : JSObject::New(target, new_target, Handle<AllocationSite>::null()));
294 : Handle<T> result = Handle<T>::cast(obj);
295 : result->set_flags(0);
296 :
297 2471 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
298 2471 : Handle<Object> options = args.atOrUndefined(isolate, 2);
299 :
300 : // 3. Return Initialize<T>(t, locales, options).
301 5172 : RETURN_RESULT_OR_FAILURE(isolate,
302 : T::Initialize(isolate, result, locales, options));
303 : }
304 :
305 : /**
306 : * Common code shared by Collator and V8BreakIterator
307 : */
308 : template <class T>
309 852 : Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) {
310 : Handle<JSReceiver> new_target;
311 :
312 852 : if (args.new_target()->IsUndefined(isolate)) {
313 118 : new_target = args.target();
314 : } else {
315 734 : new_target = Handle<JSReceiver>::cast(args.new_target());
316 : }
317 :
318 : // [[Construct]]
319 852 : Handle<JSFunction> target = args.target();
320 :
321 852 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
322 852 : Handle<Object> options = args.atOrUndefined(isolate, 2);
323 :
324 : Handle<JSObject> obj;
325 1704 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
326 : isolate, obj,
327 : JSObject::New(target, new_target, Handle<AllocationSite>::null()));
328 852 : Handle<T> result = Handle<T>::cast(obj);
329 :
330 1713 : RETURN_RESULT_OR_FAILURE(isolate,
331 : T::Initialize(isolate, result, locales, options));
332 : }
333 : } // namespace
334 :
335 7425 : BUILTIN(NumberFormatConstructor) {
336 : HandleScope scope(isolate);
337 :
338 : return LegacyFormatConstructor<JSNumberFormat>(
339 : args, isolate, v8::Isolate::UseCounterFeature::kNumberFormat,
340 4455 : isolate->intl_number_format_function(), "Intl.NumberFormat");
341 : }
342 :
343 3735 : BUILTIN(NumberFormatPrototypeResolvedOptions) {
344 : HandleScope scope(isolate);
345 : const char* const method = "Intl.NumberFormat.prototype.resolvedOptions";
346 :
347 : // 1. Let nf be the this value.
348 : // 2. If Type(nf) is not Object, throw a TypeError exception.
349 747 : CHECK_RECEIVER(JSReceiver, number_format_holder, method);
350 :
351 : // 3. Let nf be ? UnwrapNumberFormat(nf)
352 : Handle<JSNumberFormat> number_format;
353 1494 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
354 : isolate, number_format,
355 : JSNumberFormat::UnwrapNumberFormat(isolate, number_format_holder));
356 :
357 1494 : return *JSNumberFormat::ResolvedOptions(isolate, number_format);
358 : }
359 :
360 10575 : BUILTIN(NumberFormatPrototypeFormatNumber) {
361 : const char* const method = "get Intl.NumberFormat.prototype.format";
362 : HandleScope scope(isolate);
363 :
364 : // 1. Let nf be the this value.
365 : // 2. If Type(nf) is not Object, throw a TypeError exception.
366 2115 : CHECK_RECEIVER(JSReceiver, receiver, method);
367 :
368 : // 3. Let nf be ? UnwrapNumberFormat(nf).
369 : Handle<JSNumberFormat> number_format;
370 4275 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
371 : isolate, number_format,
372 : JSNumberFormat::UnwrapNumberFormat(isolate, receiver));
373 :
374 : Handle<Object> bound_format(number_format->bound_format(), isolate);
375 :
376 : // 4. If nf.[[BoundFormat]] is undefined, then
377 2070 : if (!bound_format->IsUndefined(isolate)) {
378 : DCHECK(bound_format->IsJSFunction());
379 : // 5. Return nf.[[BoundFormat]].
380 : return *bound_format;
381 : }
382 :
383 : Handle<JSFunction> new_bound_format_function = CreateBoundFunction(
384 405 : isolate, number_format, Builtins::kNumberFormatInternalFormatNumber, 1);
385 :
386 : // 4. c. Set nf.[[BoundFormat]] to F.
387 810 : number_format->set_bound_format(*new_bound_format_function);
388 :
389 : // 5. Return nf.[[BoundFormat]].
390 405 : return *new_bound_format_function;
391 : }
392 :
393 10260 : BUILTIN(NumberFormatInternalFormatNumber) {
394 : HandleScope scope(isolate);
395 :
396 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
397 :
398 : // 1. Let nf be F.[[NumberFormat]].
399 : // 2. Assert: Type(nf) is Object and nf has an
400 : // [[InitializedNumberFormat]] internal slot.
401 : Handle<JSNumberFormat> number_format = Handle<JSNumberFormat>(
402 : JSNumberFormat::cast(context->get(
403 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
404 : isolate);
405 :
406 : // 3. If value is not provided, let value be undefined.
407 2052 : Handle<Object> value = args.atOrUndefined(isolate, 1);
408 :
409 : // 4. Let x be ? ToNumeric(value).
410 : Handle<Object> numeric_obj;
411 2052 : if (FLAG_harmony_intl_bigint) {
412 2700 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj,
413 : Object::ToNumeric(isolate, value));
414 : } else {
415 1404 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj,
416 : Object::ToNumber(isolate, value));
417 : }
418 :
419 : icu::NumberFormat* icu_number_format =
420 4104 : number_format->icu_number_format()->raw();
421 2052 : CHECK_NOT_NULL(icu_number_format);
422 :
423 4104 : RETURN_RESULT_OR_FAILURE(
424 : isolate,
425 : JSNumberFormat::FormatNumeric(isolate, *icu_number_format, numeric_obj));
426 : }
427 :
428 17955 : BUILTIN(DateTimeFormatConstructor) {
429 : HandleScope scope(isolate);
430 :
431 : return LegacyFormatConstructor<JSDateTimeFormat>(
432 : args, isolate, v8::Isolate::UseCounterFeature::kDateTimeFormat,
433 10773 : isolate->intl_date_time_format_function(), "Intl.DateTimeFormat");
434 : }
435 :
436 3195 : BUILTIN(DateTimeFormatPrototypeFormat) {
437 : const char* const method = "get Intl.DateTimeFormat.prototype.format";
438 : HandleScope scope(isolate);
439 :
440 : // 1. Let dtf be this value.
441 : // 2. If Type(dtf) is not Object, throw a TypeError exception.
442 639 : CHECK_RECEIVER(JSReceiver, receiver, method);
443 :
444 : // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
445 : Handle<JSDateTimeFormat> format;
446 1323 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
447 : isolate, format,
448 : JSDateTimeFormat::UnwrapDateTimeFormat(isolate, receiver));
449 :
450 : Handle<Object> bound_format = Handle<Object>(format->bound_format(), isolate);
451 :
452 : // 4. If dtf.[[BoundFormat]] is undefined, then
453 594 : if (!bound_format->IsUndefined(isolate)) {
454 : DCHECK(bound_format->IsJSFunction());
455 : // 5. Return dtf.[[BoundFormat]].
456 : return *bound_format;
457 : }
458 :
459 : Handle<JSFunction> new_bound_format_function = CreateBoundFunction(
460 423 : isolate, format, Builtins::kDateTimeFormatInternalFormat, 1);
461 :
462 : // 4.c. Set dtf.[[BoundFormat]] to F.
463 846 : format->set_bound_format(*new_bound_format_function);
464 :
465 : // 5. Return dtf.[[BoundFormat]].
466 423 : return *new_bound_format_function;
467 : }
468 :
469 2880 : BUILTIN(DateTimeFormatInternalFormat) {
470 : HandleScope scope(isolate);
471 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
472 :
473 : // 1. Let dtf be F.[[DateTimeFormat]].
474 : // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]]
475 : // internal slot.
476 : Handle<JSDateTimeFormat> date_format_holder = Handle<JSDateTimeFormat>(
477 : JSDateTimeFormat::cast(context->get(
478 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
479 : isolate);
480 :
481 576 : Handle<Object> date = args.atOrUndefined(isolate, 1);
482 :
483 1206 : RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::DateTimeFormat(
484 : isolate, date_format_holder, date));
485 : }
486 :
487 1710 : BUILTIN(IntlGetCanonicalLocales) {
488 : HandleScope scope(isolate);
489 342 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
490 :
491 693 : RETURN_RESULT_OR_FAILURE(isolate,
492 : Intl::GetCanonicalLocales(isolate, locales));
493 : }
494 :
495 5110 : BUILTIN(ListFormatConstructor) {
496 : HandleScope scope(isolate);
497 :
498 : return DisallowCallConstructor<JSListFormat>(
499 : args, isolate, v8::Isolate::UseCounterFeature::kListFormat,
500 2044 : "Intl.ListFormat");
501 : }
502 :
503 1575 : BUILTIN(ListFormatPrototypeResolvedOptions) {
504 : HandleScope scope(isolate);
505 315 : CHECK_RECEIVER(JSListFormat, format_holder,
506 : "Intl.ListFormat.prototype.resolvedOptions");
507 630 : return *JSListFormat::ResolvedOptions(isolate, format_holder);
508 : }
509 :
510 180 : BUILTIN(ListFormatSupportedLocalesOf) {
511 : HandleScope scope(isolate);
512 36 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
513 36 : Handle<Object> options = args.atOrUndefined(isolate, 2);
514 :
515 72 : RETURN_RESULT_OR_FAILURE(
516 : isolate, Intl::SupportedLocalesOf(
517 : isolate, "Intl.ListFormat.supportedLocalesOf",
518 : JSListFormat::GetAvailableLocales(), locales, options));
519 : }
520 :
521 : namespace {
522 :
523 52983 : MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
524 : Handle<JSFunction> constructor,
525 : Handle<JSReceiver> new_target,
526 : Handle<Object> tag, Handle<Object> options) {
527 : Handle<JSObject> locale;
528 : // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget,
529 : // %LocalePrototype%, internalSlotsList).
530 105966 : ASSIGN_RETURN_ON_EXCEPTION(
531 : isolate, locale,
532 : JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
533 : JSLocale);
534 :
535 : // 7. If Type(tag) is not String or Object, throw a TypeError exception.
536 53037 : if (!tag->IsString() && !tag->IsJSReceiver()) {
537 108 : THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty),
538 : JSLocale);
539 : }
540 :
541 : Handle<String> locale_string;
542 : // 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal
543 : // slot, then
544 52929 : if (tag->IsJSLocale()) {
545 : // a. Let tag be tag.[[Locale]].
546 0 : locale_string = JSLocale::ToString(isolate, Handle<JSLocale>::cast(tag));
547 : } else { // 9. Else,
548 : // a. Let tag be ? ToString(tag).
549 105858 : ASSIGN_RETURN_ON_EXCEPTION(isolate, locale_string,
550 : Object::ToString(isolate, tag), JSLocale);
551 : }
552 :
553 : Handle<JSReceiver> options_object;
554 : // 10. If options is undefined, then
555 52929 : if (options->IsUndefined(isolate)) {
556 : // a. Let options be ! ObjectCreate(null).
557 6957 : options_object = isolate->factory()->NewJSObjectWithNullProto();
558 : } else { // 11. Else
559 : // a. Let options be ? ToObject(options).
560 91944 : ASSIGN_RETURN_ON_EXCEPTION(isolate, options_object,
561 : Object::ToObject(isolate, options), JSLocale);
562 : }
563 :
564 : return JSLocale::Initialize(isolate, Handle<JSLocale>::cast(locale),
565 52929 : locale_string, options_object);
566 : }
567 :
568 : } // namespace
569 :
570 : // Intl.Locale implementation
571 35775 : BUILTIN(LocaleConstructor) {
572 : HandleScope scope(isolate);
573 :
574 7155 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
575 :
576 7155 : if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
577 27 : THROW_NEW_ERROR_RETURN_FAILURE(
578 : isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
579 : isolate->factory()->NewStringFromAsciiChecked(
580 : "Intl.Locale")));
581 : }
582 : // [[Construct]]
583 7146 : Handle<JSFunction> target = args.target();
584 7146 : Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
585 :
586 7146 : Handle<Object> tag = args.atOrUndefined(isolate, 1);
587 7146 : Handle<Object> options = args.atOrUndefined(isolate, 2);
588 :
589 14454 : RETURN_RESULT_OR_FAILURE(
590 : isolate, CreateLocale(isolate, target, new_target, tag, options));
591 : }
592 :
593 114525 : BUILTIN(LocalePrototypeMaximize) {
594 : HandleScope scope(isolate);
595 22905 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize");
596 : Handle<JSFunction> constructor(
597 68715 : isolate->native_context()->intl_locale_function(), isolate);
598 22905 : Handle<String> locale_str = JSLocale::ToString(isolate, locale);
599 91620 : RETURN_RESULT_OR_FAILURE(
600 : isolate, CreateLocale(isolate, constructor, constructor,
601 : JSLocale::Maximize(isolate, *locale_str),
602 : isolate->factory()->NewJSObjectWithNullProto()));
603 : }
604 :
605 114660 : BUILTIN(LocalePrototypeMinimize) {
606 : HandleScope scope(isolate);
607 22932 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize");
608 : Handle<JSFunction> constructor(
609 68796 : isolate->native_context()->intl_locale_function(), isolate);
610 22932 : Handle<String> locale_str = JSLocale::ToString(isolate, locale);
611 91728 : RETURN_RESULT_OR_FAILURE(
612 : isolate, CreateLocale(isolate, constructor, constructor,
613 : JSLocale::Minimize(isolate, *locale_str),
614 : isolate->factory()->NewJSObjectWithNullProto()));
615 : }
616 :
617 180 : BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
618 : HandleScope scope(isolate);
619 36 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
620 36 : Handle<Object> options = args.atOrUndefined(isolate, 2);
621 :
622 72 : RETURN_RESULT_OR_FAILURE(
623 : isolate,
624 : Intl::SupportedLocalesOf(
625 : isolate, "Intl.RelativeTimeFormat.supportedLocalesOf",
626 : JSRelativeTimeFormat::GetAvailableLocales(), locales, options));
627 : }
628 :
629 28980 : BUILTIN(RelativeTimeFormatPrototypeFormat) {
630 : HandleScope scope(isolate);
631 : // 1. Let relativeTimeFormat be the this value.
632 : // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
633 : // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
634 : // true, throw a TypeError exception.
635 5796 : CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
636 : "Intl.RelativeTimeFormat.prototype.format");
637 5796 : Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
638 5796 : Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
639 :
640 13572 : RETURN_RESULT_OR_FAILURE(
641 : isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj,
642 : format_holder, "format", false));
643 : }
644 :
645 3285 : BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
646 : HandleScope scope(isolate);
647 : // 1. Let relativeTimeFormat be the this value.
648 : // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
649 : // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
650 : // true, throw a TypeError exception.
651 657 : CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
652 : "Intl.RelativeTimeFormat.prototype.formatToParts");
653 657 : Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
654 657 : Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
655 1548 : RETURN_RESULT_OR_FAILURE(isolate, JSRelativeTimeFormat::Format(
656 : isolate, value_obj, unit_obj,
657 : format_holder, "formatToParts", true));
658 : }
659 :
660 : // Locale getters.
661 180 : BUILTIN(LocalePrototypeLanguage) {
662 : HandleScope scope(isolate);
663 : // CHECK_RECEIVER will case locale_holder to JSLocale.
664 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.language");
665 :
666 36 : return *JSLocale::Language(isolate, locale);
667 : }
668 :
669 225 : BUILTIN(LocalePrototypeScript) {
670 : HandleScope scope(isolate);
671 99 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.script");
672 :
673 54 : return *JSLocale::Script(isolate, locale);
674 : }
675 :
676 180 : BUILTIN(LocalePrototypeRegion) {
677 : HandleScope scope(isolate);
678 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.region");
679 :
680 36 : return *JSLocale::Region(isolate, locale);
681 : }
682 :
683 180 : BUILTIN(LocalePrototypeBaseName) {
684 : HandleScope scope(isolate);
685 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.baseName");
686 :
687 36 : return *JSLocale::BaseName(isolate, locale);
688 : }
689 :
690 180 : BUILTIN(LocalePrototypeCalendar) {
691 : HandleScope scope(isolate);
692 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendar");
693 :
694 36 : return *JSLocale::Calendar(isolate, locale);
695 : }
696 :
697 180 : BUILTIN(LocalePrototypeCaseFirst) {
698 : HandleScope scope(isolate);
699 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.caseFirst");
700 :
701 36 : return *JSLocale::CaseFirst(isolate, locale);
702 : }
703 :
704 180 : BUILTIN(LocalePrototypeCollation) {
705 : HandleScope scope(isolate);
706 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collation");
707 :
708 36 : return *JSLocale::Collation(isolate, locale);
709 : }
710 :
711 180 : BUILTIN(LocalePrototypeHourCycle) {
712 : HandleScope scope(isolate);
713 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycle");
714 :
715 36 : return *JSLocale::HourCycle(isolate, locale);
716 : }
717 :
718 180 : BUILTIN(LocalePrototypeNumeric) {
719 : HandleScope scope(isolate);
720 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numeric");
721 :
722 36 : return *JSLocale::Numeric(isolate, locale);
723 : }
724 :
725 180 : BUILTIN(LocalePrototypeNumberingSystem) {
726 : HandleScope scope(isolate);
727 90 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystem");
728 :
729 36 : return *JSLocale::NumberingSystem(isolate, locale);
730 : }
731 :
732 370260 : BUILTIN(LocalePrototypeToString) {
733 : HandleScope scope(isolate);
734 74052 : CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.toString");
735 :
736 148104 : return *JSLocale::ToString(isolate, locale);
737 : }
738 :
739 3960 : BUILTIN(RelativeTimeFormatConstructor) {
740 : HandleScope scope(isolate);
741 :
742 : return DisallowCallConstructor<JSRelativeTimeFormat>(
743 : args, isolate, v8::Isolate::UseCounterFeature::kRelativeTimeFormat,
744 1584 : "Intl.RelativeTimeFormat");
745 : }
746 :
747 2565 : BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) {
748 : HandleScope scope(isolate);
749 567 : CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
750 : "Intl.RelativeTimeFormat.prototype.resolvedOptions");
751 990 : return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder);
752 : }
753 :
754 2790 : BUILTIN(StringPrototypeToLocaleLowerCase) {
755 : HandleScope scope(isolate);
756 :
757 558 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleLowerCase);
758 :
759 1440 : TO_THIS_STRING(string, "String.prototype.toLocaleLowerCase");
760 :
761 810 : RETURN_RESULT_OR_FAILURE(
762 : isolate, Intl::StringLocaleConvertCase(isolate, string, false,
763 : args.atOrUndefined(isolate, 1)));
764 : }
765 :
766 2835 : BUILTIN(StringPrototypeToLocaleUpperCase) {
767 : HandleScope scope(isolate);
768 :
769 567 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleUpperCase);
770 :
771 1458 : TO_THIS_STRING(string, "String.prototype.toLocaleUpperCase");
772 :
773 828 : RETURN_RESULT_OR_FAILURE(
774 : isolate, Intl::StringLocaleConvertCase(isolate, string, true,
775 : args.atOrUndefined(isolate, 1)));
776 : }
777 :
778 225 : BUILTIN(PluralRulesConstructor) {
779 : HandleScope scope(isolate);
780 :
781 : return DisallowCallConstructor<JSPluralRules>(
782 : args, isolate, v8::Isolate::UseCounterFeature::kPluralRules,
783 90 : "Intl.PluralRules");
784 : }
785 :
786 0 : BUILTIN(PluralRulesPrototypeResolvedOptions) {
787 : HandleScope scope(isolate);
788 0 : CHECK_RECEIVER(JSPluralRules, plural_rules_holder,
789 : "Intl.PluralRules.prototype.resolvedOptions");
790 0 : return *JSPluralRules::ResolvedOptions(isolate, plural_rules_holder);
791 : }
792 :
793 1890 : BUILTIN(PluralRulesPrototypeSelect) {
794 : HandleScope scope(isolate);
795 :
796 : // 1. Let pr be the this value.
797 : // 2. If Type(pr) is not Object, throw a TypeError exception.
798 : // 3. If pr does not have an [[InitializedPluralRules]] internal slot, throw a
799 : // TypeError exception.
800 378 : CHECK_RECEIVER(JSPluralRules, plural_rules,
801 : "Intl.PluralRules.prototype.select");
802 :
803 : // 4. Let n be ? ToNumber(value).
804 : Handle<Object> number = args.atOrUndefined(isolate, 1);
805 756 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number,
806 : Object::ToNumber(isolate, number));
807 : double number_double = number->Number();
808 :
809 : // 5. Return ? ResolvePlural(pr, n).
810 756 : RETURN_RESULT_OR_FAILURE(isolate, JSPluralRules::ResolvePlural(
811 : isolate, plural_rules, number_double));
812 : }
813 :
814 630 : BUILTIN(PluralRulesSupportedLocalesOf) {
815 : HandleScope scope(isolate);
816 126 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
817 126 : Handle<Object> options = args.atOrUndefined(isolate, 2);
818 :
819 261 : RETURN_RESULT_OR_FAILURE(
820 : isolate, Intl::SupportedLocalesOf(
821 : isolate, "Intl.PluralRules.supportedLocalesOf",
822 : JSPluralRules::GetAvailableLocales(), locales, options));
823 : }
824 :
825 3110 : BUILTIN(CollatorConstructor) {
826 : HandleScope scope(isolate);
827 :
828 622 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator);
829 :
830 1244 : return CallOrConstructConstructor<JSCollator>(args, isolate);
831 : }
832 :
833 2255 : BUILTIN(CollatorPrototypeResolvedOptions) {
834 : HandleScope scope(isolate);
835 451 : CHECK_RECEIVER(JSCollator, collator_holder,
836 : "Intl.Collator.prototype.resolvedOptions");
837 902 : return *JSCollator::ResolvedOptions(isolate, collator_holder);
838 : }
839 :
840 855 : BUILTIN(CollatorSupportedLocalesOf) {
841 : HandleScope scope(isolate);
842 171 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
843 171 : Handle<Object> options = args.atOrUndefined(isolate, 2);
844 :
845 387 : RETURN_RESULT_OR_FAILURE(
846 : isolate, Intl::SupportedLocalesOf(
847 : isolate, "Intl.Collator.supportedLocalesOf",
848 : JSCollator::GetAvailableLocales(), locales, options));
849 : }
850 :
851 26125 : BUILTIN(CollatorPrototypeCompare) {
852 : const char* const method = "get Intl.Collator.prototype.compare";
853 : HandleScope scope(isolate);
854 :
855 : // 1. Let collator be this value.
856 : // 2. If Type(collator) is not Object, throw a TypeError exception.
857 : // 3. If collator does not have an [[InitializedCollator]] internal slot,
858 : // throw a TypeError exception.
859 5414 : CHECK_RECEIVER(JSCollator, collator, method);
860 :
861 : // 4. If collator.[[BoundCompare]] is undefined, then
862 : Handle<Object> bound_compare(collator->bound_compare(), isolate);
863 5162 : if (!bound_compare->IsUndefined(isolate)) {
864 : DCHECK(bound_compare->IsJSFunction());
865 : // 5. Return collator.[[BoundCompare]].
866 : return *bound_compare;
867 : }
868 :
869 : Handle<JSFunction> new_bound_compare_function = CreateBoundFunction(
870 167 : isolate, collator, Builtins::kCollatorInternalCompare, 2);
871 :
872 : // 4.c. Set collator.[[BoundCompare]] to F.
873 334 : collator->set_bound_compare(*new_bound_compare_function);
874 :
875 : // 5. Return collator.[[BoundCompare]].
876 167 : return *new_bound_compare_function;
877 : }
878 :
879 30895 : BUILTIN(CollatorInternalCompare) {
880 : HandleScope scope(isolate);
881 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
882 :
883 : // 1. Let collator be F.[[Collator]].
884 : // 2. Assert: Type(collator) is Object and collator has an
885 : // [[InitializedCollator]] internal slot.
886 : Handle<JSCollator> collator = Handle<JSCollator>(
887 : JSCollator::cast(context->get(
888 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
889 : isolate);
890 :
891 : // 3. If x is not provided, let x be undefined.
892 6179 : Handle<Object> x = args.atOrUndefined(isolate, 1);
893 : // 4. If y is not provided, let y be undefined.
894 6179 : Handle<Object> y = args.atOrUndefined(isolate, 2);
895 :
896 : // 5. Let X be ? ToString(x).
897 : Handle<String> string_x;
898 12358 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_x,
899 : Object::ToString(isolate, x));
900 : // 6. Let Y be ? ToString(y).
901 : Handle<String> string_y;
902 12358 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_y,
903 : Object::ToString(isolate, y));
904 :
905 : // 7. Return CompareStrings(collator, X, Y).
906 12358 : icu::Collator* icu_collator = collator->icu_collator()->raw();
907 6179 : CHECK_NOT_NULL(icu_collator);
908 12358 : return *Intl::CompareStrings(isolate, *icu_collator, string_x, string_y);
909 : }
910 :
911 : // ecma402 #sec-segment-iterator-prototype-breakType
912 180630 : BUILTIN(SegmentIteratorPrototypeBreakType) {
913 : const char* const method = "get %SegmentIteratorPrototype%.breakType";
914 : HandleScope scope(isolate);
915 :
916 36126 : CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
917 72252 : return *segment_iterator->BreakType();
918 : }
919 :
920 : // ecma402 #sec-segment-iterator-prototype-following
921 89415 : BUILTIN(SegmentIteratorPrototypeFollowing) {
922 : const char* const method = "%SegmentIteratorPrototype%.following";
923 : HandleScope scope(isolate);
924 18288 : CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
925 :
926 17748 : Handle<Object> from = args.atOrUndefined(isolate, 1);
927 :
928 : Maybe<bool> success =
929 17748 : JSSegmentIterator::Following(isolate, segment_iterator, from);
930 17775 : MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
931 35442 : return *isolate->factory()->ToBoolean(success.FromJust());
932 : }
933 :
934 : // ecma402 #sec-segment-iterator-prototype-next
935 89595 : BUILTIN(SegmentIteratorPrototypeNext) {
936 : const char* const method = "%SegmentIteratorPrototype%.next";
937 : HandleScope scope(isolate);
938 18324 : CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
939 :
940 35568 : RETURN_RESULT_OR_FAILURE(isolate,
941 : JSSegmentIterator::Next(isolate, segment_iterator));
942 : }
943 :
944 : // ecma402 #sec-segment-iterator-prototype-preceding
945 45270 : BUILTIN(SegmentIteratorPrototypePreceding) {
946 : const char* const method = "%SegmentIteratorPrototype%.preceding";
947 : HandleScope scope(isolate);
948 9459 : CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
949 :
950 8919 : Handle<Object> from = args.atOrUndefined(isolate, 1);
951 :
952 : Maybe<bool> success =
953 8919 : JSSegmentIterator::Preceding(isolate, segment_iterator, from);
954 8964 : MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
955 17748 : return *isolate->factory()->ToBoolean(success.FromJust());
956 : }
957 :
958 : // ecma402 #sec-segment-iterator-prototype-index
959 504675 : BUILTIN(SegmentIteratorPrototypeIndex) {
960 : const char* const method = "get %SegmentIteratorPrototype%.index";
961 : HandleScope scope(isolate);
962 :
963 100935 : CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
964 201870 : return *JSSegmentIterator::Index(isolate, segment_iterator);
965 : }
966 :
967 3195 : BUILTIN(SegmenterConstructor) {
968 : HandleScope scope(isolate);
969 :
970 : return DisallowCallConstructor<JSSegmenter>(
971 : args, isolate, v8::Isolate::UseCounterFeature::kSegmenter,
972 1278 : "Intl.Segmenter");
973 : }
974 :
975 180 : BUILTIN(SegmenterSupportedLocalesOf) {
976 : HandleScope scope(isolate);
977 36 : Handle<Object> locales = args.atOrUndefined(isolate, 1);
978 36 : Handle<Object> options = args.atOrUndefined(isolate, 2);
979 :
980 72 : RETURN_RESULT_OR_FAILURE(
981 : isolate, Intl::SupportedLocalesOf(
982 : isolate, "Intl.Segmenter.supportedLocalesOf",
983 : JSSegmenter::GetAvailableLocales(), locales, options));
984 : }
985 :
986 405 : BUILTIN(SegmenterPrototypeResolvedOptions) {
987 : HandleScope scope(isolate);
988 81 : CHECK_RECEIVER(JSSegmenter, segmenter_holder,
989 : "Intl.Segmenter.prototype.resolvedOptions");
990 162 : return *JSSegmenter::ResolvedOptions(isolate, segmenter_holder);
991 : }
992 :
993 : // ecma402 #sec-Intl.Segmenter.prototype.segment
994 13905 : BUILTIN(SegmenterPrototypeSegment) {
995 : HandleScope scope(isolate);
996 2781 : CHECK_RECEIVER(JSSegmenter, segmenter_holder,
997 : "Intl.Segmenter.prototype.segment");
998 2781 : Handle<Object> input_text = args.atOrUndefined(isolate, 1);
999 : // 3. Let string be ? ToString(string).
1000 : Handle<String> text;
1001 5571 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
1002 : Object::ToString(isolate, input_text));
1003 :
1004 : // 4. Return ? CreateSegmentIterator(segment, string).
1005 5544 : RETURN_RESULT_OR_FAILURE(
1006 : isolate,
1007 : JSSegmentIterator::Create(
1008 : isolate, segmenter_holder->icu_break_iterator()->raw()->clone(),
1009 : segmenter_holder->granularity(), text));
1010 : }
1011 :
1012 1150 : BUILTIN(V8BreakIteratorConstructor) {
1013 : HandleScope scope(isolate);
1014 :
1015 460 : return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate);
1016 : }
1017 :
1018 360 : BUILTIN(V8BreakIteratorPrototypeResolvedOptions) {
1019 : HandleScope scope(isolate);
1020 72 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator,
1021 : "Intl.v8BreakIterator.prototype.resolvedOptions");
1022 144 : return *JSV8BreakIterator::ResolvedOptions(isolate, break_iterator);
1023 : }
1024 :
1025 385 : BUILTIN(V8BreakIteratorPrototypeAdoptText) {
1026 : const char* const method = "get Intl.v8BreakIterator.prototype.adoptText";
1027 : HandleScope scope(isolate);
1028 :
1029 185 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1030 :
1031 : Handle<Object> bound_adopt_text(break_iterator->bound_adopt_text(), isolate);
1032 41 : if (!bound_adopt_text->IsUndefined(isolate)) {
1033 : DCHECK(bound_adopt_text->IsJSFunction());
1034 : return *bound_adopt_text;
1035 : }
1036 :
1037 : Handle<JSFunction> new_bound_adopt_text_function = CreateBoundFunction(
1038 41 : isolate, break_iterator, Builtins::kV8BreakIteratorInternalAdoptText, 1);
1039 82 : break_iterator->set_bound_adopt_text(*new_bound_adopt_text_function);
1040 41 : return *new_bound_adopt_text_function;
1041 : }
1042 :
1043 205 : BUILTIN(V8BreakIteratorInternalAdoptText) {
1044 : HandleScope scope(isolate);
1045 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1046 :
1047 : Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1048 : JSV8BreakIterator::cast(context->get(
1049 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1050 : isolate);
1051 :
1052 41 : Handle<Object> input_text = args.atOrUndefined(isolate, 1);
1053 : Handle<String> text;
1054 82 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
1055 : Object::ToString(isolate, input_text));
1056 :
1057 41 : JSV8BreakIterator::AdoptText(isolate, break_iterator, text);
1058 41 : return ReadOnlyRoots(isolate).undefined_value();
1059 : }
1060 :
1061 360 : BUILTIN(V8BreakIteratorPrototypeFirst) {
1062 : const char* const method = "get Intl.v8BreakIterator.prototype.first";
1063 : HandleScope scope(isolate);
1064 :
1065 180 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1066 :
1067 : Handle<Object> bound_first(break_iterator->bound_first(), isolate);
1068 36 : if (!bound_first->IsUndefined(isolate)) {
1069 : DCHECK(bound_first->IsJSFunction());
1070 : return *bound_first;
1071 : }
1072 :
1073 : Handle<JSFunction> new_bound_first_function = CreateBoundFunction(
1074 36 : isolate, break_iterator, Builtins::kV8BreakIteratorInternalFirst, 0);
1075 72 : break_iterator->set_bound_first(*new_bound_first_function);
1076 36 : return *new_bound_first_function;
1077 : }
1078 :
1079 180 : BUILTIN(V8BreakIteratorInternalFirst) {
1080 : HandleScope scope(isolate);
1081 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1082 :
1083 : Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1084 : JSV8BreakIterator::cast(context->get(
1085 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1086 : isolate);
1087 :
1088 108 : return *JSV8BreakIterator::First(isolate, break_iterator);
1089 : }
1090 :
1091 2345 : BUILTIN(V8BreakIteratorPrototypeNext) {
1092 : const char* const method = "get Intl.v8BreakIterator.prototype.next";
1093 : HandleScope scope(isolate);
1094 :
1095 604 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1096 :
1097 : Handle<Object> bound_next(break_iterator->bound_next(), isolate);
1098 424 : if (!bound_next->IsUndefined(isolate)) {
1099 : DCHECK(bound_next->IsJSFunction());
1100 : return *bound_next;
1101 : }
1102 :
1103 : Handle<JSFunction> new_bound_next_function = CreateBoundFunction(
1104 50 : isolate, break_iterator, Builtins::kV8BreakIteratorInternalNext, 0);
1105 100 : break_iterator->set_bound_next(*new_bound_next_function);
1106 50 : return *new_bound_next_function;
1107 : }
1108 :
1109 2075 : BUILTIN(V8BreakIteratorInternalNext) {
1110 : HandleScope scope(isolate);
1111 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1112 :
1113 : Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1114 : JSV8BreakIterator::cast(context->get(
1115 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1116 : isolate);
1117 1245 : return *JSV8BreakIterator::Next(isolate, break_iterator);
1118 : }
1119 :
1120 180 : BUILTIN(V8BreakIteratorPrototypeCurrent) {
1121 : const char* const method = "get Intl.v8BreakIterator.prototype.current";
1122 : HandleScope scope(isolate);
1123 :
1124 144 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1125 :
1126 : Handle<Object> bound_current(break_iterator->bound_current(), isolate);
1127 0 : if (!bound_current->IsUndefined(isolate)) {
1128 : DCHECK(bound_current->IsJSFunction());
1129 : return *bound_current;
1130 : }
1131 :
1132 : Handle<JSFunction> new_bound_current_function = CreateBoundFunction(
1133 0 : isolate, break_iterator, Builtins::kV8BreakIteratorInternalCurrent, 0);
1134 0 : break_iterator->set_bound_current(*new_bound_current_function);
1135 0 : return *new_bound_current_function;
1136 : }
1137 :
1138 0 : BUILTIN(V8BreakIteratorInternalCurrent) {
1139 : HandleScope scope(isolate);
1140 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1141 :
1142 : Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1143 : JSV8BreakIterator::cast(context->get(
1144 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1145 : isolate);
1146 0 : return *JSV8BreakIterator::Current(isolate, break_iterator);
1147 : }
1148 :
1149 1575 : BUILTIN(V8BreakIteratorPrototypeBreakType) {
1150 : const char* const method = "get Intl.v8BreakIterator.prototype.breakType";
1151 : HandleScope scope(isolate);
1152 :
1153 423 : CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1154 :
1155 : Handle<Object> bound_break_type(break_iterator->bound_break_type(), isolate);
1156 279 : if (!bound_break_type->IsUndefined(isolate)) {
1157 : DCHECK(bound_break_type->IsJSFunction());
1158 : return *bound_break_type;
1159 : }
1160 :
1161 : Handle<JSFunction> new_bound_break_type_function = CreateBoundFunction(
1162 18 : isolate, break_iterator, Builtins::kV8BreakIteratorInternalBreakType, 0);
1163 36 : break_iterator->set_bound_break_type(*new_bound_break_type_function);
1164 18 : return *new_bound_break_type_function;
1165 : }
1166 :
1167 1395 : BUILTIN(V8BreakIteratorInternalBreakType) {
1168 : HandleScope scope(isolate);
1169 : Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1170 :
1171 : Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1172 : JSV8BreakIterator::cast(context->get(
1173 : static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1174 : isolate);
1175 558 : return JSV8BreakIterator::BreakType(isolate, break_iterator);
1176 : }
1177 :
1178 : } // namespace internal
1179 120216 : } // namespace v8
|