LCOV - code coverage report
Current view: top level - src/builtins - builtins-intl.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 348 364 95.6 %
Date: 2019-04-17 Functions: 151 229 65.9 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_INTL_SUPPORT
       6             : #error Internationalization is expected to be enabled.
       7             : #endif  // V8_INTL_SUPPORT
       8             : 
       9             : #include <cmath>
      10             : #include <list>
      11             : #include <memory>
      12             : 
      13             : #include "src/builtins/builtins-utils-inl.h"
      14             : #include "src/builtins/builtins.h"
      15             : #include "src/counters.h"
      16             : #include "src/date.h"
      17             : #include "src/elements.h"
      18             : #include "src/objects-inl.h"
      19             : #include "src/objects/intl-objects.h"
      20             : #include "src/objects/js-array-inl.h"
      21             : #include "src/objects/js-break-iterator-inl.h"
      22             : #include "src/objects/js-collator-inl.h"
      23             : #include "src/objects/js-date-time-format-inl.h"
      24             : #include "src/objects/js-list-format-inl.h"
      25             : #include "src/objects/js-locale-inl.h"
      26             : #include "src/objects/js-number-format-inl.h"
      27             : #include "src/objects/js-plural-rules-inl.h"
      28             : #include "src/objects/js-relative-time-format-inl.h"
      29             : #include "src/objects/js-segment-iterator-inl.h"
      30             : #include "src/objects/js-segmenter-inl.h"
      31             : #include "src/objects/smi.h"
      32             : #include "src/property-descriptor.h"
      33             : 
      34             : #include "unicode/brkiter.h"
      35             : 
      36             : namespace v8 {
      37             : namespace internal {
      38             : 
      39       24785 : BUILTIN(StringPrototypeToUpperCaseIntl) {
      40             :   HandleScope scope(isolate);
      41       10238 :   TO_THIS_STRING(string, "String.prototype.toUpperCase");
      42        4795 :   string = String::Flatten(isolate, string);
      43        9590 :   RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string));
      44             : }
      45             : 
      46       11700 : BUILTIN(StringPrototypeNormalizeIntl) {
      47             :   HandleScope handle_scope(isolate);
      48        2340 :   isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringNormalize);
      49        4680 :   TO_THIS_STRING(string, "String.prototype.normalize");
      50             : 
      51        2340 :   Handle<Object> form_input = args.atOrUndefined(isolate, 1);
      52             : 
      53        4779 :   RETURN_RESULT_OR_FAILURE(isolate,
      54             :                            Intl::Normalize(isolate, string, form_input));
      55             : }
      56             : 
      57           0 : BUILTIN(V8BreakIteratorSupportedLocalesOf) {
      58             :   HandleScope scope(isolate);
      59           0 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
      60           0 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
      61             : 
      62           0 :   RETURN_RESULT_OR_FAILURE(
      63             :       isolate, Intl::SupportedLocalesOf(
      64             :                    isolate, "Intl.v8BreakIterator.supportedLocalesOf",
      65             :                    JSV8BreakIterator::GetAvailableLocales(), locales, options));
      66             : }
      67             : 
      68         630 : BUILTIN(NumberFormatSupportedLocalesOf) {
      69             :   HandleScope scope(isolate);
      70         126 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
      71         126 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
      72             : 
      73         261 :   RETURN_RESULT_OR_FAILURE(
      74             :       isolate, Intl::SupportedLocalesOf(
      75             :                    isolate, "Intl.NumberFormat.supportedLocalesOf",
      76             :                    JSNumberFormat::GetAvailableLocales(), locales, options));
      77             : }
      78             : 
      79        5670 : BUILTIN(NumberFormatPrototypeFormatToParts) {
      80             :   const char* const method = "Intl.NumberFormat.prototype.formatToParts";
      81             :   HandleScope handle_scope(isolate);
      82        1134 :   CHECK_RECEIVER(JSNumberFormat, number_format, method);
      83             : 
      84             :   Handle<Object> x;
      85        1134 :   if (args.length() >= 2) {
      86        1134 :     if (FLAG_harmony_intl_bigint) {
      87        1728 :       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      88             :           isolate, x, Object::ToNumeric(isolate, args.at(1)));
      89             :     } else {
      90         540 :       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
      91             :                                          Object::ToNumber(isolate, args.at(1)));
      92             :     }
      93             :   } else {
      94           0 :     x = isolate->factory()->nan_value();
      95             :   }
      96             : 
      97        2268 :   RETURN_RESULT_OR_FAILURE(
      98             :       isolate, JSNumberFormat::FormatToParts(isolate, number_format, x));
      99             : }
     100             : 
     101       12645 : BUILTIN(DateTimeFormatPrototypeResolvedOptions) {
     102             :   const char* const method = "Intl.DateTimeFormat.prototype.resolvedOptions";
     103             :   HandleScope scope(isolate);
     104        2529 :   CHECK_RECEIVER(JSReceiver, format_holder, method);
     105             : 
     106             :   // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
     107             :   Handle<JSDateTimeFormat> date_time_format;
     108        5058 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     109             :       isolate, date_time_format,
     110             :       JSDateTimeFormat::UnwrapDateTimeFormat(isolate, format_holder));
     111             : 
     112        5058 :   RETURN_RESULT_OR_FAILURE(
     113             :       isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_time_format));
     114             : }
     115             : 
     116         630 : BUILTIN(DateTimeFormatSupportedLocalesOf) {
     117             :   HandleScope scope(isolate);
     118         126 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     119         126 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     120             : 
     121         261 :   RETURN_RESULT_OR_FAILURE(
     122             :       isolate, Intl::SupportedLocalesOf(
     123             :                    isolate, "Intl.DateTimeFormat.supportedLocalesOf",
     124             :                    JSDateTimeFormat::GetAvailableLocales(), locales, options));
     125             : }
     126             : 
     127         990 : BUILTIN(DateTimeFormatPrototypeFormatToParts) {
     128             :   const char* const method = "Intl.DateTimeFormat.prototype.formatToParts";
     129             :   HandleScope handle_scope(isolate);
     130         225 :   CHECK_RECEIVER(JSObject, date_format_holder, method);
     131             :   Factory* factory = isolate->factory();
     132             : 
     133         189 :   if (!date_format_holder->IsJSDateTimeFormat()) {
     134          27 :     THROW_NEW_ERROR_RETURN_FAILURE(
     135             :         isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
     136             :                               factory->NewStringFromAsciiChecked(method),
     137             :                               date_format_holder));
     138             :   }
     139             :   Handle<JSDateTimeFormat> dtf =
     140         180 :       Handle<JSDateTimeFormat>::cast(date_format_holder);
     141             : 
     142             :   Handle<Object> x = args.atOrUndefined(isolate, 1);
     143         180 :   if (x->IsUndefined(isolate)) {
     144          18 :     x = factory->NewNumber(JSDate::CurrentTimeValue(isolate));
     145             :   } else {
     146         324 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
     147             :                                        Object::ToNumber(isolate, args.at(1)));
     148             :   }
     149             : 
     150         180 :   double date_value = DateCache::TimeClip(x->Number());
     151         180 :   if (std::isnan(date_value)) {
     152          54 :     THROW_NEW_ERROR_RETURN_FAILURE(
     153             :         isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
     154             :   }
     155             : 
     156         306 :   RETURN_RESULT_OR_FAILURE(
     157             :       isolate, JSDateTimeFormat::FormatToParts(isolate, dtf, date_value));
     158             : }
     159             : 
     160             : // Common code for DateTimeFormatPrototypeFormtRange(|ToParts)
     161             : template <class T>
     162         261 : V8_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         261 :   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         261 :   if (!date_format_holder->IsJSDateTimeFormat()) {
     175           0 :     THROW_NEW_ERROR_RETURN_FAILURE(
     176             :         isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
     177             :                               factory->NewStringFromAsciiChecked(method),
     178             :                               date_format_holder));
     179             :   }
     180             :   Handle<JSDateTimeFormat> dtf =
     181         261 :       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         486 :   if (start_date->IsUndefined(isolate) || end_date->IsUndefined(isolate)) {
     188         144 :     THROW_NEW_ERROR_RETURN_FAILURE(
     189             :         isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
     190             :   }
     191             :   // 5. Let x be ? ToNumber(startDate).
     192         378 :   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         387 :   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         180 :   if (x > y) {
     202          36 :     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         360 :   RETURN_RESULT_OR_FAILURE(isolate, format(isolate, dtf, x, y));
     210             : }
     211             : 
     212         945 : BUILTIN(DateTimeFormatPrototypeFormatRange) {
     213             :   const char* const method = "Intl.DateTimeFormat.prototype.formatRange";
     214             :   HandleScope handle_scope(isolate);
     215             :   return DateTimeFormatRange<String>(args, isolate, method,
     216         378 :                                      JSDateTimeFormat::FormatRange);
     217             : }
     218             : 
     219         360 : BUILTIN(DateTimeFormatPrototypeFormatRangeToParts) {
     220             :   const char* const method = "Intl.DateTimeFormat.prototype.formatRangeToParts";
     221             :   HandleScope handle_scope(isolate);
     222             :   return DateTimeFormatRange<JSArray>(args, isolate, method,
     223         144 :                                       JSDateTimeFormat::FormatRangeToParts);
     224             : }
     225             : 
     226             : namespace {
     227        1284 : Handle<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        1284 :       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        1284 :           isolate->factory()->empty_string(), builtin_id, kNormalFunction);
     242             :   info->set_internal_formal_parameter_count(len);
     243             :   info->set_length(len);
     244             : 
     245        1284 :   Handle<Map> map = isolate->strict_function_without_prototype_map();
     246             : 
     247             :   Handle<JSFunction> new_bound_function =
     248        1284 :       isolate->factory()->NewFunctionFromSharedFunctionInfo(map, info, context);
     249        1284 :   return new_bound_function;
     250             : }
     251             : 
     252             : /**
     253             :  * Common code shared between DateTimeFormatConstructor and
     254             :  * NumberFormatConstrutor
     255             :  */
     256             : template <class T>
     257        5301 : Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
     258             :                                v8::Isolate::UseCounterFeature feature,
     259             :                                Handle<Object> constructor, const char* method) {
     260        5301 :   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        5301 :   if (args.new_target()->IsUndefined(isolate)) {
     265        1008 :     new_target = args.target();
     266             :   } else {
     267        4293 :     new_target = Handle<JSReceiver>::cast(args.new_target());
     268             :   }
     269             : 
     270             :   // [[Construct]]
     271        5301 :   Handle<JSFunction> target = args.target();
     272             : 
     273        5301 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     274        5301 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     275             : 
     276             :   // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget,
     277             :   // "%<T>Prototype%", ...).
     278             : 
     279             :   Handle<JSObject> obj;
     280       10602 :   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       11160 :   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        9486 :   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        4743 :   bool is_instance_of = is_instance_of_obj->BooleanValue(isolate);
     303             : 
     304        4743 :   if (args.new_target()->IsUndefined(isolate) && is_instance_of) {
     305          72 :     if (!receiver->IsJSReceiver()) {
     306          54 :       THROW_NEW_ERROR_RETURN_FAILURE(
     307             :           isolate,
     308             :           NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
     309             :                        isolate->factory()->NewStringFromAsciiChecked(method),
     310             :                        receiver));
     311             :     }
     312          54 :     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          54 :     Maybe<bool> success = JSReceiver::DefineOwnProperty(
     322             :         isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc,
     323          54 :         Just(kThrowOnError));
     324          72 :     MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
     325          36 :     CHECK(success.FromJust());
     326             :     // b. b. Return this.
     327             :     return *receiver;
     328             :   }
     329             :   // 6. Return format.
     330        4671 :   return *format;
     331             : }
     332             : 
     333             : /**
     334             :  * Common code shared by ListFormat, RelativeTimeFormat, PluralRules, and
     335             :  * Segmenter
     336             :  */
     337             : template <class T>
     338        2574 : Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
     339             :                                v8::Isolate::UseCounterFeature feature,
     340             :                                const char* method) {
     341        2574 :   isolate->CountUsage(feature);
     342             : 
     343             :   // 1. If NewTarget is undefined, throw a TypeError exception.
     344        2574 :   if (args.new_target()->IsUndefined(isolate)) {  // [[Call]]
     345         324 :     THROW_NEW_ERROR_RETURN_FAILURE(
     346             :         isolate,
     347             :         NewTypeError(MessageTemplate::kConstructorNotFunction,
     348             :                      isolate->factory()->NewStringFromAsciiChecked(method)));
     349             :   }
     350             :   // [[Construct]]
     351        2466 :   Handle<JSFunction> target = args.target();
     352        2466 :   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        4932 :   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        2466 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     364        2466 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     365             : 
     366             :   // 3. Return Initialize<T>(t, locales, options).
     367        5076 :   RETURN_RESULT_OR_FAILURE(isolate,
     368             :                            T::Initialize(isolate, result, locales, options));
     369             : }
     370             : 
     371             : /**
     372             :  * Common code shared by Collator and V8BreakIterator
     373             :  */
     374             : template <class T>
     375         906 : Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) {
     376             :   Handle<JSReceiver> new_target;
     377             : 
     378         906 :   if (args.new_target()->IsUndefined(isolate)) {
     379         172 :     new_target = args.target();
     380             :   } else {
     381         734 :     new_target = Handle<JSReceiver>::cast(args.new_target());
     382             :   }
     383             : 
     384             :   // [[Construct]]
     385         906 :   Handle<JSFunction> target = args.target();
     386             : 
     387         906 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     388         906 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     389             : 
     390             :   Handle<JSObject> obj;
     391        1812 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     392             :       isolate, obj,
     393             :       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
     394         906 :   Handle<T> result = Handle<T>::cast(obj);
     395             : 
     396        1821 :   RETURN_RESULT_OR_FAILURE(isolate,
     397             :                            T::Initialize(isolate, result, locales, options));
     398             : }
     399             : }  // namespace
     400             : 
     401        8280 : BUILTIN(NumberFormatConstructor) {
     402             :   HandleScope scope(isolate);
     403             : 
     404             :   return LegacyFormatConstructor<JSNumberFormat>(
     405             :       args, isolate, v8::Isolate::UseCounterFeature::kNumberFormat,
     406        4968 :       isolate->intl_number_format_function(), "Intl.NumberFormat");
     407             : }
     408             : 
     409        3735 : BUILTIN(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         747 :   CHECK_RECEIVER(JSReceiver, number_format_holder, method);
     416             : 
     417             :   // 3. Let nf be ? UnwrapNumberFormat(nf)
     418             :   Handle<JSNumberFormat> number_format;
     419        1494 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     420             :       isolate, number_format,
     421             :       JSNumberFormat::UnwrapNumberFormat(isolate, number_format_holder));
     422             : 
     423        1494 :   return *JSNumberFormat::ResolvedOptions(isolate, number_format);
     424             : }
     425             : 
     426       11295 : BUILTIN(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        2259 :   CHECK_RECEIVER(JSReceiver, receiver, method);
     433             : 
     434             :   // 3. Let nf be ? UnwrapNumberFormat(nf).
     435             :   Handle<JSNumberFormat> number_format;
     436        4563 :   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        2214 :   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         549 :       isolate, number_format, Builtins::kNumberFormatInternalFormatNumber, 1);
     451             : 
     452             :   // 4. c. Set nf.[[BoundFormat]] to F.
     453        1098 :   number_format->set_bound_format(*new_bound_format_function);
     454             : 
     455             :   // 5. Return nf.[[BoundFormat]].
     456         549 :   return *new_bound_format_function;
     457             : }
     458             : 
     459       10980 : BUILTIN(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        2196 :   Handle<Object> value = args.atOrUndefined(isolate, 1);
     474             : 
     475             :   // 4. Let x be ? ToNumeric(value).
     476             :   Handle<Object> numeric_obj;
     477        2196 :   if (FLAG_harmony_intl_bigint) {
     478        2700 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj,
     479             :                                        Object::ToNumeric(isolate, value));
     480             :   } else {
     481        1692 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj,
     482             :                                        Object::ToNumber(isolate, value));
     483             :   }
     484             : 
     485             :   icu::NumberFormat* icu_number_format =
     486        4392 :       number_format->icu_number_format()->raw();
     487        2196 :   CHECK_NOT_NULL(icu_number_format);
     488             : 
     489        4392 :   RETURN_RESULT_OR_FAILURE(
     490             :       isolate,
     491             :       JSNumberFormat::FormatNumeric(isolate, *icu_number_format, numeric_obj));
     492             : }
     493             : 
     494       18225 : BUILTIN(DateTimeFormatConstructor) {
     495             :   HandleScope scope(isolate);
     496             : 
     497             :   return LegacyFormatConstructor<JSDateTimeFormat>(
     498             :       args, isolate, v8::Isolate::UseCounterFeature::kDateTimeFormat,
     499       10935 :       isolate->intl_date_time_format_function(), "Intl.DateTimeFormat");
     500             : }
     501             : 
     502        3195 : BUILTIN(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         639 :   CHECK_RECEIVER(JSReceiver, receiver, method);
     509             : 
     510             :   // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
     511             :   Handle<JSDateTimeFormat> format;
     512        1323 :   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         594 :   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         423 :       isolate, format, Builtins::kDateTimeFormatInternalFormat, 1);
     527             : 
     528             :   // 4.c. Set dtf.[[BoundFormat]] to F.
     529         846 :   format->set_bound_format(*new_bound_format_function);
     530             : 
     531             :   // 5. Return dtf.[[BoundFormat]].
     532         423 :   return *new_bound_format_function;
     533             : }
     534             : 
     535        2880 : BUILTIN(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         576 :   Handle<Object> date = args.atOrUndefined(isolate, 1);
     548             : 
     549        1206 :   RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::DateTimeFormat(
     550             :                                         isolate, date_format_holder, date));
     551             : }
     552             : 
     553        1845 : BUILTIN(IntlGetCanonicalLocales) {
     554             :   HandleScope scope(isolate);
     555         369 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     556             : 
     557         747 :   RETURN_RESULT_OR_FAILURE(isolate,
     558             :                            Intl::GetCanonicalLocales(isolate, locales));
     559             : }
     560             : 
     561        5220 : BUILTIN(ListFormatConstructor) {
     562             :   HandleScope scope(isolate);
     563             : 
     564             :   return DisallowCallConstructor<JSListFormat>(
     565             :       args, isolate, v8::Isolate::UseCounterFeature::kListFormat,
     566        2088 :       "Intl.ListFormat");
     567             : }
     568             : 
     569        1575 : BUILTIN(ListFormatPrototypeResolvedOptions) {
     570             :   HandleScope scope(isolate);
     571         315 :   CHECK_RECEIVER(JSListFormat, format_holder,
     572             :                  "Intl.ListFormat.prototype.resolvedOptions");
     573         630 :   return *JSListFormat::ResolvedOptions(isolate, format_holder);
     574             : }
     575             : 
     576         180 : BUILTIN(ListFormatSupportedLocalesOf) {
     577             :   HandleScope scope(isolate);
     578          36 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     579          36 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     580             : 
     581          72 :   RETURN_RESULT_OR_FAILURE(
     582             :       isolate, Intl::SupportedLocalesOf(
     583             :                    isolate, "Intl.ListFormat.supportedLocalesOf",
     584             :                    JSListFormat::GetAvailableLocales(), locales, options));
     585             : }
     586             : 
     587             : namespace {
     588             : 
     589       52983 : MaybeHandle<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      105966 :   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       53037 :   if (!tag->IsString() && !tag->IsJSReceiver()) {
     603         108 :     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       52929 :   if (tag->IsJSLocale()) {
     611             :     // a. Let tag be tag.[[Locale]].
     612           0 :     locale_string = JSLocale::ToString(isolate, Handle<JSLocale>::cast(tag));
     613             :   } else {  // 9. Else,
     614             :     // a. Let tag be ? ToString(tag).
     615      105858 :     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       52929 :   if (options->IsUndefined(isolate)) {
     622             :     // a. Let options be ! ObjectCreate(null).
     623        6957 :     options_object = isolate->factory()->NewJSObjectWithNullProto();
     624             :   } else {  // 11. Else
     625             :     // a. Let options be ? ToObject(options).
     626       91944 :     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       52929 :                               locale_string, options_object);
     632             : }
     633             : 
     634             : }  // namespace
     635             : 
     636             : // Intl.Locale implementation
     637       35910 : BUILTIN(LocaleConstructor) {
     638             :   HandleScope scope(isolate);
     639             : 
     640        7182 :   isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
     641             : 
     642        7182 :   if (args.new_target()->IsUndefined(isolate)) {  // [[Call]]
     643         108 :     THROW_NEW_ERROR_RETURN_FAILURE(
     644             :         isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
     645             :                               isolate->factory()->NewStringFromAsciiChecked(
     646             :                                   "Intl.Locale")));
     647             :   }
     648             :   // [[Construct]]
     649        7146 :   Handle<JSFunction> target = args.target();
     650        7146 :   Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
     651             : 
     652        7146 :   Handle<Object> tag = args.atOrUndefined(isolate, 1);
     653        7146 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     654             : 
     655       14454 :   RETURN_RESULT_OR_FAILURE(
     656             :       isolate, CreateLocale(isolate, target, new_target, tag, options));
     657             : }
     658             : 
     659      114525 : BUILTIN(LocalePrototypeMaximize) {
     660             :   HandleScope scope(isolate);
     661       22905 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize");
     662             :   Handle<JSFunction> constructor(
     663       68715 :       isolate->native_context()->intl_locale_function(), isolate);
     664       22905 :   Handle<String> locale_str = JSLocale::ToString(isolate, locale);
     665       91620 :   RETURN_RESULT_OR_FAILURE(
     666             :       isolate, CreateLocale(isolate, constructor, constructor,
     667             :                             JSLocale::Maximize(isolate, *locale_str),
     668             :                             isolate->factory()->NewJSObjectWithNullProto()));
     669             : }
     670             : 
     671      114660 : BUILTIN(LocalePrototypeMinimize) {
     672             :   HandleScope scope(isolate);
     673       22932 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize");
     674             :   Handle<JSFunction> constructor(
     675       68796 :       isolate->native_context()->intl_locale_function(), isolate);
     676       22932 :   Handle<String> locale_str = JSLocale::ToString(isolate, locale);
     677       91728 :   RETURN_RESULT_OR_FAILURE(
     678             :       isolate, CreateLocale(isolate, constructor, constructor,
     679             :                             JSLocale::Minimize(isolate, *locale_str),
     680             :                             isolate->factory()->NewJSObjectWithNullProto()));
     681             : }
     682             : 
     683         180 : BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
     684             :   HandleScope scope(isolate);
     685          36 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     686          36 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     687             : 
     688          72 :   RETURN_RESULT_OR_FAILURE(
     689             :       isolate,
     690             :       Intl::SupportedLocalesOf(
     691             :           isolate, "Intl.RelativeTimeFormat.supportedLocalesOf",
     692             :           JSRelativeTimeFormat::GetAvailableLocales(), locales, options));
     693             : }
     694             : 
     695       28980 : BUILTIN(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        5796 :   CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
     702             :                  "Intl.RelativeTimeFormat.prototype.format");
     703        5796 :   Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
     704        5796 :   Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
     705             : 
     706       13572 :   RETURN_RESULT_OR_FAILURE(
     707             :       isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj,
     708             :                                             format_holder));
     709             : }
     710             : 
     711        3285 : BUILTIN(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         657 :   CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
     718             :                  "Intl.RelativeTimeFormat.prototype.formatToParts");
     719         657 :   Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
     720         657 :   Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
     721        1548 :   RETURN_RESULT_OR_FAILURE(
     722             :       isolate, JSRelativeTimeFormat::FormatToParts(isolate, value_obj, unit_obj,
     723             :                                                    format_holder));
     724             : }
     725             : 
     726             : // Locale getters.
     727         180 : BUILTIN(LocalePrototypeLanguage) {
     728             :   HandleScope scope(isolate);
     729             :   // CHECK_RECEIVER will case locale_holder to JSLocale.
     730          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.language");
     731             : 
     732          36 :   return *JSLocale::Language(isolate, locale);
     733             : }
     734             : 
     735         225 : BUILTIN(LocalePrototypeScript) {
     736             :   HandleScope scope(isolate);
     737          99 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.script");
     738             : 
     739          54 :   return *JSLocale::Script(isolate, locale);
     740             : }
     741             : 
     742         180 : BUILTIN(LocalePrototypeRegion) {
     743             :   HandleScope scope(isolate);
     744          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.region");
     745             : 
     746          36 :   return *JSLocale::Region(isolate, locale);
     747             : }
     748             : 
     749         180 : BUILTIN(LocalePrototypeBaseName) {
     750             :   HandleScope scope(isolate);
     751          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.baseName");
     752             : 
     753          36 :   return *JSLocale::BaseName(isolate, locale);
     754             : }
     755             : 
     756         180 : BUILTIN(LocalePrototypeCalendar) {
     757             :   HandleScope scope(isolate);
     758          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendar");
     759             : 
     760          36 :   return *JSLocale::Calendar(isolate, locale);
     761             : }
     762             : 
     763         180 : BUILTIN(LocalePrototypeCaseFirst) {
     764             :   HandleScope scope(isolate);
     765          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.caseFirst");
     766             : 
     767          36 :   return *JSLocale::CaseFirst(isolate, locale);
     768             : }
     769             : 
     770         180 : BUILTIN(LocalePrototypeCollation) {
     771             :   HandleScope scope(isolate);
     772          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collation");
     773             : 
     774          36 :   return *JSLocale::Collation(isolate, locale);
     775             : }
     776             : 
     777         180 : BUILTIN(LocalePrototypeHourCycle) {
     778             :   HandleScope scope(isolate);
     779          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycle");
     780             : 
     781          36 :   return *JSLocale::HourCycle(isolate, locale);
     782             : }
     783             : 
     784         180 : BUILTIN(LocalePrototypeNumeric) {
     785             :   HandleScope scope(isolate);
     786          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numeric");
     787             : 
     788          36 :   return *JSLocale::Numeric(isolate, locale);
     789             : }
     790             : 
     791         180 : BUILTIN(LocalePrototypeNumberingSystem) {
     792             :   HandleScope scope(isolate);
     793          90 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystem");
     794             : 
     795          36 :   return *JSLocale::NumberingSystem(isolate, locale);
     796             : }
     797             : 
     798      370260 : BUILTIN(LocalePrototypeToString) {
     799             :   HandleScope scope(isolate);
     800       74052 :   CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.toString");
     801             : 
     802      148104 :   return *JSLocale::ToString(isolate, locale);
     803             : }
     804             : 
     805        4095 : BUILTIN(RelativeTimeFormatConstructor) {
     806             :   HandleScope scope(isolate);
     807             : 
     808             :   return DisallowCallConstructor<JSRelativeTimeFormat>(
     809             :       args, isolate, v8::Isolate::UseCounterFeature::kRelativeTimeFormat,
     810        1638 :       "Intl.RelativeTimeFormat");
     811             : }
     812             : 
     813        2565 : BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) {
     814             :   HandleScope scope(isolate);
     815         567 :   CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
     816             :                  "Intl.RelativeTimeFormat.prototype.resolvedOptions");
     817         990 :   return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder);
     818             : }
     819             : 
     820        2925 : BUILTIN(StringPrototypeToLocaleLowerCase) {
     821             :   HandleScope scope(isolate);
     822             : 
     823         585 :   isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleLowerCase);
     824             : 
     825        1494 :   TO_THIS_STRING(string, "String.prototype.toLocaleLowerCase");
     826             : 
     827         864 :   RETURN_RESULT_OR_FAILURE(
     828             :       isolate, Intl::StringLocaleConvertCase(isolate, string, false,
     829             :                                              args.atOrUndefined(isolate, 1)));
     830             : }
     831             : 
     832        2970 : BUILTIN(StringPrototypeToLocaleUpperCase) {
     833             :   HandleScope scope(isolate);
     834             : 
     835         594 :   isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleUpperCase);
     836             : 
     837        1512 :   TO_THIS_STRING(string, "String.prototype.toLocaleUpperCase");
     838             : 
     839         882 :   RETURN_RESULT_OR_FAILURE(
     840             :       isolate, Intl::StringLocaleConvertCase(isolate, string, true,
     841             :                                              args.atOrUndefined(isolate, 1)));
     842             : }
     843             : 
     844         360 : BUILTIN(PluralRulesConstructor) {
     845             :   HandleScope scope(isolate);
     846             : 
     847             :   return DisallowCallConstructor<JSPluralRules>(
     848             :       args, isolate, v8::Isolate::UseCounterFeature::kPluralRules,
     849         144 :       "Intl.PluralRules");
     850             : }
     851             : 
     852           0 : BUILTIN(PluralRulesPrototypeResolvedOptions) {
     853             :   HandleScope scope(isolate);
     854           0 :   CHECK_RECEIVER(JSPluralRules, plural_rules_holder,
     855             :                  "Intl.PluralRules.prototype.resolvedOptions");
     856           0 :   return *JSPluralRules::ResolvedOptions(isolate, plural_rules_holder);
     857             : }
     858             : 
     859        1890 : BUILTIN(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         378 :   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         756 :   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         756 :   RETURN_RESULT_OR_FAILURE(isolate, JSPluralRules::ResolvePlural(
     877             :                                         isolate, plural_rules, number_double));
     878             : }
     879             : 
     880         630 : BUILTIN(PluralRulesSupportedLocalesOf) {
     881             :   HandleScope scope(isolate);
     882         126 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     883         126 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     884             : 
     885         261 :   RETURN_RESULT_OR_FAILURE(
     886             :       isolate, Intl::SupportedLocalesOf(
     887             :                    isolate, "Intl.PluralRules.supportedLocalesOf",
     888             :                    JSPluralRules::GetAvailableLocales(), locales, options));
     889             : }
     890             : 
     891        3245 : BUILTIN(CollatorConstructor) {
     892             :   HandleScope scope(isolate);
     893             : 
     894         649 :   isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator);
     895             : 
     896        1298 :   return CallOrConstructConstructor<JSCollator>(args, isolate);
     897             : }
     898             : 
     899        2255 : BUILTIN(CollatorPrototypeResolvedOptions) {
     900             :   HandleScope scope(isolate);
     901         451 :   CHECK_RECEIVER(JSCollator, collator_holder,
     902             :                  "Intl.Collator.prototype.resolvedOptions");
     903         902 :   return *JSCollator::ResolvedOptions(isolate, collator_holder);
     904             : }
     905             : 
     906         855 : BUILTIN(CollatorSupportedLocalesOf) {
     907             :   HandleScope scope(isolate);
     908         171 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
     909         171 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
     910             : 
     911         387 :   RETURN_RESULT_OR_FAILURE(
     912             :       isolate, Intl::SupportedLocalesOf(
     913             :                    isolate, "Intl.Collator.supportedLocalesOf",
     914             :                    JSCollator::GetAvailableLocales(), locales, options));
     915             : }
     916             : 
     917       26125 : BUILTIN(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        5414 :   CHECK_RECEIVER(JSCollator, collator, method);
     926             : 
     927             :   // 4. If collator.[[BoundCompare]] is undefined, then
     928             :   Handle<Object> bound_compare(collator->bound_compare(), isolate);
     929        5162 :   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         167 :       isolate, collator, Builtins::kCollatorInternalCompare, 2);
     937             : 
     938             :   // 4.c. Set collator.[[BoundCompare]] to F.
     939         334 :   collator->set_bound_compare(*new_bound_compare_function);
     940             : 
     941             :   // 5. Return collator.[[BoundCompare]].
     942         167 :   return *new_bound_compare_function;
     943             : }
     944             : 
     945       30895 : BUILTIN(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        6179 :   Handle<Object> x = args.atOrUndefined(isolate, 1);
     959             :   // 4. If y is not provided, let y be undefined.
     960        6179 :   Handle<Object> y = args.atOrUndefined(isolate, 2);
     961             : 
     962             :   // 5. Let X be ? ToString(x).
     963             :   Handle<String> string_x;
     964       12358 :   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       12358 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_y,
     969             :                                      Object::ToString(isolate, y));
     970             : 
     971             :   // 7. Return CompareStrings(collator, X, Y).
     972       12358 :   icu::Collator* icu_collator = collator->icu_collator()->raw();
     973        6179 :   CHECK_NOT_NULL(icu_collator);
     974       12358 :   return *Intl::CompareStrings(isolate, *icu_collator, string_x, string_y);
     975             : }
     976             : 
     977             : // ecma402 #sec-segment-iterator-prototype-breakType
     978      180630 : BUILTIN(SegmentIteratorPrototypeBreakType) {
     979             :   const char* const method = "get %SegmentIteratorPrototype%.breakType";
     980             :   HandleScope scope(isolate);
     981             : 
     982       36126 :   CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
     983       72252 :   return *segment_iterator->BreakType();
     984             : }
     985             : 
     986             : // ecma402 #sec-segment-iterator-prototype-following
     987       89415 : BUILTIN(SegmentIteratorPrototypeFollowing) {
     988             :   const char* const method = "%SegmentIteratorPrototype%.following";
     989             :   HandleScope scope(isolate);
     990       18288 :   CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
     991             : 
     992       17748 :   Handle<Object> from = args.atOrUndefined(isolate, 1);
     993             : 
     994             :   Maybe<bool> success =
     995       17748 :       JSSegmentIterator::Following(isolate, segment_iterator, from);
     996       17775 :   MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
     997       35442 :   return *isolate->factory()->ToBoolean(success.FromJust());
     998             : }
     999             : 
    1000             : // ecma402 #sec-segment-iterator-prototype-next
    1001       89595 : BUILTIN(SegmentIteratorPrototypeNext) {
    1002             :   const char* const method = "%SegmentIteratorPrototype%.next";
    1003             :   HandleScope scope(isolate);
    1004       18324 :   CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
    1005             : 
    1006       35568 :   RETURN_RESULT_OR_FAILURE(isolate,
    1007             :                            JSSegmentIterator::Next(isolate, segment_iterator));
    1008             : }
    1009             : 
    1010             : // ecma402 #sec-segment-iterator-prototype-preceding
    1011       45270 : BUILTIN(SegmentIteratorPrototypePreceding) {
    1012             :   const char* const method = "%SegmentIteratorPrototype%.preceding";
    1013             :   HandleScope scope(isolate);
    1014        9459 :   CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
    1015             : 
    1016        8919 :   Handle<Object> from = args.atOrUndefined(isolate, 1);
    1017             : 
    1018             :   Maybe<bool> success =
    1019        8919 :       JSSegmentIterator::Preceding(isolate, segment_iterator, from);
    1020        8964 :   MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
    1021       17748 :   return *isolate->factory()->ToBoolean(success.FromJust());
    1022             : }
    1023             : 
    1024             : // ecma402 #sec-segment-iterator-prototype-index
    1025      504675 : BUILTIN(SegmentIteratorPrototypeIndex) {
    1026             :   const char* const method = "get %SegmentIteratorPrototype%.index";
    1027             :   HandleScope scope(isolate);
    1028             : 
    1029      100935 :   CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
    1030      201870 :   return *JSSegmentIterator::Index(isolate, segment_iterator);
    1031             : }
    1032             : 
    1033        3195 : BUILTIN(SegmenterConstructor) {
    1034             :   HandleScope scope(isolate);
    1035             : 
    1036             :   return DisallowCallConstructor<JSSegmenter>(
    1037             :       args, isolate, v8::Isolate::UseCounterFeature::kSegmenter,
    1038        1278 :       "Intl.Segmenter");
    1039             : }
    1040             : 
    1041         180 : BUILTIN(SegmenterSupportedLocalesOf) {
    1042             :   HandleScope scope(isolate);
    1043          36 :   Handle<Object> locales = args.atOrUndefined(isolate, 1);
    1044          36 :   Handle<Object> options = args.atOrUndefined(isolate, 2);
    1045             : 
    1046          72 :   RETURN_RESULT_OR_FAILURE(
    1047             :       isolate, Intl::SupportedLocalesOf(
    1048             :                    isolate, "Intl.Segmenter.supportedLocalesOf",
    1049             :                    JSSegmenter::GetAvailableLocales(), locales, options));
    1050             : }
    1051             : 
    1052         405 : BUILTIN(SegmenterPrototypeResolvedOptions) {
    1053             :   HandleScope scope(isolate);
    1054          81 :   CHECK_RECEIVER(JSSegmenter, segmenter_holder,
    1055             :                  "Intl.Segmenter.prototype.resolvedOptions");
    1056         162 :   return *JSSegmenter::ResolvedOptions(isolate, segmenter_holder);
    1057             : }
    1058             : 
    1059             : // ecma402 #sec-Intl.Segmenter.prototype.segment
    1060       13905 : BUILTIN(SegmenterPrototypeSegment) {
    1061             :   HandleScope scope(isolate);
    1062        2781 :   CHECK_RECEIVER(JSSegmenter, segmenter_holder,
    1063             :                  "Intl.Segmenter.prototype.segment");
    1064        2781 :   Handle<Object> input_text = args.atOrUndefined(isolate, 1);
    1065             :   // 3. Let string be ? ToString(string).
    1066             :   Handle<String> text;
    1067        5571 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
    1068             :                                      Object::ToString(isolate, input_text));
    1069             : 
    1070             :   // 4. Return ? CreateSegmentIterator(segment, string).
    1071        5544 :   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             : 
    1078        1285 : BUILTIN(V8BreakIteratorConstructor) {
    1079             :   HandleScope scope(isolate);
    1080             : 
    1081         514 :   return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate);
    1082             : }
    1083             : 
    1084         360 : BUILTIN(V8BreakIteratorPrototypeResolvedOptions) {
    1085             :   HandleScope scope(isolate);
    1086          72 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator,
    1087             :                  "Intl.v8BreakIterator.prototype.resolvedOptions");
    1088         144 :   return *JSV8BreakIterator::ResolvedOptions(isolate, break_iterator);
    1089             : }
    1090             : 
    1091         385 : BUILTIN(V8BreakIteratorPrototypeAdoptText) {
    1092             :   const char* const method = "get Intl.v8BreakIterator.prototype.adoptText";
    1093             :   HandleScope scope(isolate);
    1094             : 
    1095         185 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
    1096             : 
    1097             :   Handle<Object> bound_adopt_text(break_iterator->bound_adopt_text(), isolate);
    1098          41 :   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          41 :       isolate, break_iterator, Builtins::kV8BreakIteratorInternalAdoptText, 1);
    1105          82 :   break_iterator->set_bound_adopt_text(*new_bound_adopt_text_function);
    1106          41 :   return *new_bound_adopt_text_function;
    1107             : }
    1108             : 
    1109         205 : BUILTIN(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          41 :   Handle<Object> input_text = args.atOrUndefined(isolate, 1);
    1119             :   Handle<String> text;
    1120          82 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
    1121             :                                      Object::ToString(isolate, input_text));
    1122             : 
    1123          41 :   JSV8BreakIterator::AdoptText(isolate, break_iterator, text);
    1124          41 :   return ReadOnlyRoots(isolate).undefined_value();
    1125             : }
    1126             : 
    1127         360 : BUILTIN(V8BreakIteratorPrototypeFirst) {
    1128             :   const char* const method = "get Intl.v8BreakIterator.prototype.first";
    1129             :   HandleScope scope(isolate);
    1130             : 
    1131         180 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
    1132             : 
    1133             :   Handle<Object> bound_first(break_iterator->bound_first(), isolate);
    1134          36 :   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          36 :       isolate, break_iterator, Builtins::kV8BreakIteratorInternalFirst, 0);
    1141          72 :   break_iterator->set_bound_first(*new_bound_first_function);
    1142          36 :   return *new_bound_first_function;
    1143             : }
    1144             : 
    1145         180 : BUILTIN(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         108 :   return *JSV8BreakIterator::First(isolate, break_iterator);
    1155             : }
    1156             : 
    1157        2345 : BUILTIN(V8BreakIteratorPrototypeNext) {
    1158             :   const char* const method = "get Intl.v8BreakIterator.prototype.next";
    1159             :   HandleScope scope(isolate);
    1160             : 
    1161         604 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
    1162             : 
    1163             :   Handle<Object> bound_next(break_iterator->bound_next(), isolate);
    1164         424 :   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          50 :       isolate, break_iterator, Builtins::kV8BreakIteratorInternalNext, 0);
    1171         100 :   break_iterator->set_bound_next(*new_bound_next_function);
    1172          50 :   return *new_bound_next_function;
    1173             : }
    1174             : 
    1175        2075 : BUILTIN(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        1245 :   return *JSV8BreakIterator::Next(isolate, break_iterator);
    1184             : }
    1185             : 
    1186         180 : BUILTIN(V8BreakIteratorPrototypeCurrent) {
    1187             :   const char* const method = "get Intl.v8BreakIterator.prototype.current";
    1188             :   HandleScope scope(isolate);
    1189             : 
    1190         144 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
    1191             : 
    1192             :   Handle<Object> bound_current(break_iterator->bound_current(), isolate);
    1193           0 :   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           0 :       isolate, break_iterator, Builtins::kV8BreakIteratorInternalCurrent, 0);
    1200           0 :   break_iterator->set_bound_current(*new_bound_current_function);
    1201           0 :   return *new_bound_current_function;
    1202             : }
    1203             : 
    1204           0 : BUILTIN(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           0 :   return *JSV8BreakIterator::Current(isolate, break_iterator);
    1213             : }
    1214             : 
    1215        1575 : BUILTIN(V8BreakIteratorPrototypeBreakType) {
    1216             :   const char* const method = "get Intl.v8BreakIterator.prototype.breakType";
    1217             :   HandleScope scope(isolate);
    1218             : 
    1219         423 :   CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
    1220             : 
    1221             :   Handle<Object> bound_break_type(break_iterator->bound_break_type(), isolate);
    1222         279 :   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          18 :       isolate, break_iterator, Builtins::kV8BreakIteratorInternalBreakType, 0);
    1229          36 :   break_iterator->set_bound_break_type(*new_bound_break_type_function);
    1230          18 :   return *new_bound_break_type_function;
    1231             : }
    1232             : 
    1233        1395 : BUILTIN(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         558 :   return JSV8BreakIterator::BreakType(isolate, break_iterator);
    1242             : }
    1243             : 
    1244             : }  // namespace internal
    1245      121996 : }  // namespace v8

Generated by: LCOV version 1.10