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