%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/builtins-intl.cc |
// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_INTL_SUPPORT #error Internationalization is expected to be enabled. #endif // V8_INTL_SUPPORT #include <cmath> #include <list> #include <memory> #include "src/builtins/builtins-utils-inl.h" #include "src/builtins/builtins.h" #include "src/date/date.h" #include "src/logging/counters.h" #include "src/objects/elements.h" #include "src/objects/intl-objects.h" #include "src/objects/js-array-inl.h" #include "src/objects/js-break-iterator-inl.h" #include "src/objects/js-collator-inl.h" #include "src/objects/js-date-time-format-inl.h" #include "src/objects/js-display-names-inl.h" #include "src/objects/js-duration-format-inl.h" #include "src/objects/js-list-format-inl.h" #include "src/objects/js-locale-inl.h" #include "src/objects/js-number-format-inl.h" #include "src/objects/js-plural-rules-inl.h" #include "src/objects/js-relative-time-format-inl.h" #include "src/objects/js-segment-iterator-inl.h" #include "src/objects/js-segmenter-inl.h" #include "src/objects/js-segments-inl.h" #include "src/objects/objects-inl.h" #include "src/objects/option-utils.h" #include "src/objects/property-descriptor.h" #include "src/objects/smi.h" #include "unicode/brkiter.h" namespace v8 { namespace internal { BUILTIN(StringPrototypeToUpperCaseIntl) { HandleScope scope(isolate); TO_THIS_STRING(string, "String.prototype.toUpperCase"); string = String::Flatten(isolate, string); RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string)); } BUILTIN(StringPrototypeNormalizeIntl) { HandleScope handle_scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringNormalize); TO_THIS_STRING(string, "String.prototype.normalize"); Handle<Object> form_input = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, Intl::Normalize(isolate, string, form_input)); } BUILTIN(V8BreakIteratorSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.v8BreakIterator.supportedLocalesOf", JSV8BreakIterator::GetAvailableLocales(), locales, options)); } BUILTIN(NumberFormatSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.NumberFormat.supportedLocalesOf", JSNumberFormat::GetAvailableLocales(), locales, options)); } BUILTIN(NumberFormatPrototypeFormatToParts) { const char* const method_name = "Intl.NumberFormat.prototype.formatToParts"; HandleScope handle_scope(isolate); CHECK_RECEIVER(JSNumberFormat, number_format, method_name); Handle<Object> x; if (args.length() >= 2) { x = args.at(1); } else { x = isolate->factory()->nan_value(); } RETURN_RESULT_OR_FAILURE( isolate, JSNumberFormat::FormatToParts(isolate, number_format, x)); } BUILTIN(DateTimeFormatPrototypeResolvedOptions) { const char* const method_name = "Intl.DateTimeFormat.prototype.resolvedOptions"; HandleScope scope(isolate); CHECK_RECEIVER(JSReceiver, format_holder, method_name); // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). Handle<JSDateTimeFormat> date_time_format; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, date_time_format, JSDateTimeFormat::UnwrapDateTimeFormat(isolate, format_holder)); RETURN_RESULT_OR_FAILURE( isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_time_format)); } BUILTIN(DateTimeFormatSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.DateTimeFormat.supportedLocalesOf", JSDateTimeFormat::GetAvailableLocales(), locales, options)); } BUILTIN(DateTimeFormatPrototypeFormatToParts) { const char* const method_name = "Intl.DateTimeFormat.prototype.formatToParts"; HandleScope handle_scope(isolate); CHECK_RECEIVER(JSObject, date_format_holder, method_name); Factory* factory = isolate->factory(); if (!IsJSDateTimeFormat(*date_format_holder)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, factory->NewStringFromAsciiChecked(method_name), date_format_holder)); } Handle<JSDateTimeFormat> dtf = Handle<JSDateTimeFormat>::cast(date_format_holder); Handle<Object> x = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::FormatToParts( isolate, dtf, x, false, method_name)); } // Common code for DateTimeFormatPrototypeFormtRange(|ToParts) template <class T, MaybeHandle<T> (*F)(Isolate*, Handle<JSDateTimeFormat>, Handle<Object>, Handle<Object>, const char* const)> V8_WARN_UNUSED_RESULT Tagged<Object> DateTimeFormatRange( BuiltinArguments args, Isolate* isolate, const char* const method_name) { // 1. Let dtf be this value. // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). CHECK_RECEIVER(JSDateTimeFormat, dtf, method_name); // 3. If startDate is undefined or endDate is undefined, throw a TypeError // exception. Handle<Object> start_date = args.atOrUndefined(isolate, 1); Handle<Object> end_date = args.atOrUndefined(isolate, 2); if (IsUndefined(*start_date, isolate) || IsUndefined(*end_date, isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kInvalidTimeValue)); } // 4. Return ? FormatDateTimeRange(dtf, startDate, endDate) // OR // 4. Return ? FormatDateTimeRangeToParts(dtf, startDate, endDate). RETURN_RESULT_OR_FAILURE(isolate, F(isolate, dtf, start_date, end_date, method_name)); } BUILTIN(DateTimeFormatPrototypeFormatRange) { const char* const method_name = "Intl.DateTimeFormat.prototype.formatRange"; HandleScope handle_scope(isolate); return DateTimeFormatRange<String, JSDateTimeFormat::FormatRange>( args, isolate, method_name); } BUILTIN(DateTimeFormatPrototypeFormatRangeToParts) { const char* const method_name = "Intl.DateTimeFormat.prototype.formatRangeToParts"; HandleScope handle_scope(isolate); return DateTimeFormatRange<JSArray, JSDateTimeFormat::FormatRangeToParts>( args, isolate, method_name); } namespace { Handle<JSFunction> CreateBoundFunction(Isolate* isolate, Handle<JSObject> object, Builtin builtin, int len) { Handle<NativeContext> native_context(isolate->context()->native_context(), isolate); Handle<Context> context = isolate->factory()->NewBuiltinContext( native_context, static_cast<int>(Intl::BoundFunctionContextSlot::kLength)); context->set(static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction), *object); Handle<SharedFunctionInfo> info = isolate->factory()->NewSharedFunctionInfoForBuiltin( isolate->factory()->empty_string(), builtin, FunctionKind::kNormalFunction); info->set_internal_formal_parameter_count(JSParameterCount(len)); info->set_length(len); return Factory::JSFunctionBuilder{isolate, info, context} .set_map(isolate->strict_function_without_prototype_map()) .Build(); } /** * Common code shared between DateTimeFormatConstructor and * NumberFormatConstrutor */ template <class T> Tagged<Object> LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, v8::Isolate::UseCounterFeature feature, Handle<Object> constructor, const char* method_name) { isolate->CountUsage(feature); Handle<JSReceiver> new_target; // 1. If NewTarget is undefined, let newTarget be the active // function object, else let newTarget be NewTarget. if (IsUndefined(*args.new_target(), isolate)) { new_target = args.target(); } else { new_target = Handle<JSReceiver>::cast(args.new_target()); } // [[Construct]] Handle<JSFunction> target = args.target(); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget, // "%<T>Prototype%", ...). Handle<Map> map; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); // 3. Perform ? Initialize<T>(Format, locales, options). Handle<T> format; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, format, T::New(isolate, map, locales, options, method_name)); // 4. Let this be the this value. if (IsUndefined(*args.new_target(), isolate)) { Handle<Object> receiver = args.receiver(); // 5. If NewTarget is undefined and ? OrdinaryHasInstance(%<T>%, this) // is true, then Look up the intrinsic value that has been stored on // the context. Handle<Object> ordinary_has_instance_obj; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, ordinary_has_instance_obj, Object::OrdinaryHasInstance(isolate, constructor, receiver)); if (Object::BooleanValue(*ordinary_has_instance_obj, isolate)) { if (!IsJSReceiver(*receiver)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, isolate->factory()->NewStringFromAsciiChecked( method_name), receiver)); } Handle<JSReceiver> rec = Handle<JSReceiver>::cast(receiver); // a. Perform ? DefinePropertyOrThrow(this, // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format, // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). PropertyDescriptor desc; desc.set_value(format); desc.set_writable(false); desc.set_enumerable(false); desc.set_configurable(false); Maybe<bool> success = JSReceiver::DefineOwnProperty( isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc, Just(kThrowOnError)); MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception()); CHECK(success.FromJust()); // b. b. Return this. return *receiver; } } // 6. Return format. return *format; } /** * Common code shared by ListFormat, RelativeTimeFormat, PluralRules, and * Segmenter */ template <class T> Tagged<Object> DisallowCallConstructor(BuiltinArguments args, Isolate* isolate, v8::Isolate::UseCounterFeature feature, const char* method_name) { isolate->CountUsage(feature); // 1. If NewTarget is undefined, throw a TypeError exception. if (IsUndefined(*args.new_target(), isolate)) { // [[Call]] THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kConstructorNotFunction, isolate->factory()->NewStringFromAsciiChecked( method_name))); } // [[Construct]] Handle<JSFunction> target = args.target(); Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); Handle<Map> map; // 2. Let result be OrdinaryCreateFromConstructor(NewTarget, // "%<T>Prototype%"). ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); // 3. Return New<T>(t, locales, options). RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options)); } /** * Common code shared by Collator and V8BreakIterator */ template <class T> Tagged<Object> CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate, const char* method_name) { Handle<JSReceiver> new_target; if (IsUndefined(*args.new_target(), isolate)) { new_target = args.target(); } else { new_target = Handle<JSReceiver>::cast(args.new_target()); } // [[Construct]] Handle<JSFunction> target = args.target(); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Map> map; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options, method_name)); } } // namespace // Intl.DisplayNames BUILTIN(DisplayNamesConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSDisplayNames>( args, isolate, v8::Isolate::UseCounterFeature::kDisplayNames, "Intl.DisplayNames"); } BUILTIN(DisplayNamesPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSDisplayNames, holder, "Intl.DisplayNames.prototype.resolvedOptions"); return *JSDisplayNames::ResolvedOptions(isolate, holder); } BUILTIN(DisplayNamesSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.DisplayNames.supportedLocalesOf", JSDisplayNames::GetAvailableLocales(), locales, options)); } BUILTIN(DisplayNamesPrototypeOf) { HandleScope scope(isolate); CHECK_RECEIVER(JSDisplayNames, holder, "Intl.DisplayNames.prototype.of"); Handle<Object> code_obj = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, JSDisplayNames::Of(isolate, holder, code_obj)); } // Intl.DurationFormat BUILTIN(DurationFormatConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSDurationFormat>( args, isolate, v8::Isolate::UseCounterFeature::kDurationFormat, "Intl.DurationFormat"); } BUILTIN(DurationFormatPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSDurationFormat, holder, "Intl.DurationFormat.prototype.resolvedOptions"); return *JSDurationFormat::ResolvedOptions(isolate, holder); } BUILTIN(DurationFormatSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.DurationFormat.supportedLocalesOf", JSDurationFormat::GetAvailableLocales(), locales, options)); } BUILTIN(DurationFormatPrototypeFormat) { HandleScope scope(isolate); CHECK_RECEIVER(JSDurationFormat, holder, "Intl.DurationFormat.prototype.format"); Handle<Object> value = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, JSDurationFormat::Format(isolate, holder, value)); } BUILTIN(DurationFormatPrototypeFormatToParts) { HandleScope scope(isolate); CHECK_RECEIVER(JSDurationFormat, holder, "Intl.DurationFormat.prototype.formatToParts"); Handle<Object> value = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE( isolate, JSDurationFormat::FormatToParts(isolate, holder, value)); } // Intl.NumberFormat BUILTIN(NumberFormatConstructor) { HandleScope scope(isolate); return LegacyFormatConstructor<JSNumberFormat>( args, isolate, v8::Isolate::UseCounterFeature::kNumberFormat, isolate->intl_number_format_function(), "Intl.NumberFormat"); } BUILTIN(NumberFormatPrototypeResolvedOptions) { HandleScope scope(isolate); const char* const method_name = "Intl.NumberFormat.prototype.resolvedOptions"; // 1. Let nf be the this value. // 2. If Type(nf) is not Object, throw a TypeError exception. CHECK_RECEIVER(JSReceiver, number_format_holder, method_name); // 3. Let nf be ? UnwrapNumberFormat(nf) Handle<JSNumberFormat> number_format; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, number_format, JSNumberFormat::UnwrapNumberFormat(isolate, number_format_holder)); return *JSNumberFormat::ResolvedOptions(isolate, number_format); } BUILTIN(NumberFormatPrototypeFormatNumber) { const char* const method_name = "get Intl.NumberFormat.prototype.format"; HandleScope scope(isolate); // 1. Let nf be the this value. // 2. If Type(nf) is not Object, throw a TypeError exception. CHECK_RECEIVER(JSReceiver, receiver, method_name); // 3. Let nf be ? UnwrapNumberFormat(nf). Handle<JSNumberFormat> number_format; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, number_format, JSNumberFormat::UnwrapNumberFormat(isolate, receiver)); Handle<Object> bound_format(number_format->bound_format(), isolate); // 4. If nf.[[BoundFormat]] is undefined, then if (!IsUndefined(*bound_format, isolate)) { DCHECK(IsJSFunction(*bound_format)); // 5. Return nf.[[BoundFormat]]. return *bound_format; } Handle<JSFunction> new_bound_format_function = CreateBoundFunction( isolate, number_format, Builtin::kNumberFormatInternalFormatNumber, 1); // 4. c. Set nf.[[BoundFormat]] to F. number_format->set_bound_format(*new_bound_format_function); // 5. Return nf.[[BoundFormat]]. return *new_bound_format_function; } BUILTIN(NumberFormatInternalFormatNumber) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); // 1. Let nf be F.[[NumberFormat]]. // 2. Assert: Type(nf) is Object and nf has an // [[InitializedNumberFormat]] internal slot. Handle<JSNumberFormat> number_format = Handle<JSNumberFormat>( JSNumberFormat::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); // 3. If value is not provided, let value be undefined. Handle<Object> value = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, JSNumberFormat::NumberFormatFunction( isolate, number_format, value)); } // Common code for NumberFormatPrototypeFormtRange(|ToParts) template <class T, MaybeHandle<T> (*F)(Isolate*, Handle<JSNumberFormat>, Handle<Object>, Handle<Object>)> V8_WARN_UNUSED_RESULT Tagged<Object> NumberFormatRange( BuiltinArguments args, Isolate* isolate, const char* const method_name) { // 1. Let nf be this value. // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). CHECK_RECEIVER(JSNumberFormat, nf, method_name); Handle<Object> start = args.atOrUndefined(isolate, 1); Handle<Object> end = args.atOrUndefined(isolate, 2); Factory* factory = isolate->factory(); // 3. If start is undefined or end is undefined, throw a TypeError exception. if (IsUndefined(*start, isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kInvalid, factory->NewStringFromStaticChars("start"), start)); } if (IsUndefined(*end, isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kInvalid, factory->NewStringFromStaticChars("end"), end)); } RETURN_RESULT_OR_FAILURE(isolate, F(isolate, nf, start, end)); } BUILTIN(NumberFormatPrototypeFormatRange) { const char* const method_name = "Intl.NumberFormat.prototype.formatRange"; HandleScope handle_scope(isolate); return NumberFormatRange<String, JSNumberFormat::FormatNumericRange>( args, isolate, method_name); } BUILTIN(NumberFormatPrototypeFormatRangeToParts) { const char* const method_name = "Intl.NumberFormat.prototype.formatRangeToParts"; HandleScope handle_scope(isolate); return NumberFormatRange<JSArray, JSNumberFormat::FormatNumericRangeToParts>( args, isolate, method_name); } BUILTIN(DateTimeFormatConstructor) { HandleScope scope(isolate); return LegacyFormatConstructor<JSDateTimeFormat>( args, isolate, v8::Isolate::UseCounterFeature::kDateTimeFormat, isolate->intl_date_time_format_function(), "Intl.DateTimeFormat"); } BUILTIN(DateTimeFormatPrototypeFormat) { const char* const method_name = "get Intl.DateTimeFormat.prototype.format"; HandleScope scope(isolate); // 1. Let dtf be this value. // 2. If Type(dtf) is not Object, throw a TypeError exception. CHECK_RECEIVER(JSReceiver, receiver, method_name); // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). Handle<JSDateTimeFormat> format; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, format, JSDateTimeFormat::UnwrapDateTimeFormat(isolate, receiver)); Handle<Object> bound_format = Handle<Object>(format->bound_format(), isolate); // 4. If dtf.[[BoundFormat]] is undefined, then if (!IsUndefined(*bound_format, isolate)) { DCHECK(IsJSFunction(*bound_format)); // 5. Return dtf.[[BoundFormat]]. return *bound_format; } Handle<JSFunction> new_bound_format_function = CreateBoundFunction( isolate, format, Builtin::kDateTimeFormatInternalFormat, 1); // 4.c. Set dtf.[[BoundFormat]] to F. format->set_bound_format(*new_bound_format_function); // 5. Return dtf.[[BoundFormat]]. return *new_bound_format_function; } BUILTIN(DateTimeFormatInternalFormat) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); // 1. Let dtf be F.[[DateTimeFormat]]. // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]] // internal slot. Handle<JSDateTimeFormat> date_format_holder = Handle<JSDateTimeFormat>( JSDateTimeFormat::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); Handle<Object> date = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::DateTimeFormat( isolate, date_format_holder, date, "DateTime Format Functions")); } BUILTIN(IntlGetCanonicalLocales) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, Intl::GetCanonicalLocales(isolate, locales)); } BUILTIN(IntlSupportedValuesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); RETURN_RESULT_OR_FAILURE(isolate, Intl::SupportedValuesOf(isolate, locales)); } BUILTIN(ListFormatConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSListFormat>( args, isolate, v8::Isolate::UseCounterFeature::kListFormat, "Intl.ListFormat"); } BUILTIN(ListFormatPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSListFormat, format_holder, "Intl.ListFormat.prototype.resolvedOptions"); return *JSListFormat::ResolvedOptions(isolate, format_holder); } BUILTIN(ListFormatSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.ListFormat.supportedLocalesOf", JSListFormat::GetAvailableLocales(), locales, options)); } // Intl.Locale implementation BUILTIN(LocaleConstructor) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale); const char* method_name = "Intl.Locale"; if (IsUndefined(*args.new_target(), isolate)) { // [[Call]] THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kConstructorNotFunction, isolate->factory()->NewStringFromAsciiChecked( method_name))); } // [[Construct]] Handle<JSFunction> target = args.target(); Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target()); Handle<Object> tag = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); Handle<Map> map; // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, // %LocalePrototype%, internalSlotsList). ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); // 7. If Type(tag) is not String or Object, throw a TypeError exception. if (!IsString(*tag) && !IsJSReceiver(*tag)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty)); } Handle<String> locale_string; // 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal // slot, then if (IsJSLocale(*tag)) { // a. Let tag be tag.[[Locale]]. locale_string = JSLocale::ToString(isolate, Handle<JSLocale>::cast(tag)); } else { // 9. Else, // a. Let tag be ? ToString(tag). ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_string, Object::ToString(isolate, tag)); } // 10. Set options to ? CoerceOptionsToObject(options). Handle<JSReceiver> options_object; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, options_object, CoerceOptionsToObject(isolate, options, method_name)); RETURN_RESULT_OR_FAILURE( isolate, JSLocale::New(isolate, map, locale_string, options_object)); } BUILTIN(LocalePrototypeMaximize) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.maximize"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Maximize(isolate, locale)); } BUILTIN(LocalePrototypeMinimize) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.minimize"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::Minimize(isolate, locale)); } BUILTIN(LocalePrototypeGetCalendars) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getCalendars"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCalendars(isolate, locale)); } BUILTIN(LocalePrototypeGetCollations) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getCollations"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCollations(isolate, locale)); } BUILTIN(LocalePrototypeGetHourCycles) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getHourCycles"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetHourCycles(isolate, locale)); } BUILTIN(LocalePrototypeGetNumberingSystems) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getNumberingSystems"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetNumberingSystems(isolate, locale)); } BUILTIN(LocalePrototypeGetTextInfo) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getTextInfo"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTextInfo(isolate, locale)); } BUILTIN(LocalePrototypeGetTimeZones) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getTimeZones"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTimeZones(isolate, locale)); } BUILTIN(LocalePrototypeGetWeekInfo) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocaleInfoFunctions); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.getWeekInfo"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetWeekInfo(isolate, locale)); } BUILTIN(LocalePrototypeCalendars) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendars"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCalendars(isolate, locale)); } BUILTIN(LocalePrototypeCollations) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collations"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetCollations(isolate, locale)); } BUILTIN(LocalePrototypeHourCycles) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycles"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetHourCycles(isolate, locale)); } BUILTIN(LocalePrototypeNumberingSystems) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystems"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetNumberingSystems(isolate, locale)); } BUILTIN(LocalePrototypeTextInfo) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.textInfo"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTextInfo(isolate, locale)); } BUILTIN(LocalePrototypeTimeZones) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.timeZones"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetTimeZones(isolate, locale)); } BUILTIN(LocalePrototypeWeekInfo) { HandleScope scope(isolate); isolate->CountUsage( v8::Isolate::UseCounterFeature::kLocaleInfoObsoletedGetters); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.weekInfo"); RETURN_RESULT_OR_FAILURE(isolate, JSLocale::GetWeekInfo(isolate, locale)); } BUILTIN(RelativeTimeFormatSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.RelativeTimeFormat.supportedLocalesOf", JSRelativeTimeFormat::GetAvailableLocales(), locales, options)); } BUILTIN(RelativeTimeFormatPrototypeFormat) { HandleScope scope(isolate); // 1. Let relativeTimeFormat be the this value. // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not // have an [[InitializedRelativeTimeFormat]] internal slot whose value is // true, throw a TypeError exception. CHECK_RECEIVER(JSRelativeTimeFormat, format_holder, "Intl.RelativeTimeFormat.prototype.format"); Handle<Object> value_obj = args.atOrUndefined(isolate, 1); Handle<Object> unit_obj = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj, format_holder)); } BUILTIN(RelativeTimeFormatPrototypeFormatToParts) { HandleScope scope(isolate); // 1. Let relativeTimeFormat be the this value. // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not // have an [[InitializedRelativeTimeFormat]] internal slot whose value is // true, throw a TypeError exception. CHECK_RECEIVER(JSRelativeTimeFormat, format_holder, "Intl.RelativeTimeFormat.prototype.formatToParts"); Handle<Object> value_obj = args.atOrUndefined(isolate, 1); Handle<Object> unit_obj = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, JSRelativeTimeFormat::FormatToParts(isolate, value_obj, unit_obj, format_holder)); } // Locale getters. BUILTIN(LocalePrototypeLanguage) { HandleScope scope(isolate); // CHECK_RECEIVER will case locale_holder to JSLocale. CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.language"); return *JSLocale::Language(isolate, locale); } BUILTIN(LocalePrototypeScript) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.script"); return *JSLocale::Script(isolate, locale); } BUILTIN(LocalePrototypeRegion) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.region"); return *JSLocale::Region(isolate, locale); } BUILTIN(LocalePrototypeBaseName) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.baseName"); return *JSLocale::BaseName(isolate, locale); } BUILTIN(LocalePrototypeCalendar) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.calendar"); return *JSLocale::Calendar(isolate, locale); } BUILTIN(LocalePrototypeCaseFirst) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.caseFirst"); return *JSLocale::CaseFirst(isolate, locale); } BUILTIN(LocalePrototypeCollation) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.collation"); return *JSLocale::Collation(isolate, locale); } BUILTIN(LocalePrototypeHourCycle) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.hourCycle"); return *JSLocale::HourCycle(isolate, locale); } BUILTIN(LocalePrototypeNumeric) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numeric"); return *JSLocale::Numeric(isolate, locale); } BUILTIN(LocalePrototypeNumberingSystem) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.numberingSystem"); return *JSLocale::NumberingSystem(isolate, locale); } BUILTIN(LocalePrototypeToString) { HandleScope scope(isolate); CHECK_RECEIVER(JSLocale, locale, "Intl.Locale.prototype.toString"); return *JSLocale::ToString(isolate, locale); } BUILTIN(RelativeTimeFormatConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSRelativeTimeFormat>( args, isolate, v8::Isolate::UseCounterFeature::kRelativeTimeFormat, "Intl.RelativeTimeFormat"); } BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSRelativeTimeFormat, format_holder, "Intl.RelativeTimeFormat.prototype.resolvedOptions"); return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder); } bool IsFastLocale(Tagged<Object> maybe_locale) { DisallowGarbageCollection no_gc; if (!IsSeqOneByteString(maybe_locale)) { return false; } auto locale = SeqOneByteString::cast(maybe_locale); uint8_t* chars = locale->GetChars(no_gc); if (locale->length() < 2 || !std::isalpha(chars[0]) || !std::isalpha(chars[1])) { return false; } if (locale->length() != 2 && (locale->length() != 5 || chars[2] != '-' || !std::isalpha(chars[3]) || !std::isalpha(chars[4]))) { return false; } char first = chars[0] | 0x20; char second = chars[1] | 0x20; return (first != 'a' || second != 'z') && (first != 'e' || second != 'l') && (first != 'l' || second != 't') && (first != 't' || second != 'r'); } BUILTIN(StringPrototypeToLocaleUpperCase) { HandleScope scope(isolate); Handle<Object> maybe_locale = args.atOrUndefined(isolate, 1); TO_THIS_STRING(string, "String.prototype.toLocaleUpperCase"); if (IsUndefined(*maybe_locale) || IsFastLocale(*maybe_locale)) { string = String::Flatten(isolate, string); RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string)); } else { RETURN_RESULT_OR_FAILURE(isolate, Intl::StringLocaleConvertCase( isolate, string, true, maybe_locale)); } } BUILTIN(PluralRulesConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSPluralRules>( args, isolate, v8::Isolate::UseCounterFeature::kPluralRules, "Intl.PluralRules"); } BUILTIN(PluralRulesPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSPluralRules, plural_rules_holder, "Intl.PluralRules.prototype.resolvedOptions"); return *JSPluralRules::ResolvedOptions(isolate, plural_rules_holder); } BUILTIN(PluralRulesPrototypeSelect) { HandleScope scope(isolate); // 1. 1. Let pr be the this value. // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). CHECK_RECEIVER(JSPluralRules, plural_rules, "Intl.PluralRules.prototype.select"); // 3. Let n be ? ToNumber(value). Handle<Object> number = args.atOrUndefined(isolate, 1); ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number, Object::ToNumber(isolate, number)); double number_double = Object::Number(*number); // 4. Return ! ResolvePlural(pr, n). RETURN_RESULT_OR_FAILURE(isolate, JSPluralRules::ResolvePlural( isolate, plural_rules, number_double)); } BUILTIN(PluralRulesPrototypeSelectRange) { HandleScope scope(isolate); // 1. Let pr be the this value. // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). CHECK_RECEIVER(JSPluralRules, plural_rules, "Intl.PluralRules.prototype.selectRange"); // 3. If start is undefined or end is undefined, throw a TypeError exception. Handle<Object> start = args.atOrUndefined(isolate, 1); Handle<Object> end = args.atOrUndefined(isolate, 2); if (IsUndefined(*start)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kInvalid, isolate->factory()->startRange_string(), start)); } if (IsUndefined(*end)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kInvalid, isolate->factory()->endRange_string(), end)); } // 4. Let x be ? ToNumber(start). Handle<Object> x; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(isolate, start)); // 5. Let y be ? ToNumber(end). Handle<Object> y; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, y, Object::ToNumber(isolate, end)); // 6. Return ! ResolvePluralRange(pr, x, y). if (IsNaN(*x)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewRangeError(MessageTemplate::kInvalid, isolate->factory()->startRange_string(), x)); } if (IsNaN(*y)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewRangeError(MessageTemplate::kInvalid, isolate->factory()->endRange_string(), y)); } RETURN_RESULT_OR_FAILURE( isolate, JSPluralRules::ResolvePluralRange( isolate, plural_rules, Object::Number(*x), Object::Number(*y))); } BUILTIN(PluralRulesSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.PluralRules.supportedLocalesOf", JSPluralRules::GetAvailableLocales(), locales, options)); } BUILTIN(CollatorConstructor) { HandleScope scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator); return CallOrConstructConstructor<JSCollator>(args, isolate, "Intl.Collator"); } BUILTIN(CollatorPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSCollator, collator_holder, "Intl.Collator.prototype.resolvedOptions"); return *JSCollator::ResolvedOptions(isolate, collator_holder); } BUILTIN(CollatorSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.Collator.supportedLocalesOf", JSCollator::GetAvailableLocales(), locales, options)); } BUILTIN(CollatorPrototypeCompare) { const char* const method_name = "get Intl.Collator.prototype.compare"; HandleScope scope(isolate); // 1. Let collator be this value. // 2. If Type(collator) is not Object, throw a TypeError exception. // 3. If collator does not have an [[InitializedCollator]] internal slot, // throw a TypeError exception. CHECK_RECEIVER(JSCollator, collator, method_name); // 4. If collator.[[BoundCompare]] is undefined, then Handle<Object> bound_compare(collator->bound_compare(), isolate); if (!IsUndefined(*bound_compare, isolate)) { DCHECK(IsJSFunction(*bound_compare)); // 5. Return collator.[[BoundCompare]]. return *bound_compare; } Handle<JSFunction> new_bound_compare_function = CreateBoundFunction( isolate, collator, Builtin::kCollatorInternalCompare, 2); // 4.c. Set collator.[[BoundCompare]] to F. collator->set_bound_compare(*new_bound_compare_function); // 5. Return collator.[[BoundCompare]]. return *new_bound_compare_function; } BUILTIN(CollatorInternalCompare) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); // 1. Let collator be F.[[Collator]]. // 2. Assert: Type(collator) is Object and collator has an // [[InitializedCollator]] internal slot. Handle<JSCollator> collator = Handle<JSCollator>( JSCollator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); // 3. If x is not provided, let x be undefined. Handle<Object> x = args.atOrUndefined(isolate, 1); // 4. If y is not provided, let y be undefined. Handle<Object> y = args.atOrUndefined(isolate, 2); // 5. Let X be ? ToString(x). Handle<String> string_x; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_x, Object::ToString(isolate, x)); // 6. Let Y be ? ToString(y). Handle<String> string_y; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_y, Object::ToString(isolate, y)); // 7. Return CompareStrings(collator, X, Y). icu::Collator* icu_collator = collator->icu_collator()->raw(); CHECK_NOT_NULL(icu_collator); return Smi::FromInt( Intl::CompareStrings(isolate, *icu_collator, string_x, string_y)); } // ecma402 #sec-%segmentiteratorprototype%.next BUILTIN(SegmentIteratorPrototypeNext) { const char* const method_name = "%SegmentIterator.prototype%.next"; HandleScope scope(isolate); CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method_name); RETURN_RESULT_OR_FAILURE(isolate, JSSegmentIterator::Next(isolate, segment_iterator)); } // ecma402 #sec-intl.segmenter BUILTIN(SegmenterConstructor) { HandleScope scope(isolate); return DisallowCallConstructor<JSSegmenter>( args, isolate, v8::Isolate::UseCounterFeature::kSegmenter, "Intl.Segmenter"); } // ecma402 #sec-intl.segmenter.supportedlocalesof BUILTIN(SegmenterSupportedLocalesOf) { HandleScope scope(isolate); Handle<Object> locales = args.atOrUndefined(isolate, 1); Handle<Object> options = args.atOrUndefined(isolate, 2); RETURN_RESULT_OR_FAILURE( isolate, Intl::SupportedLocalesOf( isolate, "Intl.Segmenter.supportedLocalesOf", JSSegmenter::GetAvailableLocales(), locales, options)); } // ecma402 #sec-intl.segmenter.prototype.resolvedoptions BUILTIN(SegmenterPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSSegmenter, segmenter, "Intl.Segmenter.prototype.resolvedOptions"); return *JSSegmenter::ResolvedOptions(isolate, segmenter); } // ecma402 #sec-intl.segmenter.prototype.segment BUILTIN(SegmenterPrototypeSegment) { HandleScope scope(isolate); CHECK_RECEIVER(JSSegmenter, segmenter, "Intl.Segmenter.prototype.segment"); Handle<Object> input_text = args.atOrUndefined(isolate, 1); // 3. Let string be ? ToString(string). Handle<String> string; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, Object::ToString(isolate, input_text)); // 4. Return ? CreateSegmentsObject(segmenter, string). RETURN_RESULT_OR_FAILURE(isolate, JSSegments::Create(isolate, segmenter, string)); } // ecma402 #sec-%segmentsprototype%.containing BUILTIN(SegmentsPrototypeContaining) { const char* const method_name = "%Segments.prototype%.containing"; HandleScope scope(isolate); CHECK_RECEIVER(JSSegments, segments, method_name); Handle<Object> index = args.atOrUndefined(isolate, 1); // 6. Let n be ? ToInteger(index). ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, index, Object::ToInteger(isolate, index)); double const n = Object::Number(*index); RETURN_RESULT_OR_FAILURE(isolate, JSSegments::Containing(isolate, segments, n)); } // ecma402 #sec-%segmentsprototype%-@@iterator BUILTIN(SegmentsPrototypeIterator) { const char* const method_name = "%SegmentIsPrototype%[@@iterator]"; HandleScope scope(isolate); CHECK_RECEIVER(JSSegments, segments, method_name); RETURN_RESULT_OR_FAILURE( isolate, JSSegmentIterator::Create(isolate, segments->icu_break_iterator()->raw(), segments->granularity())); } BUILTIN(V8BreakIteratorConstructor) { HandleScope scope(isolate); return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate, "Intl.v8BreakIterator"); } BUILTIN(V8BreakIteratorPrototypeResolvedOptions) { HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, "Intl.v8BreakIterator.prototype.resolvedOptions"); return *JSV8BreakIterator::ResolvedOptions(isolate, break_iterator); } BUILTIN(V8BreakIteratorPrototypeAdoptText) { const char* const method_name = "get Intl.v8BreakIterator.prototype.adoptText"; HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name); Handle<Object> bound_adopt_text(break_iterator->bound_adopt_text(), isolate); if (!IsUndefined(*bound_adopt_text, isolate)) { DCHECK(IsJSFunction(*bound_adopt_text)); return *bound_adopt_text; } Handle<JSFunction> new_bound_adopt_text_function = CreateBoundFunction( isolate, break_iterator, Builtin::kV8BreakIteratorInternalAdoptText, 1); break_iterator->set_bound_adopt_text(*new_bound_adopt_text_function); return *new_bound_adopt_text_function; } BUILTIN(V8BreakIteratorInternalAdoptText) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>( JSV8BreakIterator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); Handle<Object> input_text = args.atOrUndefined(isolate, 1); Handle<String> text; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text, Object::ToString(isolate, input_text)); JSV8BreakIterator::AdoptText(isolate, break_iterator, text); return ReadOnlyRoots(isolate).undefined_value(); } BUILTIN(V8BreakIteratorPrototypeFirst) { const char* const method_name = "get Intl.v8BreakIterator.prototype.first"; HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name); Handle<Object> bound_first(break_iterator->bound_first(), isolate); if (!IsUndefined(*bound_first, isolate)) { DCHECK(IsJSFunction(*bound_first)); return *bound_first; } Handle<JSFunction> new_bound_first_function = CreateBoundFunction( isolate, break_iterator, Builtin::kV8BreakIteratorInternalFirst, 0); break_iterator->set_bound_first(*new_bound_first_function); return *new_bound_first_function; } BUILTIN(V8BreakIteratorInternalFirst) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>( JSV8BreakIterator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); return *JSV8BreakIterator::First(isolate, break_iterator); } BUILTIN(V8BreakIteratorPrototypeNext) { const char* const method_name = "get Intl.v8BreakIterator.prototype.next"; HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name); Handle<Object> bound_next(break_iterator->bound_next(), isolate); if (!IsUndefined(*bound_next, isolate)) { DCHECK(IsJSFunction(*bound_next)); return *bound_next; } Handle<JSFunction> new_bound_next_function = CreateBoundFunction( isolate, break_iterator, Builtin::kV8BreakIteratorInternalNext, 0); break_iterator->set_bound_next(*new_bound_next_function); return *new_bound_next_function; } BUILTIN(V8BreakIteratorInternalNext) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>( JSV8BreakIterator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); return *JSV8BreakIterator::Next(isolate, break_iterator); } BUILTIN(V8BreakIteratorPrototypeCurrent) { const char* const method_name = "get Intl.v8BreakIterator.prototype.current"; HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name); Handle<Object> bound_current(break_iterator->bound_current(), isolate); if (!IsUndefined(*bound_current, isolate)) { DCHECK(IsJSFunction(*bound_current)); return *bound_current; } Handle<JSFunction> new_bound_current_function = CreateBoundFunction( isolate, break_iterator, Builtin::kV8BreakIteratorInternalCurrent, 0); break_iterator->set_bound_current(*new_bound_current_function); return *new_bound_current_function; } BUILTIN(V8BreakIteratorInternalCurrent) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>( JSV8BreakIterator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); return *JSV8BreakIterator::Current(isolate, break_iterator); } BUILTIN(V8BreakIteratorPrototypeBreakType) { const char* const method_name = "get Intl.v8BreakIterator.prototype.breakType"; HandleScope scope(isolate); CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method_name); Handle<Object> bound_break_type(break_iterator->bound_break_type(), isolate); if (!IsUndefined(*bound_break_type, isolate)) { DCHECK(IsJSFunction(*bound_break_type)); return *bound_break_type; } Handle<JSFunction> new_bound_break_type_function = CreateBoundFunction( isolate, break_iterator, Builtin::kV8BreakIteratorInternalBreakType, 0); break_iterator->set_bound_break_type(*new_bound_break_type_function); return *new_bound_break_type_function; } BUILTIN(V8BreakIteratorInternalBreakType) { HandleScope scope(isolate); Handle<Context> context = Handle<Context>(isolate->context(), isolate); Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>( JSV8BreakIterator::cast(context->get( static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))), isolate); return JSV8BreakIterator::BreakType(isolate, break_iterator); } } // namespace internal } // namespace v8