v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
builtins-intl.cc
Go to the documentation of this file.
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
15#include "src/date/date.h"
36#include "src/objects/smi.h"
37#include "unicode/brkiter.h"
38
39namespace v8 {
40namespace internal {
41
42BUILTIN(StringPrototypeToUpperCaseIntl) {
43 HandleScope scope(isolate);
44 TO_THIS_STRING(string, "String.prototype.toUpperCase");
45 string = String::Flatten(isolate, string);
46 RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string));
47}
48
49BUILTIN(StringPrototypeNormalizeIntl) {
50 HandleScope handle_scope(isolate);
52 TO_THIS_STRING(string, "String.prototype.normalize");
53
54 DirectHandle<Object> form_input = args.atOrUndefined(isolate, 1);
55
57 Intl::Normalize(isolate, string, form_input));
58}
59
60// ecma402 #sup-properties-of-the-string-prototype-object
61// ecma402 section 19.1.1.
62// String.prototype.localeCompare ( that [ , locales [ , options ] ] )
63// This implementation supersedes the definition provided in ES6.
64BUILTIN(StringPrototypeLocaleCompareIntl) {
65 HandleScope handle_scope(isolate);
66
68 static const char* const kMethod = "String.prototype.localeCompare";
69
73 isolate, str2, Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
74 std::optional<int> result = Intl::StringLocaleCompare(
75 isolate, str1, str2, args.atOrUndefined(isolate, 2),
76 args.atOrUndefined(isolate, 3), kMethod);
77 if (!result.has_value()) {
78 DCHECK(isolate->has_exception());
79 return ReadOnlyRoots(isolate).exception();
80 }
81 return Smi::FromInt(result.value());
82}
83
84BUILTIN(V8BreakIteratorSupportedLocalesOf) {
85 HandleScope scope(isolate);
86 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
87 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
88
91 isolate, "Intl.v8BreakIterator.supportedLocalesOf",
92 JSV8BreakIterator::GetAvailableLocales(), locales, options));
93}
94
95BUILTIN(NumberFormatSupportedLocalesOf) {
96 HandleScope scope(isolate);
97 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
98 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
99
102 isolate, "Intl.NumberFormat.supportedLocalesOf",
103 JSNumberFormat::GetAvailableLocales(), locales, options));
104}
105
106BUILTIN(NumberFormatPrototypeFormatToParts) {
107 const char* const method_name = "Intl.NumberFormat.prototype.formatToParts";
108 HandleScope handle_scope(isolate);
109 CHECK_RECEIVER(JSNumberFormat, number_format, method_name);
110
112 if (args.length() >= 2) {
113 x = args.at(1);
114 } else {
115 x = isolate->factory()->nan_value();
116 }
117
119 isolate, JSNumberFormat::FormatToParts(isolate, number_format, x));
120}
121
122BUILTIN(DateTimeFormatPrototypeResolvedOptions) {
123 const char* const method_name =
124 "Intl.DateTimeFormat.prototype.resolvedOptions";
125 HandleScope scope(isolate);
126 CHECK_RECEIVER(JSReceiver, format_holder, method_name);
127
128 // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
129 DirectHandle<JSDateTimeFormat> date_time_format;
131 isolate, date_time_format,
132 JSDateTimeFormat::UnwrapDateTimeFormat(isolate, format_holder));
133
135 isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_time_format));
136}
137
138BUILTIN(DateTimeFormatSupportedLocalesOf) {
139 HandleScope scope(isolate);
140 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
141 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
142
145 isolate, "Intl.DateTimeFormat.supportedLocalesOf",
146 JSDateTimeFormat::GetAvailableLocales(), locales, options));
147}
148
149BUILTIN(DateTimeFormatPrototypeFormatToParts) {
150 const char* const method_name = "Intl.DateTimeFormat.prototype.formatToParts";
151 HandleScope handle_scope(isolate);
152 CHECK_RECEIVER(JSObject, date_format_holder, method_name);
153 Factory* factory = isolate->factory();
154
155 if (!IsJSDateTimeFormat(*date_format_holder)) {
157 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
158 factory->NewStringFromAsciiChecked(method_name),
159 date_format_holder));
160 }
161 auto dtf = Cast<JSDateTimeFormat>(date_format_holder);
162
163 DirectHandle<Object> x = args.atOrUndefined(isolate, 1);
165 isolate, dtf, x, false, method_name));
166}
167
168// Common code for DateTimeFormatPrototypeFormatRange(|ToParts)
169template <class T,
170 MaybeDirectHandle<T> (*F)(Isolate*, DirectHandle<JSDateTimeFormat>,
171 DirectHandle<Object>, DirectHandle<Object>,
172 const char* const)>
174 BuiltinArguments args, Isolate* isolate, const char* const method_name) {
175 // 1. Let dtf be this value.
176 // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
177 CHECK_RECEIVER(JSDateTimeFormat, dtf, method_name);
178
179 // 3. If startDate is undefined or endDate is undefined, throw a TypeError
180 // exception.
181 DirectHandle<Object> start_date = args.atOrUndefined(isolate, 1);
182 DirectHandle<Object> end_date = args.atOrUndefined(isolate, 2);
183 if (IsUndefined(*start_date, isolate) || IsUndefined(*end_date, isolate)) {
185 isolate, NewTypeError(MessageTemplate::kInvalidTimeValue));
186 }
187
188 // 4. Return ? FormatDateTimeRange(dtf, startDate, endDate)
189 // OR
190 // 4. Return ? FormatDateTimeRangeToParts(dtf, startDate, endDate).
192 F(isolate, dtf, start_date, end_date, method_name));
193}
194
195BUILTIN(DateTimeFormatPrototypeFormatRange) {
196 const char* const method_name = "Intl.DateTimeFormat.prototype.formatRange";
197 HandleScope handle_scope(isolate);
199 args, isolate, method_name);
200}
201
202BUILTIN(DateTimeFormatPrototypeFormatRangeToParts) {
203 const char* const method_name =
204 "Intl.DateTimeFormat.prototype.formatRangeToParts";
205 HandleScope handle_scope(isolate);
207 args, isolate, method_name);
208}
209
210namespace {
211
212DirectHandle<JSFunction> CreateBoundFunction(Isolate* isolate,
213 DirectHandle<JSObject> object,
214 Builtin builtin, int len) {
215 DirectHandle<NativeContext> native_context(
216 isolate->context()->native_context(), isolate);
217 DirectHandle<Context> context = isolate->factory()->NewBuiltinContext(
220
221 context->set(static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction),
222 *object);
223
224 DirectHandle<SharedFunctionInfo> info =
225 isolate->factory()->NewSharedFunctionInfoForBuiltin(
226 isolate->factory()->empty_string(), builtin, len, kAdapt);
227
228 return Factory::JSFunctionBuilder{isolate, info, context}
229 .set_map(isolate->strict_function_without_prototype_map())
230 .Build();
231}
232
237template <class T>
238Tagged<Object> LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
240 DirectHandle<JSAny> constructor,
241 const char* method_name) {
242 isolate->CountUsage(feature);
243 DirectHandle<JSReceiver> new_target;
244 // 1. If NewTarget is undefined, let newTarget be the active
245 // function object, else let newTarget be NewTarget.
246 if (IsUndefined(*args.new_target(), isolate)) {
247 new_target = args.target();
248 } else {
249 new_target = Cast<JSReceiver>(args.new_target());
250 }
251
252 // [[Construct]]
253 DirectHandle<JSFunction> target = args.target();
254 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
255 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
256
257 // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget,
258 // "%<T>Prototype%", ...).
259 DirectHandle<Map> map;
261 isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
262
263 // 3. Perform ? Initialize<T>(Format, locales, options).
264 DirectHandle<T> format;
266 isolate, format, T::New(isolate, map, locales, options, method_name));
267 // 4. Let this be the this value.
268 if (IsUndefined(*args.new_target(), isolate)) {
269 DirectHandle<JSAny> receiver = args.receiver();
270 // 5. If NewTarget is undefined and ? OrdinaryHasInstance(%<T>%, this)
271 // is true, then Look up the intrinsic value that has been stored on
272 // the context.
273 DirectHandle<Object> ordinary_has_instance_obj;
275 isolate, ordinary_has_instance_obj,
276 Object::OrdinaryHasInstance(isolate, constructor, receiver));
277 if (Object::BooleanValue(*ordinary_has_instance_obj, isolate)) {
278 if (!IsJSReceiver(*receiver)) {
280 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
281 isolate->factory()->NewStringFromAsciiChecked(
282 method_name),
283 receiver));
284 }
285 DirectHandle<JSReceiver> rec = Cast<JSReceiver>(receiver);
286 // a. Perform ? DefinePropertyOrThrow(this,
287 // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format,
288 // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
289 PropertyDescriptor desc;
290 desc.set_value(format);
291 desc.set_writable(false);
292 desc.set_enumerable(false);
293 desc.set_configurable(false);
294 Maybe<bool> success = JSReceiver::DefineOwnProperty(
295 isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc,
297 MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
298 CHECK(success.FromJust());
299 // b. b. Return this.
300 return *receiver;
301 }
302 }
303 // 6. Return format.
304 return *format;
305}
306
311template <class T>
312Tagged<Object> DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
314 const char* method_name) {
315 isolate->CountUsage(feature);
316
317 // 1. If NewTarget is undefined, throw a TypeError exception.
318 if (IsUndefined(*args.new_target(), isolate)) { // [[Call]]
320 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
321 isolate->factory()->NewStringFromAsciiChecked(
322 method_name)));
323 }
324 // [[Construct]]
325 DirectHandle<JSFunction> target = args.target();
326 DirectHandle<JSReceiver> new_target = Cast<JSReceiver>(args.new_target());
327
328 DirectHandle<Map> map;
329 // 2. Let result be OrdinaryCreateFromConstructor(NewTarget,
330 // "%<T>Prototype%").
332 isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
333
334 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
335 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
336
337 // 3. Return New<T>(t, locales, options).
338 RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options));
339}
340
344template <class T>
345Tagged<Object> CallOrConstructConstructor(BuiltinArguments args,
346 Isolate* isolate,
347 const char* method_name) {
348 DirectHandle<JSReceiver> new_target;
349
350 if (IsUndefined(*args.new_target(), isolate)) {
351 new_target = args.target();
352 } else {
353 new_target = Cast<JSReceiver>(args.new_target());
354 }
355
356 // [[Construct]]
357 DirectHandle<JSFunction> target = args.target();
358
359 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
360 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
361
362 DirectHandle<Map> map;
364 isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
365
367 T::New(isolate, map, locales, options, method_name));
368}
369
370} // namespace
371
372// Intl.DisplayNames
373
374BUILTIN(DisplayNamesConstructor) {
375 HandleScope scope(isolate);
376
377 return DisallowCallConstructor<JSDisplayNames>(
379 "Intl.DisplayNames");
380}
381
382BUILTIN(DisplayNamesPrototypeResolvedOptions) {
383 HandleScope scope(isolate);
385 "Intl.DisplayNames.prototype.resolvedOptions");
386 return *JSDisplayNames::ResolvedOptions(isolate, holder);
387}
388
389BUILTIN(DisplayNamesSupportedLocalesOf) {
390 HandleScope scope(isolate);
391 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
392 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
393
396 isolate, "Intl.DisplayNames.supportedLocalesOf",
397 JSDisplayNames::GetAvailableLocales(), locales, options));
398}
399
400BUILTIN(DisplayNamesPrototypeOf) {
401 HandleScope scope(isolate);
402 CHECK_RECEIVER(JSDisplayNames, holder, "Intl.DisplayNames.prototype.of");
403 Handle<Object> code_obj = args.atOrUndefined(isolate, 1);
404
406 JSDisplayNames::Of(isolate, holder, code_obj));
407}
408
409// Intl.DurationFormat
410BUILTIN(DurationFormatConstructor) {
411 HandleScope scope(isolate);
412
413 return DisallowCallConstructor<JSDurationFormat>(
415 "Intl.DurationFormat");
416}
417
418BUILTIN(DurationFormatPrototypeResolvedOptions) {
419 HandleScope scope(isolate);
421 "Intl.DurationFormat.prototype.resolvedOptions");
422 return *JSDurationFormat::ResolvedOptions(isolate, holder);
423}
424
425BUILTIN(DurationFormatSupportedLocalesOf) {
426 HandleScope scope(isolate);
427 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
428 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
429
432 isolate, "Intl.DurationFormat.supportedLocalesOf",
433 JSDurationFormat::GetAvailableLocales(), locales, options));
434}
435
436BUILTIN(DurationFormatPrototypeFormat) {
437 HandleScope scope(isolate);
439 "Intl.DurationFormat.prototype.format");
440 Handle<Object> value = args.atOrUndefined(isolate, 1);
442 JSDurationFormat::Format(isolate, holder, value));
443}
444
445BUILTIN(DurationFormatPrototypeFormatToParts) {
446 HandleScope scope(isolate);
448 "Intl.DurationFormat.prototype.formatToParts");
449 Handle<Object> value = args.atOrUndefined(isolate, 1);
451 isolate, JSDurationFormat::FormatToParts(isolate, holder, value));
452}
453
454// Intl.NumberFormat
455
456BUILTIN(NumberFormatConstructor) {
457 HandleScope scope(isolate);
458
459 return LegacyFormatConstructor<JSNumberFormat>(
461 isolate->intl_number_format_function(), "Intl.NumberFormat");
462}
463
464BUILTIN(NumberFormatPrototypeResolvedOptions) {
465 HandleScope scope(isolate);
466 const char* const method_name = "Intl.NumberFormat.prototype.resolvedOptions";
467
468 // 1. Let nf be the this value.
469 // 2. If Type(nf) is not Object, throw a TypeError exception.
470 CHECK_RECEIVER(JSReceiver, number_format_holder, method_name);
471
472 // 3. Let nf be ? UnwrapNumberFormat(nf)
473 DirectHandle<JSNumberFormat> number_format;
475 isolate, number_format,
476 JSNumberFormat::UnwrapNumberFormat(isolate, number_format_holder));
477
478 return *JSNumberFormat::ResolvedOptions(isolate, number_format);
479}
480
481BUILTIN(NumberFormatPrototypeFormatNumber) {
482 const char* const method_name = "get Intl.NumberFormat.prototype.format";
483 HandleScope scope(isolate);
484
485 // 1. Let nf be the this value.
486 // 2. If Type(nf) is not Object, throw a TypeError exception.
487 CHECK_RECEIVER(JSReceiver, receiver, method_name);
488
489 // 3. Let nf be ? UnwrapNumberFormat(nf).
490 DirectHandle<JSNumberFormat> number_format;
492 isolate, number_format,
494
495 DirectHandle<Object> bound_format(number_format->bound_format(), isolate);
496
497 // 4. If nf.[[BoundFormat]] is undefined, then
498 if (!IsUndefined(*bound_format, isolate)) {
499 DCHECK(IsJSFunction(*bound_format));
500 // 5. Return nf.[[BoundFormat]].
501 return *bound_format;
502 }
503
504 DirectHandle<JSFunction> new_bound_format_function = CreateBoundFunction(
505 isolate, number_format, Builtin::kNumberFormatInternalFormatNumber, 1);
506
507 // 4. c. Set nf.[[BoundFormat]] to F.
508 number_format->set_bound_format(*new_bound_format_function);
509
510 // 5. Return nf.[[BoundFormat]].
511 return *new_bound_format_function;
512}
513
514BUILTIN(NumberFormatInternalFormatNumber) {
515 HandleScope scope(isolate);
516
517 DirectHandle<Context> context(isolate->context(), isolate);
518
519 // 1. Let nf be F.[[NumberFormat]].
520 // 2. Assert: Type(nf) is Object and nf has an
521 // [[InitializedNumberFormat]] internal slot.
522 DirectHandle<JSNumberFormat> number_format(
523 Cast<JSNumberFormat>(context->get(
525 isolate);
526
527 // 3. If value is not provided, let value be undefined.
528 Handle<Object> value = args.atOrUndefined(isolate, 1);
529
531 isolate, number_format, value));
532}
533
534// Common code for NumberFormatPrototypeFormatRange(|ToParts)
535template <class T,
536 MaybeDirectHandle<T> (*F)(Isolate*, DirectHandle<JSNumberFormat>,
539 BuiltinArguments args, Isolate* isolate, const char* const method_name) {
540 // 1. Let nf be this value.
541 // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
542 CHECK_RECEIVER(JSNumberFormat, nf, method_name);
543
544 Handle<Object> start = args.atOrUndefined(isolate, 1);
545 Handle<Object> end = args.atOrUndefined(isolate, 2);
546
547 Factory* factory = isolate->factory();
548 // 3. If start is undefined or end is undefined, throw a TypeError exception.
549 if (IsUndefined(*start, isolate)) {
551 isolate,
552 NewTypeError(MessageTemplate::kInvalid,
553 factory->NewStringFromStaticChars("start"), start));
554 }
555 if (IsUndefined(*end, isolate)) {
557 isolate, NewTypeError(MessageTemplate::kInvalid,
558 factory->NewStringFromStaticChars("end"), end));
559 }
560
561 RETURN_RESULT_OR_FAILURE(isolate, F(isolate, nf, start, end));
562}
563
564BUILTIN(NumberFormatPrototypeFormatRange) {
565 const char* const method_name = "Intl.NumberFormat.prototype.formatRange";
566 HandleScope handle_scope(isolate);
568 args, isolate, method_name);
569}
570
571BUILTIN(NumberFormatPrototypeFormatRangeToParts) {
572 const char* const method_name =
573 "Intl.NumberFormat.prototype.formatRangeToParts";
574 HandleScope handle_scope(isolate);
576 args, isolate, method_name);
577}
578
579BUILTIN(DateTimeFormatConstructor) {
580 HandleScope scope(isolate);
581
582 return LegacyFormatConstructor<JSDateTimeFormat>(
584 isolate->intl_date_time_format_function(), "Intl.DateTimeFormat");
585}
586
587BUILTIN(DateTimeFormatPrototypeFormat) {
588 const char* const method_name = "get Intl.DateTimeFormat.prototype.format";
589 HandleScope scope(isolate);
590
591 // 1. Let dtf be this value.
592 // 2. If Type(dtf) is not Object, throw a TypeError exception.
593 CHECK_RECEIVER(JSReceiver, receiver, method_name);
594
595 // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
598 isolate, format,
600
601 DirectHandle<Object> bound_format =
602 DirectHandle<Object>(format->bound_format(), isolate);
603
604 // 4. If dtf.[[BoundFormat]] is undefined, then
605 if (!IsUndefined(*bound_format, isolate)) {
606 DCHECK(IsJSFunction(*bound_format));
607 // 5. Return dtf.[[BoundFormat]].
608 return *bound_format;
609 }
610
611 DirectHandle<JSFunction> new_bound_format_function = CreateBoundFunction(
612 isolate, format, Builtin::kDateTimeFormatInternalFormat, 1);
613
614 // 4.c. Set dtf.[[BoundFormat]] to F.
615 format->set_bound_format(*new_bound_format_function);
616
617 // 5. Return dtf.[[BoundFormat]].
618 return *new_bound_format_function;
619}
620
621BUILTIN(DateTimeFormatInternalFormat) {
622 HandleScope scope(isolate);
623 DirectHandle<Context> context(isolate->context(), isolate);
624
625 // 1. Let dtf be F.[[DateTimeFormat]].
626 // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]]
627 // internal slot.
628 DirectHandle<JSDateTimeFormat> date_format_holder(
629 Cast<JSDateTimeFormat>(context->get(
631 isolate);
632
633 DirectHandle<Object> date = args.atOrUndefined(isolate, 1);
634
636 isolate, date_format_holder, date,
637 "DateTime Format Functions"));
638}
639
640BUILTIN(IntlGetCanonicalLocales) {
641 HandleScope scope(isolate);
642 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
643
645 Intl::GetCanonicalLocales(isolate, locales));
646}
647
648BUILTIN(IntlSupportedValuesOf) {
649 HandleScope scope(isolate);
650 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
651
652 RETURN_RESULT_OR_FAILURE(isolate, Intl::SupportedValuesOf(isolate, locales));
653}
654
655BUILTIN(ListFormatConstructor) {
656 HandleScope scope(isolate);
657
658 return DisallowCallConstructor<JSListFormat>(
660 "Intl.ListFormat");
661}
662
663BUILTIN(ListFormatPrototypeResolvedOptions) {
664 HandleScope scope(isolate);
665 CHECK_RECEIVER(JSListFormat, format_holder,
666 "Intl.ListFormat.prototype.resolvedOptions");
667 return *JSListFormat::ResolvedOptions(isolate, format_holder);
668}
669
670BUILTIN(ListFormatSupportedLocalesOf) {
671 HandleScope scope(isolate);
672 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
673 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
674
677 isolate, "Intl.ListFormat.supportedLocalesOf",
678 JSListFormat::GetAvailableLocales(), locales, options));
679}
680
681// Intl.Locale implementation
682BUILTIN(LocaleConstructor) {
683 HandleScope scope(isolate);
684
685 isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
686
687 const char* method_name = "Intl.Locale";
688 if (IsUndefined(*args.new_target(), isolate)) { // [[Call]]
690 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
691 isolate->factory()->NewStringFromAsciiChecked(
692 method_name)));
693 }
694 // [[Construct]]
695 DirectHandle<JSFunction> target = args.target();
697
698 DirectHandle<Object> tag = args.atOrUndefined(isolate, 1);
699 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
700
702 // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget,
703 // %LocalePrototype%, internalSlotsList).
705 isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
706
707 // 7. If Type(tag) is not String or Object, throw a TypeError exception.
708 if (!IsString(*tag) && !IsJSReceiver(*tag)) {
710 isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty));
711 }
712
713 DirectHandle<String> locale_string;
714 // 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal
715 // slot, then
716 if (IsJSLocale(*tag)) {
717 // a. Let tag be tag.[[Locale]].
718 locale_string = JSLocale::ToString(isolate, Cast<JSLocale>(tag));
719 } else { // 9. Else,
720 // a. Let tag be ? ToString(tag).
721 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_string,
722 Object::ToString(isolate, tag));
723 }
724
725 // 10. Set options to ? CoerceOptionsToObject(options).
726 DirectHandle<JSReceiver> options_object;
728 isolate, options_object,
729 CoerceOptionsToObject(isolate, options, method_name));
730
732 isolate, JSLocale::New(isolate, map, locale_string, options_object));
733}
734
735BUILTIN(LocalePrototypeMaximize) {
736 HandleScope scope(isolate);
737 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize");
738 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Maximize(isolate, locale));
739}
740
741BUILTIN(LocalePrototypeMinimize) {
742 HandleScope scope(isolate);
743 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize");
744 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Minimize(isolate, locale));
745}
746
747BUILTIN(LocalePrototypeGetCalendars) {
748 HandleScope scope(isolate);
750 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getCalendars");
751 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCalendars(isolate, locale));
752}
753
754BUILTIN(LocalePrototypeGetCollations) {
755 HandleScope scope(isolate);
757 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getCollations");
758 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCollations(isolate, locale));
759}
760
761BUILTIN(LocalePrototypeGetHourCycles) {
762 HandleScope scope(isolate);
764 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getHourCycles");
765 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetHourCycles(isolate, locale));
766}
767
768BUILTIN(LocalePrototypeGetNumberingSystems) {
769 HandleScope scope(isolate);
771 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getNumberingSystems");
773 JSLocale::GetNumberingSystems(isolate, locale));
774}
775
776BUILTIN(LocalePrototypeGetTextInfo) {
777 HandleScope scope(isolate);
779 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getTextInfo");
780 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTextInfo(isolate, locale));
781}
782
783BUILTIN(LocalePrototypeGetTimeZones) {
784 HandleScope scope(isolate);
786 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getTimeZones");
787 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTimeZones(isolate, locale));
788}
789
790BUILTIN(LocalePrototypeGetWeekInfo) {
791 HandleScope scope(isolate);
793 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getWeekInfo");
794 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetWeekInfo(isolate, locale));
795}
796
797BUILTIN(LocalePrototypeCalendars) {
798 HandleScope scope(isolate);
799 isolate->CountUsage(
801 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendars");
802 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCalendars(isolate, locale));
803}
804
805BUILTIN(LocalePrototypeCollations) {
806 HandleScope scope(isolate);
807 isolate->CountUsage(
809 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collations");
810 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCollations(isolate, locale));
811}
812
813BUILTIN(LocalePrototypeHourCycles) {
814 HandleScope scope(isolate);
815 isolate->CountUsage(
817 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycles");
818 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetHourCycles(isolate, locale));
819}
820
821BUILTIN(LocalePrototypeNumberingSystems) {
822 HandleScope scope(isolate);
823 isolate->CountUsage(
825 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystems");
827 JSLocale::GetNumberingSystems(isolate, locale));
828}
829
830BUILTIN(LocalePrototypeTextInfo) {
831 HandleScope scope(isolate);
832 isolate->CountUsage(
834 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.textInfo");
835 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTextInfo(isolate, locale));
836}
837
838BUILTIN(LocalePrototypeTimeZones) {
839 HandleScope scope(isolate);
840 isolate->CountUsage(
842 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.timeZones");
843 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTimeZones(isolate, locale));
844}
845
846BUILTIN(LocalePrototypeWeekInfo) {
847 HandleScope scope(isolate);
848 isolate->CountUsage(
850 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.weekInfo");
851 RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetWeekInfo(isolate, locale));
852}
853
854BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
855 HandleScope scope(isolate);
856 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
857 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
858
860 isolate,
862 isolate, "Intl.RelativeTimeFormat.supportedLocalesOf",
863 JSRelativeTimeFormat::GetAvailableLocales(), locales, options));
864}
865
866BUILTIN(RelativeTimeFormatPrototypeFormat) {
867 HandleScope scope(isolate);
868 // 1. Let relativeTimeFormat be the this value.
869 // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
870 // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
871 // true, throw a TypeError exception.
873 "Intl.RelativeTimeFormat.prototype.format");
874 Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
875 Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
876
878 isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj,
879 format_holder));
880}
881
882BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
883 HandleScope scope(isolate);
884 // 1. Let relativeTimeFormat be the this value.
885 // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
886 // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
887 // true, throw a TypeError exception.
889 "Intl.RelativeTimeFormat.prototype.formatToParts");
890 Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
891 Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
893 isolate, JSRelativeTimeFormat::FormatToParts(isolate, value_obj, unit_obj,
894 format_holder));
895}
896
897// Locale getters.
898BUILTIN(LocalePrototypeLanguage) {
899 HandleScope scope(isolate);
900 // CHECK_RECEIVER will case locale_holder to JSLocale.
901 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.language");
902
903 return *JSLocale::Language(isolate, locale);
904}
905
906BUILTIN(LocalePrototypeScript) {
907 HandleScope scope(isolate);
908 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.script");
909
910 return *JSLocale::Script(isolate, locale);
911}
912
913BUILTIN(LocalePrototypeRegion) {
914 HandleScope scope(isolate);
915 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.region");
916
917 return *JSLocale::Region(isolate, locale);
918}
919
920BUILTIN(LocalePrototypeBaseName) {
921 HandleScope scope(isolate);
922 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.baseName");
923
924 return *JSLocale::BaseName(isolate, locale);
925}
926
927BUILTIN(LocalePrototypeCalendar) {
928 HandleScope scope(isolate);
929 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendar");
930
931 return *JSLocale::Calendar(isolate, locale);
932}
933
934BUILTIN(LocalePrototypeCaseFirst) {
935 HandleScope scope(isolate);
936 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.caseFirst");
937
938 return *JSLocale::CaseFirst(isolate, locale);
939}
940
941BUILTIN(LocalePrototypeCollation) {
942 HandleScope scope(isolate);
943 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collation");
944
945 return *JSLocale::Collation(isolate, locale);
946}
947
948BUILTIN(LocalePrototypeFirstDayOfWeek) {
949 HandleScope scope(isolate);
950 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.firstDayOfWeek");
951
952 return *JSLocale::FirstDayOfWeek(isolate, locale);
953}
954
955BUILTIN(LocalePrototypeHourCycle) {
956 HandleScope scope(isolate);
957 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycle");
958
959 return *JSLocale::HourCycle(isolate, locale);
960}
961
962BUILTIN(LocalePrototypeNumeric) {
963 HandleScope scope(isolate);
964 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numeric");
965
966 return *JSLocale::Numeric(isolate, locale);
967}
968
969BUILTIN(LocalePrototypeNumberingSystem) {
970 HandleScope scope(isolate);
971 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystem");
972
973 return *JSLocale::NumberingSystem(isolate, locale);
974}
975
976BUILTIN(LocalePrototypeToString) {
977 HandleScope scope(isolate);
978 CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.toString");
979
980 return *JSLocale::ToString(isolate, locale);
981}
982
983BUILTIN(RelativeTimeFormatConstructor) {
984 HandleScope scope(isolate);
985
986 return DisallowCallConstructor<JSRelativeTimeFormat>(
988 "Intl.RelativeTimeFormat");
989}
990
991BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) {
992 HandleScope scope(isolate);
994 "Intl.RelativeTimeFormat.prototype.resolvedOptions");
995 return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder);
996}
997
998bool IsFastLocale(Tagged<Object> maybe_locale) {
1000 if (!IsSeqOneByteString(maybe_locale)) {
1001 return false;
1002 }
1003 auto locale = Cast<SeqOneByteString>(maybe_locale);
1004 uint8_t* chars = locale->GetChars(no_gc);
1005 if (locale->length() < 2 || !std::isalpha(chars[0]) ||
1006 !std::isalpha(chars[1])) {
1007 return false;
1008 }
1009 if (locale->length() != 2 &&
1010 (locale->length() != 5 || chars[2] != '-' || !std::isalpha(chars[3]) ||
1011 !std::isalpha(chars[4]))) {
1012 return false;
1013 }
1014 char first = chars[0] | 0x20;
1015 char second = chars[1] | 0x20;
1016 return (first != 'a' || second != 'z') && (first != 'e' || second != 'l') &&
1017 (first != 'l' || second != 't') && (first != 't' || second != 'r');
1018}
1019
1020BUILTIN(StringPrototypeToLocaleUpperCase) {
1021 HandleScope scope(isolate);
1022 DirectHandle<Object> maybe_locale = args.atOrUndefined(isolate, 1);
1023 TO_THIS_STRING(string, "String.prototype.toLocaleUpperCase");
1024 if (IsUndefined(*maybe_locale) || IsFastLocale(*maybe_locale)) {
1025 string = String::Flatten(isolate, string);
1026 RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string));
1027 } else {
1029 isolate, string, true, maybe_locale));
1030 }
1031}
1032
1033BUILTIN(PluralRulesConstructor) {
1034 HandleScope scope(isolate);
1035
1036 return DisallowCallConstructor<JSPluralRules>(
1038 "Intl.PluralRules");
1039}
1040
1041BUILTIN(PluralRulesPrototypeResolvedOptions) {
1042 HandleScope scope(isolate);
1043 CHECK_RECEIVER(JSPluralRules, plural_rules_holder,
1044 "Intl.PluralRules.prototype.resolvedOptions");
1045 return *JSPluralRules::ResolvedOptions(isolate, plural_rules_holder);
1046}
1047
1048BUILTIN(PluralRulesPrototypeSelect) {
1049 HandleScope scope(isolate);
1050
1051 // 1. 1. Let pr be the this value.
1052 // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
1053 CHECK_RECEIVER(JSPluralRules, plural_rules,
1054 "Intl.PluralRules.prototype.select");
1055
1056 // 3. Let n be ? ToNumber(value).
1057 DirectHandle<Object> number = args.atOrUndefined(isolate, 1);
1058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number,
1059 Object::ToNumber(isolate, number));
1060 double number_double = Object::NumberValue(*number);
1061
1062 // 4. Return ! ResolvePlural(pr, n).
1064 isolate, plural_rules, number_double));
1065}
1066
1067BUILTIN(PluralRulesPrototypeSelectRange) {
1068 HandleScope scope(isolate);
1069
1070 // 1. Let pr be the this value.
1071 // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
1072 CHECK_RECEIVER(JSPluralRules, plural_rules,
1073 "Intl.PluralRules.prototype.selectRange");
1074
1075 // 3. If start is undefined or end is undefined, throw a TypeError exception.
1076 DirectHandle<Object> start = args.atOrUndefined(isolate, 1);
1077 DirectHandle<Object> end = args.atOrUndefined(isolate, 2);
1078 if (IsUndefined(*start)) {
1080 isolate, NewTypeError(MessageTemplate::kInvalid,
1081 isolate->factory()->startRange_string(), start));
1082 }
1083 if (IsUndefined(*end)) {
1085 isolate, NewTypeError(MessageTemplate::kInvalid,
1086 isolate->factory()->endRange_string(), end));
1087 }
1088
1089 // 4. Let x be ? ToNumber(start).
1092 Object::ToNumber(isolate, start));
1093
1094 // 5. Let y be ? ToNumber(end).
1097 Object::ToNumber(isolate, end));
1098
1099 // 6. Return ! ResolvePluralRange(pr, x, y).
1100 if (IsNaN(*x)) {
1102 isolate, NewRangeError(MessageTemplate::kInvalid,
1103 isolate->factory()->startRange_string(), x));
1104 }
1105 if (IsNaN(*y)) {
1107 isolate, NewRangeError(MessageTemplate::kInvalid,
1108 isolate->factory()->endRange_string(), y));
1109 }
1110
1112 isolate, JSPluralRules::ResolvePluralRange(isolate, plural_rules,
1115}
1116
1117BUILTIN(PluralRulesSupportedLocalesOf) {
1118 HandleScope scope(isolate);
1119 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
1120 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
1121
1123 isolate, Intl::SupportedLocalesOf(
1124 isolate, "Intl.PluralRules.supportedLocalesOf",
1125 JSPluralRules::GetAvailableLocales(), locales, options));
1126}
1127
1128BUILTIN(CollatorConstructor) {
1129 HandleScope scope(isolate);
1130
1131 isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator);
1132
1133 return CallOrConstructConstructor<JSCollator>(args, isolate, "Intl.Collator");
1134}
1135
1136BUILTIN(CollatorPrototypeResolvedOptions) {
1137 HandleScope scope(isolate);
1138 CHECK_RECEIVER(JSCollator, collator_holder,
1139 "Intl.Collator.prototype.resolvedOptions");
1140 return *JSCollator::ResolvedOptions(isolate, collator_holder);
1141}
1142
1143BUILTIN(CollatorSupportedLocalesOf) {
1144 HandleScope scope(isolate);
1145 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
1146 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
1147
1149 isolate, Intl::SupportedLocalesOf(
1150 isolate, "Intl.Collator.supportedLocalesOf",
1151 JSCollator::GetAvailableLocales(), locales, options));
1152}
1153
1154BUILTIN(CollatorPrototypeCompare) {
1155 const char* const method_name = "get Intl.Collator.prototype.compare";
1156 HandleScope scope(isolate);
1157
1158 // 1. Let collator be this value.
1159 // 2. If Type(collator) is not Object, throw a TypeError exception.
1160 // 3. If collator does not have an [[InitializedCollator]] internal slot,
1161 // throw a TypeError exception.
1162 CHECK_RECEIVER(JSCollator, collator, method_name);
1163
1164 // 4. If collator.[[BoundCompare]] is undefined, then
1165 DirectHandle<Object> bound_compare(collator->bound_compare(), isolate);
1166 if (!IsUndefined(*bound_compare, isolate)) {
1167 DCHECK(IsJSFunction(*bound_compare));
1168 // 5. Return collator.[[BoundCompare]].
1169 return *bound_compare;
1170 }
1171
1172 DirectHandle<JSFunction> new_bound_compare_function = CreateBoundFunction(
1173 isolate, collator, Builtin::kCollatorInternalCompare, 2);
1174
1175 // 4.c. Set collator.[[BoundCompare]] to F.
1176 collator->set_bound_compare(*new_bound_compare_function);
1177
1178 // 5. Return collator.[[BoundCompare]].
1179 return *new_bound_compare_function;
1180}
1181
1182BUILTIN(CollatorInternalCompare) {
1183 HandleScope scope(isolate);
1184 DirectHandle<Context> context(isolate->context(), isolate);
1185
1186 // 1. Let collator be F.[[Collator]].
1187 // 2. Assert: Type(collator) is Object and collator has an
1188 // [[InitializedCollator]] internal slot.
1189 DirectHandle<JSCollator> collator(
1190 Cast<JSCollator>(context->get(
1192 isolate);
1193
1194 // 3. If x is not provided, let x be undefined.
1195 DirectHandle<Object> x = args.atOrUndefined(isolate, 1);
1196 // 4. If y is not provided, let y be undefined.
1197 DirectHandle<Object> y = args.atOrUndefined(isolate, 2);
1198
1199 // 5. Let X be ? ToString(x).
1200 DirectHandle<String> string_x;
1201 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_x,
1202 Object::ToString(isolate, x));
1203 // 6. Let Y be ? ToString(y).
1204 DirectHandle<String> string_y;
1205 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_y,
1206 Object::ToString(isolate, y));
1207
1208 // 7. Return CompareStrings(collator, X, Y).
1209 icu::Collator* icu_collator = collator->icu_collator()->raw();
1210 CHECK_NOT_NULL(icu_collator);
1211 return Smi::FromInt(
1212 Intl::CompareStrings(isolate, *icu_collator, string_x, string_y));
1213}
1214
1215// ecma402 #sec-%segmentiteratorprototype%.next
1216BUILTIN(SegmentIteratorPrototypeNext) {
1217 const char* const method_name = "%SegmentIterator.prototype%.next";
1218 HandleScope scope(isolate);
1219 CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method_name);
1220
1222 JSSegmentIterator::Next(isolate, segment_iterator));
1223}
1224
1225// ecma402 #sec-intl.segmenter
1226BUILTIN(SegmenterConstructor) {
1227 HandleScope scope(isolate);
1228
1229 return DisallowCallConstructor<JSSegmenter>(
1231 "Intl.Segmenter");
1232}
1233
1234// ecma402 #sec-intl.segmenter.supportedlocalesof
1235BUILTIN(SegmenterSupportedLocalesOf) {
1236 HandleScope scope(isolate);
1237 DirectHandle<Object> locales = args.atOrUndefined(isolate, 1);
1238 DirectHandle<Object> options = args.atOrUndefined(isolate, 2);
1239
1241 isolate, Intl::SupportedLocalesOf(
1242 isolate, "Intl.Segmenter.supportedLocalesOf",
1243 JSSegmenter::GetAvailableLocales(), locales, options));
1244}
1245
1246// ecma402 #sec-intl.segmenter.prototype.resolvedoptions
1247BUILTIN(SegmenterPrototypeResolvedOptions) {
1248 HandleScope scope(isolate);
1249 CHECK_RECEIVER(JSSegmenter, segmenter,
1250 "Intl.Segmenter.prototype.resolvedOptions");
1251 return *JSSegmenter::ResolvedOptions(isolate, segmenter);
1252}
1253
1254// ecma402 #sec-intl.segmenter.prototype.segment
1255BUILTIN(SegmenterPrototypeSegment) {
1256 HandleScope scope(isolate);
1257 CHECK_RECEIVER(JSSegmenter, segmenter, "Intl.Segmenter.prototype.segment");
1258 Handle<Object> input_text = args.atOrUndefined(isolate, 1);
1259 // 3. Let string be ? ToString(string).
1261 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
1262 Object::ToString(isolate, input_text));
1263
1264 // 4. Return ? CreateSegmentsObject(segmenter, string).
1266 JSSegments::Create(isolate, segmenter, string));
1267}
1268
1269// ecma402 #sec-%segmentsprototype%.containing
1270BUILTIN(SegmentsPrototypeContaining) {
1271 const char* const method_name = "%Segments.prototype%.containing";
1272 HandleScope scope(isolate);
1273 CHECK_RECEIVER(JSSegments, segments, method_name);
1274 DirectHandle<Object> index = args.atOrUndefined(isolate, 1);
1275
1276 // 6. Let n be ? ToInteger(index).
1277 double n;
1279 isolate, n, Object::IntegerValue(isolate, index));
1280
1282 JSSegments::Containing(isolate, segments, n));
1283}
1284
1285// ecma402 #sec-%segmentsprototype%-@@iterator
1286BUILTIN(SegmentsPrototypeIterator) {
1287 const char* const method_name = "%SegmentIsPrototype%[@@iterator]";
1288 HandleScope scope(isolate);
1289 CHECK_RECEIVER(JSSegments, segments, method_name);
1291 isolate,
1293 isolate, direct_handle(segments->raw_string(), isolate),
1294 segments->icu_break_iterator()->raw(), segments->granularity()));
1295}
1296
1297BUILTIN(V8BreakIteratorConstructor) {
1298 HandleScope scope(isolate);
1299
1300 return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate,
1301 "Intl.v8BreakIterator");
1302}
1303
1304BUILTIN(V8BreakIteratorPrototypeResolvedOptions) {
1305 HandleScope scope(isolate);
1306 CHECK_RECEIVER(JSV8BreakIterator, break_iterator,
1307 "Intl.v8BreakIterator.prototype.resolvedOptions");
1308 return *JSV8BreakIterator::ResolvedOptions(isolate, break_iterator);
1309}
1310
1311BUILTIN(V8BreakIteratorPrototypeAdoptText) {
1312 const char* const method_name =
1313 "get Intl.v8BreakIterator.prototype.adoptText";
1314 HandleScope scope(isolate);
1315
1316 CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name);
1317
1318 DirectHandle<Object> bound_adopt_text(break_iterator->bound_adopt_text(),
1319 isolate);
1320 if (!IsUndefined(*bound_adopt_text, isolate)) {
1321 DCHECK(IsJSFunction(*bound_adopt_text));
1322 return *bound_adopt_text;
1323 }
1324
1325 DirectHandle<JSFunction> new_bound_adopt_text_function = CreateBoundFunction(
1326 isolate, break_iterator, Builtin::kV8BreakIteratorInternalAdoptText, 1);
1327 break_iterator->set_bound_adopt_text(*new_bound_adopt_text_function);
1328 return *new_bound_adopt_text_function;
1329}
1330
1331BUILTIN(V8BreakIteratorInternalAdoptText) {
1332 HandleScope scope(isolate);
1333 DirectHandle<Context> context(isolate->context(), isolate);
1334
1335 DirectHandle<JSV8BreakIterator> break_iterator(
1336 Cast<JSV8BreakIterator>(context->get(
1338 isolate);
1339
1340 Handle<Object> input_text = args.atOrUndefined(isolate, 1);
1343 Object::ToString(isolate, input_text));
1344
1345 JSV8BreakIterator::AdoptText(isolate, break_iterator, text);
1346 return ReadOnlyRoots(isolate).undefined_value();
1347}
1348
1349BUILTIN(V8BreakIteratorPrototypeFirst) {
1350 const char* const method_name = "get Intl.v8BreakIterator.prototype.first";
1351 HandleScope scope(isolate);
1352
1353 CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name);
1354
1355 DirectHandle<Object> bound_first(break_iterator->bound_first(), isolate);
1356 if (!IsUndefined(*bound_first, isolate)) {
1357 DCHECK(IsJSFunction(*bound_first));
1358 return *bound_first;
1359 }
1360
1361 DirectHandle<JSFunction> new_bound_first_function = CreateBoundFunction(
1362 isolate, break_iterator, Builtin::kV8BreakIteratorInternalFirst, 0);
1363 break_iterator->set_bound_first(*new_bound_first_function);
1364 return *new_bound_first_function;
1365}
1366
1367BUILTIN(V8BreakIteratorInternalFirst) {
1368 HandleScope scope(isolate);
1369 DirectHandle<Context> context(isolate->context(), isolate);
1370
1371 DirectHandle<JSV8BreakIterator> break_iterator(
1372 Cast<JSV8BreakIterator>(context->get(
1374 isolate);
1375
1376 return *JSV8BreakIterator::First(isolate, break_iterator);
1377}
1378
1379BUILTIN(V8BreakIteratorPrototypeNext) {
1380 const char* const method_name = "get Intl.v8BreakIterator.prototype.next";
1381 HandleScope scope(isolate);
1382
1383 CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name);
1384
1385 DirectHandle<Object> bound_next(break_iterator->bound_next(), isolate);
1386 if (!IsUndefined(*bound_next, isolate)) {
1387 DCHECK(IsJSFunction(*bound_next));
1388 return *bound_next;
1389 }
1390
1391 DirectHandle<JSFunction> new_bound_next_function = CreateBoundFunction(
1392 isolate, break_iterator, Builtin::kV8BreakIteratorInternalNext, 0);
1393 break_iterator->set_bound_next(*new_bound_next_function);
1394 return *new_bound_next_function;
1395}
1396
1397BUILTIN(V8BreakIteratorInternalNext) {
1398 HandleScope scope(isolate);
1399 DirectHandle<Context> context(isolate->context(), isolate);
1400
1401 DirectHandle<JSV8BreakIterator> break_iterator(
1402 Cast<JSV8BreakIterator>(context->get(
1404 isolate);
1405 return *JSV8BreakIterator::Next(isolate, break_iterator);
1406}
1407
1408BUILTIN(V8BreakIteratorPrototypeCurrent) {
1409 const char* const method_name = "get Intl.v8BreakIterator.prototype.current";
1410 HandleScope scope(isolate);
1411
1412 CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name);
1413
1414 DirectHandle<Object> bound_current(break_iterator->bound_current(), isolate);
1415 if (!IsUndefined(*bound_current, isolate)) {
1416 DCHECK(IsJSFunction(*bound_current));
1417 return *bound_current;
1418 }
1419
1420 DirectHandle<JSFunction> new_bound_current_function = CreateBoundFunction(
1421 isolate, break_iterator, Builtin::kV8BreakIteratorInternalCurrent, 0);
1422 break_iterator->set_bound_current(*new_bound_current_function);
1423 return *new_bound_current_function;
1424}
1425
1426BUILTIN(V8BreakIteratorInternalCurrent) {
1427 HandleScope scope(isolate);
1428 DirectHandle<Context> context(isolate->context(), isolate);
1429
1430 DirectHandle<JSV8BreakIterator> break_iterator(
1431 Cast<JSV8BreakIterator>(context->get(
1433 isolate);
1434 return *JSV8BreakIterator::Current(isolate, break_iterator);
1435}
1436
1437BUILTIN(V8BreakIteratorPrototypeBreakType) {
1438 const char* const method_name =
1439 "get Intl.v8BreakIterator.prototype.breakType";
1440 HandleScope scope(isolate);
1441
1442 CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name);
1443
1444 DirectHandle<Object> bound_break_type(break_iterator->bound_break_type(),
1445 isolate);
1446 if (!IsUndefined(*bound_break_type, isolate)) {
1447 DCHECK(IsJSFunction(*bound_break_type));
1448 return *bound_break_type;
1449 }
1450
1451 DirectHandle<JSFunction> new_bound_break_type_function = CreateBoundFunction(
1452 isolate, break_iterator, Builtin::kV8BreakIteratorInternalBreakType, 0);
1453 break_iterator->set_bound_break_type(*new_bound_break_type_function);
1454 return *new_bound_break_type_function;
1455}
1456
1457BUILTIN(V8BreakIteratorInternalBreakType) {
1458 HandleScope scope(isolate);
1459 DirectHandle<Context> context(isolate->context(), isolate);
1460
1461 DirectHandle<JSV8BreakIterator> break_iterator(
1462 Cast<JSV8BreakIterator>(context->get(
1464 isolate);
1465 return JSV8BreakIterator::BreakType(isolate, break_iterator);
1466}
1467
1468} // namespace internal
1469} // namespace v8
#define T
#define TO_THIS_STRING(name, method)
#define CHECK_RECEIVER(Type, name, method)
#define BUILTIN(name)
@ kLocaleInfoFunctions
Definition v8-isolate.h:591
@ kRelativeTimeFormat
Definition v8-isolate.h:527
@ kStringLocaleCompare
Definition v8-isolate.h:531
@ kLocaleInfoObsoletedGetters
Definition v8-isolate.h:590
Handle< String > NewStringFromAsciiChecked(const char *str, AllocationType allocation=AllocationType::kYoung)
Handle< String > NewStringFromStaticChars(const char(&str)[N], AllocationType allocation=AllocationType::kYoung)
Definition factory-inl.h:79
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > StringLocaleConvertCase(Isolate *isolate, DirectHandle< String > s, bool is_upper, DirectHandle< Object > locales)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT int CompareStrings(Isolate *isolate, const icu::Collator &collator, DirectHandle< String > s1, DirectHandle< String > s2, CompareStringsOptions compare_strings_options=CompareStringsOptions::kNone)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > Normalize(Isolate *isolate, DirectHandle< String > string, DirectHandle< Object > form_input)
static V8_WARN_UNUSED_RESULT std::optional< int > StringLocaleCompare(Isolate *isolate, DirectHandle< String > s1, DirectHandle< String > s2, DirectHandle< Object > locales, DirectHandle< Object > options, const char *method_name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetCanonicalLocales(Isolate *isolate, DirectHandle< Object > locales)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ConvertToUpper(Isolate *isolate, DirectHandle< String > s)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > SupportedValuesOf(Isolate *isolate, DirectHandle< Object > key)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSObject > SupportedLocalesOf(Isolate *isolate, const char *method_name, const std::set< std::string > &available_locales, DirectHandle< Object > locales_in, DirectHandle< Object > options_in)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSCollator > collator)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSDateTimeFormat > UnwrapDateTimeFormat(Isolate *isolate, Handle< JSReceiver > format_holder)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > DateTimeFormat(Isolate *isolate, DirectHandle< JSDateTimeFormat > date_time_format, DirectHandle< Object > date, const char *method_name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSDateTimeFormat > date_time_format)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > FormatToParts(Isolate *isolate, DirectHandle< JSDateTimeFormat > date_time_format, DirectHandle< Object > x, bool output_source, const char *method_name)
static MaybeDirectHandle< Object > Of(Isolate *isolate, DirectHandle< JSDisplayNames > holder, Handle< Object > code_obj)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSDisplayNames > format_holder)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > FormatToParts(Isolate *isolate, DirectHandle< JSDurationFormat > df, Handle< Object > duration)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > Format(Isolate *isolate, DirectHandle< JSDurationFormat > df, Handle< Object > duration)
static V8_WARN_UNUSED_RESULT DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSDurationFormat > format_holder)
static V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT MaybeHandle< Map > GetDerivedMap(Isolate *isolate, DirectHandle< JSFunction > constructor, DirectHandle< JSReceiver > new_target)
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSListFormat > format_holder)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static DirectHandle< String > BaseName(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:800
static DirectHandle< Object > Region(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:792
static DirectHandle< Object > HourCycle(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:827
static DirectHandle< Object > Calendar(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:808
static MaybeDirectHandle< JSLocale > Maximize(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:434
static DirectHandle< Object > Language(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:773
static DirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:852
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSObject > GetTextInfo(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:683
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetTimeZones(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:644
static DirectHandle< Object > NumberingSystem(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:842
static MaybeDirectHandle< JSLocale > New(Isolate *isolate, DirectHandle< Map > map, DirectHandle< String > locale, DirectHandle< JSReceiver > options)
Definition js-locale.cc:370
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetNumberingSystems(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:614
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSObject > GetWeekInfo(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:712
static DirectHandle< Object > Script(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:784
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetCalendars(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:538
static MaybeDirectHandle< JSLocale > Minimize(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:468
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetHourCycles(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:557
static DirectHandle< Object > FirstDayOfWeek(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:823
static DirectHandle< Object > Collation(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:818
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetCollations(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:549
static DirectHandle< Object > CaseFirst(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:813
static DirectHandle< Object > Numeric(Isolate *isolate, DirectHandle< JSLocale > locale)
Definition js-locale.cc:832
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > NumberFormatFunction(Isolate *isolate, DirectHandle< JSNumberFormat > number_format, Handle< Object > numeric_obj)
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSNumberFormat > number_format)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSNumberFormat > UnwrapNumberFormat(Isolate *isolate, DirectHandle< JSReceiver > format_holder)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > FormatToParts(Isolate *isolate, DirectHandle< JSNumberFormat > number_format, Handle< Object > numeric_obj)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ResolvePlural(Isolate *isolate, DirectHandle< JSPluralRules > plural_rules, double number)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ResolvePluralRange(Isolate *isolate, DirectHandle< JSPluralRules > plural_rules, double x, double y)
static DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSPluralRules > plural_rules)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT Maybe< bool > DefineOwnProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Object > key, PropertyDescriptor *desc, Maybe< ShouldThrow > should_throw)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > FormatToParts(Isolate *isolate, Handle< Object > value_obj, Handle< Object > unit_obj, DirectHandle< JSRelativeTimeFormat > format)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > Format(Isolate *isolate, Handle< Object > value_obj, Handle< Object > unit_obj, DirectHandle< JSRelativeTimeFormat > format)
static V8_WARN_UNUSED_RESULT DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSRelativeTimeFormat > format_holder)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > Next(Isolate *isolate, DirectHandle< JSSegmentIterator > segment_iterator_holder)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSSegmentIterator > Create(Isolate *isolate, DirectHandle< String > input_string, icu::BreakIterator *icu_break_iterator, JSSegmenter::Granularity granularity)
static V8_EXPORT_PRIVATE const std::set< std::string > & GetAvailableLocales()
static V8_WARN_UNUSED_RESULT DirectHandle< JSObject > ResolvedOptions(Isolate *isolate, DirectHandle< JSSegmenter > segmenter_holder)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > Containing(Isolate *isolate, DirectHandle< JSSegments > segments_holder, double n)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSSegments > Create(Isolate *isolate, DirectHandle< JSSegmenter > segmenter, DirectHandle< String > string)
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 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 V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType ToString(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToNumber(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > OrdinaryHasInstance(Isolate *isolate, DirectHandle< JSAny > callable, DirectHandle< JSAny > object)
Definition objects.cc:1045
static V8_EXPORT_PRIVATE bool BooleanValue(Tagged< Object > obj, IsolateT *isolate)
static double NumberValue(Tagged< Number > obj)
static V8_WARN_UNUSED_RESULT Maybe< double > IntegerValue(Isolate *isolate, HandleType< T > input)
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
int start
Handle< SharedFunctionInfo > info
int end
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:284
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
Definition isolate.h:294
#define MAYBE_RETURN(call, value)
Definition isolate.h:408
#define RETURN_RESULT_OR_FAILURE(isolate, call)
Definition isolate.h:264
#define MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:448
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
DirectHandle< Object > new_target
Definition execution.cc:75
Isolate * isolate
TNode< Context > context
TNode< Object > receiver
std::map< const std::string, const std::string > map
double second
DateRecord date
ZoneVector< RpoNumber > & result
int x
int n
Definition mul-fft.cc:296
V8_WARN_UNUSED_RESULT Tagged< Object > DateTimeFormatRange(BuiltinArguments args, Isolate *isolate, const char *const method_name)
bool IsNaN(Tagged< Object > obj)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
constexpr AdaptArguments kAdapt
Definition globals.h:2775
MaybeDirectHandle< JSReceiver > CoerceOptionsToObject(Isolate *isolate, DirectHandle< Object > options, const char *method_name)
bool IsFastLocale(Tagged< Object > maybe_locale)
V8_EXPORT_PRIVATE void V8_EXPORT_PRIVATE void const char * format
Definition utils.h:715
template const char * string
V8_WARN_UNUSED_RESULT Tagged< Object > NumberFormatRange(BuiltinArguments args, Isolate *isolate, const char *const method_name)
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
Maybe< T > Just(const T &t)
Definition v8-maybe.h:117
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NOT_NULL(val)
#define DCHECK(condition)
Definition logging.h:482
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671