1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 16:07:35 +00:00

LibJS: Replace GlobalObject with VM in Intl AOs [Part 1/19]

Instead of passing a GlobalObject everywhere, we will simply pass a VM,
from which we can get everything we need: common names, the current
realm, symbols, arguments, the heap, and a few other things.

In some places we already don't actually need a global object and just
do it for consistency - no more `auto& vm = global_object.vm();`!

This will eventually automatically fix the "wrong realm" issue we have
in some places where we (incorrectly) use the global object from the
allocating object, e.g. in call() / construct() implementations. When
only ever a VM is passed around, this issue can't happen :^)

I've decided to split this change into a series of patches that should
keep each commit down do a somewhat manageable size.
This commit is contained in:
Linus Groh 2022-08-20 08:25:24 +01:00
parent 999da617c5
commit f9705eb2f4
54 changed files with 317 additions and 317 deletions

View file

@ -73,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string)
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(global_object, *global_object.intl_number_format_constructor(), locales, options))); auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(global_object, *global_object.intl_number_format_constructor(), locales, options)));
// 3. Return ? FormatNumeric(numberFormat, x). // 3. Return ? FormatNumeric(numberFormat, x).
auto formatted = Intl::format_numeric(global_object, *number_format, Value(bigint)); auto formatted = Intl::format_numeric(vm, *number_format, Value(bigint));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }

View file

@ -1009,13 +1009,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string)
return js_string(vm, "Invalid Date"sv); return js_string(vm, "Invalid Date"sv);
// 3. Let options be ? ToDateTimeOptions(options, "date", "date"). // 3. Let options be ? ToDateTimeOptions(options, "date", "date").
options = Value(TRY(Intl::to_date_time_options(global_object, options, Intl::OptionRequired::Date, Intl::OptionDefaults::Date))); options = Value(TRY(Intl::to_date_time_options(vm, options, Intl::OptionRequired::Date, Intl::OptionDefaults::Date)));
// 4. Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »). // 4. Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »).
auto* date_format = TRY(construct_date_time_format(global_object, locales, options)); auto* date_format = TRY(construct_date_time_format(global_object, locales, options));
// 5. Return ? FormatDateTime(dateFormat, x). // 5. Return ? FormatDateTime(dateFormat, x).
auto formatted = TRY(Intl::format_date_time(global_object, *date_format, time)); auto formatted = TRY(Intl::format_date_time(vm, *date_format, time));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }
@ -1034,13 +1034,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string)
return js_string(vm, "Invalid Date"sv); return js_string(vm, "Invalid Date"sv);
// 3. Let options be ? ToDateTimeOptions(options, "any", "all"). // 3. Let options be ? ToDateTimeOptions(options, "any", "all").
options = Value(TRY(Intl::to_date_time_options(global_object, options, Intl::OptionRequired::Any, Intl::OptionDefaults::All))); options = Value(TRY(Intl::to_date_time_options(vm, options, Intl::OptionRequired::Any, Intl::OptionDefaults::All)));
// 4. Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »). // 4. Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »).
auto* date_format = TRY(construct_date_time_format(global_object, locales, options)); auto* date_format = TRY(construct_date_time_format(global_object, locales, options));
// 5. Return ? FormatDateTime(dateFormat, x). // 5. Return ? FormatDateTime(dateFormat, x).
auto formatted = TRY(Intl::format_date_time(global_object, *date_format, time)); auto formatted = TRY(Intl::format_date_time(vm, *date_format, time));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }
@ -1059,13 +1059,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string)
return js_string(vm, "Invalid Date"sv); return js_string(vm, "Invalid Date"sv);
// 3. Let options be ? ToDateTimeOptions(options, "time", "time"). // 3. Let options be ? ToDateTimeOptions(options, "time", "time").
options = Value(TRY(Intl::to_date_time_options(global_object, options, Intl::OptionRequired::Time, Intl::OptionDefaults::Time))); options = Value(TRY(Intl::to_date_time_options(vm, options, Intl::OptionRequired::Time, Intl::OptionDefaults::Time)));
// 4. Let timeFormat be ? Construct(%DateTimeFormat%, « locales, options »). // 4. Let timeFormat be ? Construct(%DateTimeFormat%, « locales, options »).
auto* time_format = TRY(construct_date_time_format(global_object, locales, options)); auto* time_format = TRY(construct_date_time_format(global_object, locales, options));
// 5. Return ? FormatDateTime(dateFormat, x). // 5. Return ? FormatDateTime(dateFormat, x).
auto formatted = TRY(Intl::format_date_time(global_object, *time_format, time)); auto formatted = TRY(Intl::format_date_time(vm, *time_format, time));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }

View file

@ -183,10 +183,10 @@ bool is_well_formed_unit_identifier(StringView unit_identifier)
} }
// 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist // 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_object, Value locales) ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM& vm, Value locales)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. If locales is undefined, then // 1. If locales is undefined, then
if (locales.is_undefined()) { if (locales.is_undefined()) {
@ -566,13 +566,13 @@ Vector<String> best_fit_supported_locales(Vector<String> const& requested_locale
} }
// 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-supportedlocales // 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-supportedlocales
ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<String> const& requested_locales, Value options) ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<String> const& requested_locales, Value options)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Set options to ? CoerceOptionsToObject(options). // 1. Set options to ? CoerceOptionsToObject(options).
auto* options_object = TRY(coerce_options_to_object(global_object, options)); auto* options_object = TRY(coerce_options_to_object(vm, options));
// 2. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). // 2. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
auto matcher = TRY(get_option(global_object, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv)); auto matcher = TRY(get_option(global_object, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
@ -595,9 +595,10 @@ ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<
} }
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject // 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options) ThrowCompletionOr<Object*> coerce_options_to_object(VM& vm, Value options)
{ {
auto& realm = *global_object.associated_realm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If options is undefined, then // 1. If options is undefined, then
if (options.is_undefined()) { if (options.is_undefined()) {
@ -612,8 +613,11 @@ ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object,
// NOTE: 9.2.13 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal. // NOTE: 9.2.13 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal.
// 1.2.12 GetStringOrBooleanOption ( options, property, values, trueValue, falsyValue, fallback ), https://tc39.es/proposal-intl-numberformat-v3/out/negotiation/proposed.html#sec-getstringorbooleanoption // 1.2.12 GetStringOrBooleanOption ( options, property, values, trueValue, falsyValue, fallback ), https://tc39.es/proposal-intl-numberformat-v3/out/negotiation/proposed.html#sec-getstringorbooleanoption
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback) ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM& vm, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback)
{ {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let value be ? Get(options, property). // 1. Let value be ? Get(options, property).
auto value = TRY(options.get(property)); auto value = TRY(options.get(property));
@ -645,9 +649,10 @@ ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(GlobalObject& gl
} }
// 9.2.14 DefaultNumberOption ( value, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-defaultnumberoption // 9.2.14 DefaultNumberOption ( value, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-defaultnumberoption
ThrowCompletionOr<Optional<int>> default_number_option(GlobalObject& global_object, Value value, int minimum, int maximum, Optional<int> fallback) ThrowCompletionOr<Optional<int>> default_number_option(VM& vm, Value value, int minimum, int maximum, Optional<int> fallback)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If value is undefined, return fallback. // 1. If value is undefined, return fallback.
if (value.is_undefined()) if (value.is_undefined())
@ -665,7 +670,7 @@ ThrowCompletionOr<Optional<int>> default_number_option(GlobalObject& global_obje
} }
// 9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption // 9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback ), https://tc39.es/ecma402/#sec-getnumberoption
ThrowCompletionOr<Optional<int>> get_number_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback) ThrowCompletionOr<Optional<int>> get_number_option(VM& vm, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback)
{ {
// 1. Assert: Type(options) is Object. // 1. Assert: Type(options) is Object.
@ -673,7 +678,7 @@ ThrowCompletionOr<Optional<int>> get_number_option(GlobalObject& global_object,
auto value = TRY(options.get(property)); auto value = TRY(options.get(property));
// 3. Return ? DefaultNumberOption(value, minimum, maximum, fallback). // 3. Return ? DefaultNumberOption(value, minimum, maximum, fallback).
return default_number_option(global_object, value, minimum, maximum, move(fallback)); return default_number_option(vm, value, minimum, maximum, move(fallback));
} }
// 9.2.16 PartitionPattern ( pattern ), https://tc39.es/ecma402/#sec-partitionpattern // 9.2.16 PartitionPattern ( pattern ), https://tc39.es/ecma402/#sec-partitionpattern

View file

@ -95,23 +95,23 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
String canonicalize_unicode_locale_id(Unicode::LocaleID& locale); String canonicalize_unicode_locale_id(Unicode::LocaleID& locale);
bool is_well_formed_currency_code(StringView currency); bool is_well_formed_currency_code(StringView currency);
bool is_well_formed_unit_identifier(StringView unit_identifier); bool is_well_formed_unit_identifier(StringView unit_identifier);
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject&, Value locales); ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM&, Value locales);
Optional<String> best_available_locale(StringView locale); Optional<String> best_available_locale(StringView locale);
String insert_unicode_extension_and_canonicalize(Unicode::LocaleID locale_id, Unicode::LocaleExtension extension); String insert_unicode_extension_and_canonicalize(Unicode::LocaleID locale_id, Unicode::LocaleExtension extension);
LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys); LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
Vector<String> lookup_supported_locales(Vector<String> const& requested_locales); Vector<String> lookup_supported_locales(Vector<String> const& requested_locales);
Vector<String> best_fit_supported_locales(Vector<String> const& requested_locales); Vector<String> best_fit_supported_locales(Vector<String> const& requested_locales);
ThrowCompletionOr<Array*> supported_locales(GlobalObject&, Vector<String> const& requested_locales, Value options); ThrowCompletionOr<Array*> supported_locales(VM&, Vector<String> const& requested_locales, Value options);
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options); ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback); ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM&, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback);
ThrowCompletionOr<Optional<int>> default_number_option(GlobalObject& global_object, Value value, int minimum, int maximum, Optional<int> fallback); ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
ThrowCompletionOr<Optional<int>> get_number_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback); ThrowCompletionOr<Optional<int>> get_number_option(VM&, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback);
Vector<PatternPartition> partition_pattern(StringView pattern); Vector<PatternPartition> partition_pattern(StringView pattern);
template<size_t Size> template<size_t Size>
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, StringView const (&values)[Size], StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback) ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM& vm, Object const& options, PropertyKey const& property, StringView const (&values)[Size], StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback)
{ {
return get_string_or_boolean_option(global_object, options, property, Span<StringView const> { values }, move(true_value), move(falsy_value), move(fallback)); return get_string_or_boolean_option(vm, options, property, Span<StringView const> { values }, move(true_value), move(falsy_value), move(fallback));
} }
// NOTE: ECMA-402's GetOption is being removed in favor of a shared ECMA-262 GetOption in the Temporal proposal. // NOTE: ECMA-402's GetOption is being removed in favor of a shared ECMA-262 GetOption in the Temporal proposal.

View file

@ -15,15 +15,16 @@
namespace JS::Intl { namespace JS::Intl {
// 10.1.2 InitializeCollator ( collator, locales, options ), https://tc39.es/ecma402/#sec-initializecollator // 10.1.2 InitializeCollator ( collator, locales, options ), https://tc39.es/ecma402/#sec-initializecollator
static ThrowCompletionOr<Collator*> initialize_collator(GlobalObject& global_object, Collator& collator, Value locales_value, Value options_value) static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collator, Value locales_value, Value options_value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(global_object, options_value)); auto* options = TRY(coerce_options_to_object(vm, options_value));
// 3. Let usage be ? GetOption(options, "usage", "string", « "sort", "search" », "sort"). // 3. Let usage be ? GetOption(options, "usage", "string", « "sort", "search" », "sort").
auto usage = TRY(get_option(global_object, *options, vm.names.usage, OptionType::String, { "sort"sv, "search"sv }, "sort"sv)); auto usage = TRY(get_option(global_object, *options, vm.names.usage, OptionType::String, { "sort"sv, "search"sv }, "sort"sv));
@ -177,7 +178,7 @@ ThrowCompletionOr<Object*> CollatorConstructor::construct(FunctionObject& new_ta
auto* collator = TRY(ordinary_create_from_constructor<Collator>(global_object, new_target, &GlobalObject::intl_collator_prototype)); auto* collator = TRY(ordinary_create_from_constructor<Collator>(global_object, new_target, &GlobalObject::intl_collator_prototype));
// 6. Return ? InitializeCollator(collator, locales, options). // 6. Return ? InitializeCollator(collator, locales, options).
return TRY(initialize_collator(global_object, *collator, locales, options)); return TRY(initialize_collator(vm, *collator, locales, options));
} }
// 10.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-intl.collator.supportedlocalesof // 10.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-intl.collator.supportedlocalesof
@ -189,10 +190,10 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorConstructor::supported_locales_of)
// 1. Let availableLocales be %Collator%.[[AvailableLocales]]. // 1. Let availableLocales be %Collator%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
} }

View file

@ -64,10 +64,10 @@ StringView DateTimeFormat::style_to_string(Style style)
} }
// 11.5.1 ToDateTimeOptions ( options, required, defaults ), https://tc39.es/ecma402/#sec-todatetimeoptions // 11.5.1 ToDateTimeOptions ( options, required, defaults ), https://tc39.es/ecma402/#sec-todatetimeoptions
ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Value options_value, OptionRequired required, OptionDefaults defaults) ThrowCompletionOr<Object*> to_date_time_options(VM& vm, Value options_value, OptionRequired required, OptionDefaults defaults)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options). // 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
Object* options = nullptr; Object* options = nullptr;
@ -530,10 +530,10 @@ static Optional<StringView> resolve_day_period(StringView locale, StringView cal
} }
// 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern // 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options) ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let x be TimeClip(x). // 1. Let x be TimeClip(x).
time = time_clip(time); time = time_clip(time);
@ -594,7 +594,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
} }
// 13. Let tm be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). // 13. Let tm be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]).
auto local_time = TRY(to_local_time(global_object, time, date_time_format.calendar(), date_time_format.time_zone())); auto local_time = TRY(to_local_time(vm, time, date_time_format.calendar(), date_time_format.time_zone()));
// 14. Let result be a new empty List. // 14. Let result be a new empty List.
Vector<PatternPartition> result; Vector<PatternPartition> result;
@ -619,7 +619,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
value = floor(value * pow(10, static_cast<int>(*fractional_second_digits) - 3)); value = floor(value * pow(10, static_cast<int>(*fractional_second_digits) - 3));
// iii. Let fv be FormatNumeric(nf3, v). // iii. Let fv be FormatNumeric(nf3, v).
auto formatted_value = format_numeric(global_object, *number_format3, Value(value)); auto formatted_value = format_numeric(vm, *number_format3, Value(value));
// iv. Append a new Record { [[Type]]: "fractionalSecond", [[Value]]: fv } as the last element of result. // iv. Append a new Record { [[Type]]: "fractionalSecond", [[Value]]: fv } as the last element of result.
result.append({ "fractionalSecond"sv, move(formatted_value) }); result.append({ "fractionalSecond"sv, move(formatted_value) });
@ -703,13 +703,13 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
// viii. If f is "numeric", then // viii. If f is "numeric", then
case Unicode::CalendarPatternStyle::Numeric: case Unicode::CalendarPatternStyle::Numeric:
// 1. Let fv be FormatNumeric(nf, v). // 1. Let fv be FormatNumeric(nf, v).
formatted_value = format_numeric(global_object, *number_format, Value(value)); formatted_value = format_numeric(vm, *number_format, Value(value));
break; break;
// ix. Else if f is "2-digit", then // ix. Else if f is "2-digit", then
case Unicode::CalendarPatternStyle::TwoDigit: case Unicode::CalendarPatternStyle::TwoDigit:
// 1. Let fv be FormatNumeric(nf2, v). // 1. Let fv be FormatNumeric(nf2, v).
formatted_value = format_numeric(global_object, *number_format2, Value(value)); formatted_value = format_numeric(vm, *number_format2, Value(value));
// 2. If the "length" property of fv is greater than 2, let fv be the substring of fv containing the last two characters. // 2. If the "length" property of fv is greater than 2, let fv be the substring of fv containing the last two characters.
// NOTE: The first length check here isn't enough, but lets us avoid UTF-16 transcoding when the formatted value is ASCII. // NOTE: The first length check here isn't enough, but lets us avoid UTF-16 transcoding when the formatted value is ASCII.
@ -815,23 +815,23 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
} }
// 11.5.7 PartitionDateTimePattern ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-partitiondatetimepattern // 11.5.7 PartitionDateTimePattern ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-partitiondatetimepattern
ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(VM& vm, DateTimeFormat& date_time_format, double time)
{ {
// 1. Let patternParts be PartitionPattern(dateTimeFormat.[[Pattern]]). // 1. Let patternParts be PartitionPattern(dateTimeFormat.[[Pattern]]).
auto pattern_parts = partition_pattern(date_time_format.pattern()); auto pattern_parts = partition_pattern(date_time_format.pattern());
// 2. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined). // 2. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined).
auto result = TRY(format_date_time_pattern(global_object, date_time_format, move(pattern_parts), time, nullptr)); auto result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), time, nullptr));
// 3. Return result. // 3. Return result.
return result; return result;
} }
// 11.5.8 FormatDateTime ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetime // 11.5.8 FormatDateTime ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetime
ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) ThrowCompletionOr<String> format_date_time(VM& vm, DateTimeFormat& date_time_format, double time)
{ {
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x). // 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time)); auto parts = TRY(partition_date_time_pattern(vm, date_time_format, time));
// 2. Let result be the empty String. // 2. Let result be the empty String.
StringBuilder result; StringBuilder result;
@ -847,13 +847,13 @@ ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTime
} }
// 11.5.9 FormatDateTimeToParts ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetimetoparts // 11.5.9 FormatDateTimeToParts ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetimetoparts
ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) ThrowCompletionOr<Array*> format_date_time_to_parts(VM& vm, DateTimeFormat& date_time_format, double time)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x). // 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time)); auto parts = TRY(partition_date_time_pattern(vm, date_time_format, time));
// 2. Let result be ! ArrayCreate(0). // 2. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));
@ -919,10 +919,8 @@ ThrowCompletionOr<void> for_each_range_pattern_with_source(Unicode::CalendarRang
} }
// 11.5.10 PartitionDateTimeRangePattern ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-partitiondatetimerangepattern // 11.5.10 PartitionDateTimeRangePattern ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-partitiondatetimerangepattern
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(VM& vm, DateTimeFormat& date_time_format, double start, double end)
{ {
auto& vm = global_object.vm();
// 1. Let x be TimeClip(x). // 1. Let x be TimeClip(x).
start = time_clip(start); start = time_clip(start);
@ -938,10 +936,10 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime); return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime);
// 5. Let tm1 be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). // 5. Let tm1 be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]).
auto start_local_time = TRY(to_local_time(global_object, start, date_time_format.calendar(), date_time_format.time_zone())); auto start_local_time = TRY(to_local_time(vm, start, date_time_format.calendar(), date_time_format.time_zone()));
// 6. Let tm2 be ToLocalTime(y, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). // 6. Let tm2 be ToLocalTime(y, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]).
auto end_local_time = TRY(to_local_time(global_object, end, date_time_format.calendar(), date_time_format.time_zone())); auto end_local_time = TRY(to_local_time(vm, end, date_time_format.calendar(), date_time_format.time_zone()));
// 7. Let rangePatterns be dateTimeFormat.[[RangePatterns]]. // 7. Let rangePatterns be dateTimeFormat.[[RangePatterns]].
auto range_patterns = date_time_format.range_patterns(); auto range_patterns = date_time_format.range_patterns();
@ -1069,7 +1067,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
auto pattern_parts = partition_pattern(pattern); auto pattern_parts = partition_pattern(pattern);
// c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined). // c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined).
auto raw_result = TRY(format_date_time_pattern(global_object, date_time_format, move(pattern_parts), start, nullptr)); auto raw_result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), start, nullptr));
auto result = PatternPartitionWithSource::create_from_parent_list(move(raw_result)); auto result = PatternPartitionWithSource::create_from_parent_list(move(raw_result));
// d. For each Record { [[Type]], [[Value]] } r in result, do // d. For each Record { [[Type]], [[Value]] } r in result, do
@ -1126,7 +1124,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
auto pattern_parts = partition_pattern(pattern); auto pattern_parts = partition_pattern(pattern);
// f. Let partResult be ? FormatDateTimePattern(dateTimeFormat, patternParts, z, rangePattern). // f. Let partResult be ? FormatDateTimePattern(dateTimeFormat, patternParts, z, rangePattern).
auto raw_part_result = TRY(format_date_time_pattern(global_object, date_time_format, move(pattern_parts), time, &range_pattern.value())); auto raw_part_result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), time, &range_pattern.value()));
auto part_result = PatternPartitionWithSource::create_from_parent_list(move(raw_part_result)); auto part_result = PatternPartitionWithSource::create_from_parent_list(move(raw_part_result));
// g. For each Record { [[Type]], [[Value]] } r in partResult, do // g. For each Record { [[Type]], [[Value]] } r in partResult, do
@ -1145,10 +1143,10 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
} }
// 11.5.11 FormatDateTimeRange ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerange // 11.5.11 FormatDateTimeRange ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerange
ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) ThrowCompletionOr<String> format_date_time_range(VM& vm, DateTimeFormat& date_time_format, double start, double end)
{ {
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). // 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end)); auto parts = TRY(partition_date_time_range_pattern(vm, date_time_format, start, end));
// 2. Let result be the empty String. // 2. Let result be the empty String.
StringBuilder result; StringBuilder result;
@ -1164,13 +1162,13 @@ ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, Da
} }
// 11.5.12 FormatDateTimeRangeToParts ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerangetoparts // 11.5.12 FormatDateTimeRangeToParts ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerangetoparts
ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) ThrowCompletionOr<Array*> format_date_time_range_to_parts(VM& vm, DateTimeFormat& date_time_format, double start, double end)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). // 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end)); auto parts = TRY(partition_date_time_range_pattern(vm, date_time_format, start, end));
// 2. Let result be ! ArrayCreate(0). // 2. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));
@ -1204,7 +1202,7 @@ ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_o
} }
// 11.5.13 ToLocalTime ( t, calendar, timeZone ), https://tc39.es/ecma402/#sec-tolocaltime // 11.5.13 ToLocalTime ( t, calendar, timeZone ), https://tc39.es/ecma402/#sec-tolocaltime
ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double time, StringView calendar, StringView time_zone) ThrowCompletionOr<LocalTime> to_local_time(VM& vm, double time, StringView calendar, StringView time_zone)
{ {
// 1. Assert: Type(t) is Number. // 1. Assert: Type(t) is Number.
@ -1248,7 +1246,7 @@ ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double t
// 3. Else, // 3. Else,
// a. Return a record with the fields of Column 1 of Table 7 calculated from t for the given calendar and timeZone. The calculations should use best available information about the specified calendar and timeZone, including current and historical information about time zone offsets from UTC and daylight saving time rules. // a. Return a record with the fields of Column 1 of Table 7 calculated from t for the given calendar and timeZone. The calculations should use best available information about the specified calendar and timeZone, including current and historical information about time zone offsets from UTC and daylight saving time rules.
// FIXME: Implement this when non-Gregorian calendars are supported by LibUnicode. // FIXME: Implement this when non-Gregorian calendars are supported by LibUnicode.
return global_object.vm().throw_completion<InternalError>(ErrorType::NotImplemented, "Non-Gregorian calendars"sv); return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Non-Gregorian calendars"sv);
} }
} }

View file

@ -13,7 +13,6 @@
#include <AK/Types.h> #include <AK/Types.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibJS/Runtime/Completion.h> #include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/AbstractOperations.h> #include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/Object.h>
#include <LibUnicode/DateTimeFormat.h> #include <LibUnicode/DateTimeFormat.h>
@ -180,24 +179,22 @@ struct LocalTime {
u16 millisecond { 0 }; // [[Millisecond]] u16 millisecond { 0 }; // [[Millisecond]]
}; };
ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Value options_value, OptionRequired, OptionDefaults); ThrowCompletionOr<Object*> to_date_time_options(VM&, Value options_value, OptionRequired, OptionDefaults);
Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format); Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format);
Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats); Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats);
Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats); Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats);
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options); ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM&, DateTimeFormat&, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options);
ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); ThrowCompletionOr<String> format_date_time(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); ThrowCompletionOr<Array*> format_date_time_to_parts(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); ThrowCompletionOr<String> format_date_time_range(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); ThrowCompletionOr<Array*> format_date_time_range_to_parts(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double time, StringView calendar, StringView time_zone); ThrowCompletionOr<LocalTime> to_local_time(VM&, double time, StringView calendar, StringView time_zone);
template<typename Callback> template<typename Callback>
ThrowCompletionOr<void> for_each_calendar_field(GlobalObject& global_object, Unicode::CalendarPattern& pattern, Callback&& callback) ThrowCompletionOr<void> for_each_calendar_field(VM& vm, Unicode::CalendarPattern& pattern, Callback&& callback)
{ {
auto& vm = global_object.vm();
constexpr auto narrow_short_long = AK::Array { "narrow"sv, "short"sv, "long"sv }; constexpr auto narrow_short_long = AK::Array { "narrow"sv, "short"sv, "long"sv };
constexpr auto two_digit_numeric = AK::Array { "2-digit"sv, "numeric"sv }; constexpr auto two_digit_numeric = AK::Array { "2-digit"sv, "numeric"sv };
constexpr auto two_digit_numeric_narrow_short_long = AK::Array { "2-digit"sv, "numeric"sv, "narrow"sv, "short"sv, "long"sv }; constexpr auto two_digit_numeric_narrow_short_long = AK::Array { "2-digit"sv, "numeric"sv, "narrow"sv, "short"sv, "long"sv };

View file

@ -57,7 +57,7 @@ ThrowCompletionOr<Object*> DateTimeFormatConstructor::construct(FunctionObject&
auto* date_time_format = TRY(ordinary_create_from_constructor<DateTimeFormat>(global_object, new_target, &GlobalObject::intl_date_time_format_prototype)); auto* date_time_format = TRY(ordinary_create_from_constructor<DateTimeFormat>(global_object, new_target, &GlobalObject::intl_date_time_format_prototype));
// 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options). // 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options).
TRY(initialize_date_time_format(global_object, *date_time_format, locales, options)); TRY(initialize_date_time_format(vm, *date_time_format, locales, options));
// 4. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then // 4. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// a. Let this be the this value. // a. Let this be the this value.
@ -76,22 +76,23 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %DateTimeFormat%.[[AvailableLocales]]. // 1. Let availableLocales be %DateTimeFormat%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
// 11.1.2 InitializeDateTimeFormat ( dateTimeFormat, locales, options ), https://tc39.es/ecma402/#sec-initializedatetimeformat // 11.1.2 InitializeDateTimeFormat ( dateTimeFormat, locales, options ), https://tc39.es/ecma402/#sec-initializedatetimeformat
ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& global_object, DateTimeFormat& date_time_format, Value locales_value, Value options_value) ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeFormat& date_time_format, Value locales_value, Value options_value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 2. Set options to ? ToDateTimeOptions(options, "any", "date"). // 2. Set options to ? ToDateTimeOptions(options, "any", "date").
auto* options = TRY(to_date_time_options(global_object, options_value, OptionRequired::Any, OptionDefaults::Date)); auto* options = TRY(to_date_time_options(vm, options_value, OptionRequired::Any, OptionDefaults::Date));
// 3. Let opt be a new Record. // 3. Let opt be a new Record.
LocaleOptions opt {}; LocaleOptions opt {};
@ -250,7 +251,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
PropertyKey const* explicit_format_component = nullptr; PropertyKey const* explicit_format_component = nullptr;
// 36. For each row of Table 6, except the header row, in table order, do // 36. For each row of Table 6, except the header row, in table order, do
TRY(for_each_calendar_field(global_object, format_options, [&](auto& option, auto const& property, auto const& values) -> ThrowCompletionOr<void> { TRY(for_each_calendar_field(vm, format_options, [&](auto& option, auto const& property, auto const& values) -> ThrowCompletionOr<void> {
using ValueType = typename RemoveReference<decltype(option)>::ValueType; using ValueType = typename RemoveReference<decltype(option)>::ValueType;
// a. Let prop be the name given in the Property column of the row. // a. Let prop be the name given in the Property column of the row.
@ -258,7 +259,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
// b. If prop is "fractionalSecondDigits", then // b. If prop is "fractionalSecondDigits", then
if constexpr (IsIntegral<ValueType>) { if constexpr (IsIntegral<ValueType>) {
// i. Let value be ? GetNumberOption(options, "fractionalSecondDigits", 1, 3, undefined). // i. Let value be ? GetNumberOption(options, "fractionalSecondDigits", 1, 3, undefined).
auto value = TRY(get_number_option(global_object, *options, property, 1, 3, {})); auto value = TRY(get_number_option(vm, *options, property, 1, 3, {}));
// d. Set formatOptions.[[<prop>]] to value. // d. Set formatOptions.[[<prop>]] to value.
if (value.has_value()) { if (value.has_value()) {

View file

@ -27,6 +27,6 @@ private:
JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); JS_DECLARE_NATIVE_FUNCTION(supported_locales_of);
}; };
ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& global_object, DateTimeFormat& date_time_format, Value locales_value, Value options_value); ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM&, DateTimeFormat&, Value locales_value, Value options_value);
} }

View file

@ -58,7 +58,7 @@ ThrowCompletionOr<Value> DateTimeFormatFunction::call()
} }
// 5. Return ? FormatDateTime(dtf, x). // 5. Return ? FormatDateTime(dtf, x).
auto formatted = TRY(format_date_time(global_object, m_date_time_format, date_value)); auto formatted = TRY(format_date_time(vm, m_date_time_format, date_value));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }

View file

@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts)
} }
// 5. Return ? FormatDateTimeToParts(dtf, x). // 5. Return ? FormatDateTimeToParts(dtf, x).
return TRY(format_date_time_to_parts(global_object, *date_time_format, date_value)); return TRY(format_date_time_to_parts(vm, *date_time_format, date_value));
} }
// 11.3.5 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange // 11.3.5 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange
@ -111,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range)
auto end_date_number = TRY(end_date.to_number(global_object)).as_double(); auto end_date_number = TRY(end_date.to_number(global_object)).as_double();
// 6. Return ? FormatDateTimeRange(dtf, x, y). // 6. Return ? FormatDateTimeRange(dtf, x, y).
auto formatted = TRY(format_date_time_range(global_object, *date_time_format, start_date_number, end_date_number)); auto formatted = TRY(format_date_time_range(vm, *date_time_format, start_date_number, end_date_number));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }
@ -138,7 +138,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts)
auto end_date_number = TRY(end_date.to_number(global_object)).as_double(); auto end_date_number = TRY(end_date.to_number(global_object)).as_double();
// 6. Return ? FormatDateTimeRangeToParts(dtf, x, y). // 6. Return ? FormatDateTimeRangeToParts(dtf, x, y).
return TRY(format_date_time_range_to_parts(global_object, *date_time_format, start_date_number, end_date_number)); return TRY(format_date_time_range_to_parts(vm, *date_time_format, start_date_number, end_date_number));
} }
// 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions // 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
@ -190,7 +190,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
} }
if (!date_time_format->has_date_style() && !date_time_format->has_time_style()) { if (!date_time_format->has_date_style() && !date_time_format->has_time_style()) {
MUST(for_each_calendar_field(global_object, *date_time_format, [&](auto& option, auto const& property, auto const&) -> ThrowCompletionOr<void> { MUST(for_each_calendar_field(vm, *date_time_format, [&](auto& option, auto const& property, auto const&) -> ThrowCompletionOr<void> {
using ValueType = typename RemoveReference<decltype(option)>::ValueType; using ValueType = typename RemoveReference<decltype(option)>::ValueType;
if (!option.has_value()) if (!option.has_value())

View file

@ -101,10 +101,8 @@ StringView DisplayNames::language_display_string() const
} }
// 12.5.1 CanonicalCodeForDisplayNames ( type, code ), https://tc39.es/ecma402/#sec-canonicalcodefordisplaynames // 12.5.1 CanonicalCodeForDisplayNames ( type, code ), https://tc39.es/ecma402/#sec-canonicalcodefordisplaynames
ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_object, DisplayNames::Type type, StringView code) ThrowCompletionOr<Value> canonical_code_for_display_names(VM& vm, DisplayNames::Type type, StringView code)
{ {
auto& vm = global_object.vm();
// 1. If type is "language", then // 1. If type is "language", then
if (type == DisplayNames::Type::Language) { if (type == DisplayNames::Type::Language) {
// a. If code does not match the unicode_language_id production, throw a RangeError exception. // a. If code does not match the unicode_language_id production, throw a RangeError exception.

View file

@ -70,7 +70,7 @@ private:
Optional<LanguageDisplay> m_language_display {}; // [[LanguageDisplay]] Optional<LanguageDisplay> m_language_display {}; // [[LanguageDisplay]]
}; };
ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_object, DisplayNames::Type type, StringView code); ThrowCompletionOr<Value> canonical_code_for_display_names(VM&, DisplayNames::Type, StringView code);
bool is_valid_date_time_field_code(StringView field); bool is_valid_date_time_field_code(StringView field);
} }

View file

@ -56,7 +56,7 @@ ThrowCompletionOr<Object*> DisplayNamesConstructor::construct(FunctionObject& ne
auto* display_names = TRY(ordinary_create_from_constructor<DisplayNames>(global_object, new_target, &GlobalObject::intl_display_names_prototype)); auto* display_names = TRY(ordinary_create_from_constructor<DisplayNames>(global_object, new_target, &GlobalObject::intl_display_names_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locale_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));
// 4. If options is undefined, throw a TypeError exception. // 4. If options is undefined, throw a TypeError exception.
if (options_value.is_undefined()) if (options_value.is_undefined())
@ -144,10 +144,10 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesConstructor::supported_locales_of)
// No-op, availability of each requested locale is checked via Unicode::is_locale_available() // No-op, availability of each requested locale is checked via Unicode::is_locale_available()
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
} }

View file

@ -47,7 +47,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
code = js_string(vm, move(code_string)); code = js_string(vm, move(code_string));
// 4. Let code be ? CanonicalCodeForDisplayNames(displayNames.[[Type]], code). // 4. Let code be ? CanonicalCodeForDisplayNames(displayNames.[[Type]], code).
code = TRY(canonical_code_for_display_names(global_object, display_names->type(), code.as_string().string())); code = TRY(canonical_code_for_display_names(vm, display_names->type(), code.as_string().string()));
// 5. Let fields be displayNames.[[Fields]]. // 5. Let fields be displayNames.[[Fields]].
// 6. If fields has a field [[<code>]], return fields.[[<code>]]. // 6. If fields has a field [[<code>]], return fields.[[<code>]].

View file

@ -131,9 +131,10 @@ StringView DurationFormat::display_to_string(Display display)
} }
// 1.1.3 ToDurationRecord ( input ), https://tc39.es/proposal-intl-duration-format/#sec-todurationrecord // 1.1.3 ToDurationRecord ( input ), https://tc39.es/proposal-intl-duration-format/#sec-todurationrecord
ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(GlobalObject& global_object, Value input) ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(VM& vm, Value input)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If Type(input) is not Object, throw a TypeError exception. // 1. If Type(input) is not Object, throw a TypeError exception.
if (!input.is_object()) if (!input.is_object())
@ -239,9 +240,10 @@ bool is_valid_duration_record(Temporal::DurationRecord const& record)
} }
// 1.1.6 GetDurationUnitOptions ( unit, options, baseStyle, stylesList, digitalBase, prevStyle ), https://tc39.es/proposal-intl-duration-format/#sec-getdurationunitoptions // 1.1.6 GetDurationUnitOptions ( unit, options, baseStyle, stylesList, digitalBase, prevStyle ), https://tc39.es/proposal-intl-duration-format/#sec-getdurationunitoptions
ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(GlobalObject& global_object, String const& unit, Object const& options, StringView base_style, Span<StringView const> styles_list, StringView digital_base, Optional<String> const& previous_style) ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, String const& unit, Object const& options, StringView base_style, Span<StringView const> styles_list, StringView digital_base, Optional<String> const& previous_style)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let style be ? GetOption(options, unit, "string", stylesList, undefined). // 1. Let style be ? GetOption(options, unit, "string", stylesList, undefined).
auto style_value = TRY(get_option(global_object, options, unit, OptionType::String, styles_list, Empty {})); auto style_value = TRY(get_option(global_object, options, unit, OptionType::String, styles_list, Empty {}));
@ -308,10 +310,10 @@ static String convert_number_format_pattern_to_duration_format_template(Unicode:
} }
// 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern // 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(GlobalObject& global_object, DurationFormat const& duration_format, Temporal::DurationRecord const& duration) ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM& vm, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let result be a new empty List. // 1. Let result be a new empty List.
Vector<PatternPartition> result; Vector<PatternPartition> result;
@ -411,7 +413,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(Gl
// FIXME: durationFormat.[[NumberFormat]] is not a thing, the spec likely means 'nf' in this case // FIXME: durationFormat.[[NumberFormat]] is not a thing, the spec likely means 'nf' in this case
// p. Let num be ! FormatNumeric(durationFormat.[[NumberFormat]], value). // p. Let num be ! FormatNumeric(durationFormat.[[NumberFormat]], value).
auto number = format_numeric(global_object, *number_format, value); auto number = format_numeric(vm, *number_format, value);
// q. Let dataLocale be durationFormat.[[DataLocale]]. // q. Let dataLocale be durationFormat.[[DataLocale]].
auto const& data_locale = duration_format.data_locale(); auto const& data_locale = duration_format.data_locale();
@ -450,7 +452,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(Gl
auto template_ = convert_number_format_pattern_to_duration_format_template(*pattern); auto template_ = convert_number_format_pattern_to_duration_format_template(*pattern);
// FIXME: MakePartsList takes a list, not a string, so likely missing spec step: Let fv be ! PartitionNumberPattern(nf, value). // FIXME: MakePartsList takes a list, not a string, so likely missing spec step: Let fv be ! PartitionNumberPattern(nf, value).
auto formatted_value = partition_number_pattern(global_object, *number_format, value); auto formatted_value = partition_number_pattern(vm, *number_format, value);
// FIXME: Spec issue - see above, fv instead of num // FIXME: Spec issue - see above, fv instead of num
// iv. Let parts be ! MakePartsList(template, unit, num). // iv. Let parts be ! MakePartsList(template, unit, num).

View file

@ -218,10 +218,10 @@ struct DurationUnitOptions {
String display; String display;
}; };
ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(GlobalObject& global_object, Value input); ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(VM&, Value input);
i8 duration_sign(Temporal::DurationRecord const&); i8 duration_sign(Temporal::DurationRecord const&);
bool is_valid_duration_record(Temporal::DurationRecord const&); bool is_valid_duration_record(Temporal::DurationRecord const&);
ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(GlobalObject& global_object, String const& unit, Object const& options, StringView base_style, Span<StringView const> styles_list, StringView digital_base, Optional<String> const& previous_style); ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM&, String const& unit, Object const& options, StringView base_style, Span<StringView const> styles_list, StringView digital_base, Optional<String> const& previous_style);
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(GlobalObject& global_object, DurationFormat const& duration_format, Temporal::DurationRecord const& duration); ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM&, DurationFormat const&, Temporal::DurationRecord const& duration);
} }

View file

@ -53,7 +53,7 @@ ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject&
auto* duration_format = TRY(ordinary_create_from_constructor<DurationFormat>(global_object, new_target, &GlobalObject::intl_duration_format_prototype)); auto* duration_format = TRY(ordinary_create_from_constructor<DurationFormat>(global_object, new_target, &GlobalObject::intl_duration_format_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 4. Let options be ? GetOptionsObject(options). // 4. Let options be ? GetOptionsObject(options).
auto* options = TRY(Temporal::get_options_object(global_object, options_value)); auto* options = TRY(Temporal::get_options_object(global_object, options_value));
@ -119,7 +119,7 @@ ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject&
auto digital_base = duration_instances_component.digital_default; auto digital_base = duration_instances_component.digital_default;
// f. Let unitOptions be ? GetDurationUnitOptions(unit, options, style, valueList, digitalBase, prevStyle). // f. Let unitOptions be ? GetDurationUnitOptions(unit, options, style, valueList, digitalBase, prevStyle).
auto unit_options = TRY(get_duration_unit_options(global_object, unit, *options, style.as_string().string(), value_list, digital_base, previous_style)); auto unit_options = TRY(get_duration_unit_options(vm, unit, *options, style.as_string().string(), value_list, digital_base, previous_style));
// g. Set the value of the styleSlot slot of durationFormat to unitOptions.[[Style]]. // g. Set the value of the styleSlot slot of durationFormat to unitOptions.[[Style]].
(duration_format->*style_slot)(unit_options.style); (duration_format->*style_slot)(unit_options.style);
@ -135,7 +135,7 @@ ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject&
} }
// 18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined). // 18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined).
duration_format->set_fractional_digits(Optional<u8>(TRY(get_number_option(global_object, *options, vm.names.fractionalDigits, 0, 9, {})))); duration_format->set_fractional_digits(Optional<u8>(TRY(get_number_option(vm, *options, vm.names.fractionalDigits, 0, 9, {}))));
// 19. Return durationFormat. // 19. Return durationFormat.
return duration_format; return duration_format;
@ -150,10 +150,10 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %DurationFormat%.[[AvailableLocales]]. // 1. Let availableLocales be %DurationFormat%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
} }

View file

@ -39,14 +39,14 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format)
auto* duration_format = TRY(typed_this_object(global_object)); auto* duration_format = TRY(typed_this_object(global_object));
// 3. Let record be ? ToDurationRecord(duration). // 3. Let record be ? ToDurationRecord(duration).
auto record = TRY(to_duration_record(global_object, vm.argument(0))); auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception. // 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
if (!is_valid_duration_record(record)) if (!is_valid_duration_record(record))
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject); return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record). // 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record)); auto formatted = TRY(partition_duration_format_pattern(vm, *duration_format, record));
// 6. Let result be a new empty String. // 6. Let result be a new empty String.
StringBuilder result; StringBuilder result;
@ -71,14 +71,14 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
auto* duration_format = TRY(typed_this_object(global_object)); auto* duration_format = TRY(typed_this_object(global_object));
// 3. Let record be ? ToDurationRecord(duration). // 3. Let record be ? ToDurationRecord(duration).
auto record = TRY(to_duration_record(global_object, vm.argument(0))); auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception. // 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
if (!is_valid_duration_record(record)) if (!is_valid_duration_record(record))
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject); return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record). // 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record)); auto formatted = TRY(partition_duration_format_pattern(vm, *duration_format, record));
// 6. Let result be ! ArrayCreate(0). // 6. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));

View file

@ -66,7 +66,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
auto locales = vm.argument(0); auto locales = vm.argument(0);
// 1. Let ll be ? CanonicalizeLocaleList(locales). // 1. Let ll be ? CanonicalizeLocaleList(locales).
auto locale_list = TRY(canonicalize_locale_list(global_object, locales)); auto locale_list = TRY(canonicalize_locale_list(vm, locales));
MarkedVector<Value> marked_locale_list { vm.heap() }; MarkedVector<Value> marked_locale_list { vm.heap() };
marked_locale_list.ensure_capacity(locale_list.size()); marked_locale_list.ensure_capacity(locale_list.size());

View file

@ -201,10 +201,10 @@ String format_list(ListFormat const& list_format, Vector<String> const& list)
} }
// 13.5.4 FormatListToParts ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlisttoparts // 13.5.4 FormatListToParts ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlisttoparts
Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_format, Vector<String> const& list) Array* format_list_to_parts(VM& vm, ListFormat const& list_format, Vector<String> const& list)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ! CreatePartsFromList(listFormat, list). // 1. Let parts be ! CreatePartsFromList(listFormat, list).
auto parts = create_parts_from_list(list_format, list); auto parts = create_parts_from_list(list_format, list);
@ -238,9 +238,10 @@ Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_
} }
// 13.5.5 StringListFromIterable ( iterable ), https://tc39.es/ecma402/#sec-createstringlistfromiterable // 13.5.5 StringListFromIterable ( iterable ), https://tc39.es/ecma402/#sec-createstringlistfromiterable
ThrowCompletionOr<Vector<String>> string_list_from_iterable(GlobalObject& global_object, Value iterable) ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterable)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If iterable is undefined, then // 1. If iterable is undefined, then
if (iterable.is_undefined()) { if (iterable.is_undefined()) {

View file

@ -50,10 +50,10 @@ private:
using Placeables = HashMap<StringView, Variant<PatternPartition, Vector<PatternPartition>>>; using Placeables = HashMap<StringView, Variant<PatternPartition, Vector<PatternPartition>>>;
Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables placeables); Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables);
Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, Vector<String> const& list); Vector<PatternPartition> create_parts_from_list(ListFormat const&, Vector<String> const& list);
String format_list(ListFormat const& list_format, Vector<String> const& list); String format_list(ListFormat const&, Vector<String> const& list);
Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_format, Vector<String> const& list); Array* format_list_to_parts(VM&, ListFormat const&, Vector<String> const& list);
ThrowCompletionOr<Vector<String>> string_list_from_iterable(GlobalObject& global_object, Value iterable); ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM&, Value iterable);
} }

View file

@ -55,7 +55,7 @@ ThrowCompletionOr<Object*> ListFormatConstructor::construct(FunctionObject& new_
auto* list_format = TRY(ordinary_create_from_constructor<ListFormat>(global_object, new_target, &GlobalObject::intl_list_format_prototype)); auto* list_format = TRY(ordinary_create_from_constructor<ListFormat>(global_object, new_target, &GlobalObject::intl_list_format_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locale_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));
// 4. Set options to ? GetOptionsObject(options). // 4. Set options to ? GetOptionsObject(options).
auto* options = TRY(Temporal::get_options_object(global_object, options_value)); auto* options = TRY(Temporal::get_options_object(global_object, options_value));
@ -104,10 +104,10 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %ListFormat%.[[AvailableLocales]]. // 1. Let availableLocales be %ListFormat%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
} }

View file

@ -43,7 +43,7 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format)
auto* list_format = TRY(typed_this_object(global_object)); auto* list_format = TRY(typed_this_object(global_object));
// 3. Let stringList be ? StringListFromIterable(list). // 3. Let stringList be ? StringListFromIterable(list).
auto string_list = TRY(string_list_from_iterable(global_object, list)); auto string_list = TRY(string_list_from_iterable(vm, list));
// 4. Return ! FormatList(lf, stringList). // 4. Return ! FormatList(lf, stringList).
auto formatted = format_list(*list_format, string_list); auto formatted = format_list(*list_format, string_list);
@ -60,10 +60,10 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts)
auto* list_format = TRY(typed_this_object(global_object)); auto* list_format = TRY(typed_this_object(global_object));
// 3. Let stringList be ? StringListFromIterable(list). // 3. Let stringList be ? StringListFromIterable(list).
auto string_list = TRY(string_list_from_iterable(global_object, list)); auto string_list = TRY(string_list_from_iterable(vm, list));
// 4. Return ! FormatListToParts(lf, stringList). // 4. Return ! FormatListToParts(lf, stringList).
return format_list_to_parts(global_object, *list_format, string_list); return format_list_to_parts(vm, *list_format, string_list);
} }
// 13.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions // 13.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions

View file

@ -55,10 +55,9 @@ Locale::Locale(Unicode::LocaleID const& locale_id, Object& prototype)
} }
// 1.1.1 CreateArrayFromListOrRestricted ( list , restricted ) // 1.1.1 CreateArrayFromListOrRestricted ( list , restricted )
static Array* create_array_from_list_or_restricted(GlobalObject& global_object, Vector<StringView> list, Optional<String> restricted) static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> list, Optional<String> restricted)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm();
// 1. If restricted is not undefined, then // 1. If restricted is not undefined, then
if (restricted.has_value()) { if (restricted.has_value()) {
@ -73,7 +72,7 @@ static Array* create_array_from_list_or_restricted(GlobalObject& global_object,
} }
// 1.1.2 CalendarsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-calendars-of-locale // 1.1.2 CalendarsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-calendars-of-locale
Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale_object) Array* calendars_of_locale(VM& vm, Locale const& locale_object)
{ {
// 1. Let restricted be loc.[[Calendar]]. // 1. Let restricted be loc.[[Calendar]].
Optional<String> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<String> {}; Optional<String> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<String> {};
@ -88,11 +87,11 @@ Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale_obj
auto list = Unicode::get_keywords_for_locale(locale, "ca"sv); auto list = Unicode::get_keywords_for_locale(locale, "ca"sv);
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ). // 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); return create_array_from_list_or_restricted(vm, move(list), move(restricted));
} }
// 1.1.3 CollationsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-collations-of-locale // 1.1.3 CollationsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-collations-of-locale
Array* collations_of_locale(GlobalObject& global_object, Locale const& locale_object) Array* collations_of_locale(VM& vm, Locale const& locale_object)
{ {
// 1. Let restricted be loc.[[Collation]]. // 1. Let restricted be loc.[[Collation]].
Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {}; Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {};
@ -107,11 +106,11 @@ Array* collations_of_locale(GlobalObject& global_object, Locale const& locale_ob
auto list = Unicode::get_keywords_for_locale(locale, "co"sv); auto list = Unicode::get_keywords_for_locale(locale, "co"sv);
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ). // 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); return create_array_from_list_or_restricted(vm, move(list), move(restricted));
} }
// 1.1.4 HourCyclesOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-hour-cycles-of-locale // 1.1.4 HourCyclesOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-hour-cycles-of-locale
Array* hour_cycles_of_locale(GlobalObject& global_object, Locale const& locale_object) Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
{ {
// 1. Let restricted be loc.[[HourCycle]]. // 1. Let restricted be loc.[[HourCycle]].
Optional<String> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<String> {}; Optional<String> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<String> {};
@ -126,11 +125,11 @@ Array* hour_cycles_of_locale(GlobalObject& global_object, Locale const& locale_o
auto list = Unicode::get_keywords_for_locale(locale, "hc"sv); auto list = Unicode::get_keywords_for_locale(locale, "hc"sv);
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ). // 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); return create_array_from_list_or_restricted(vm, move(list), move(restricted));
} }
// 1.1.5 NumberingSystemsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-numbering-systems-of-locale // 1.1.5 NumberingSystemsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-numbering-systems-of-locale
Array* numbering_systems_of_locale(GlobalObject& global_object, Locale const& locale_object) Array* numbering_systems_of_locale(VM& vm, Locale const& locale_object)
{ {
// 1. Let restricted be loc.[[NumberingSystem]]. // 1. Let restricted be loc.[[NumberingSystem]].
Optional<String> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<String> {}; Optional<String> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<String> {};
@ -145,15 +144,14 @@ Array* numbering_systems_of_locale(GlobalObject& global_object, Locale const& lo
auto list = Unicode::get_keywords_for_locale(locale, "nu"sv); auto list = Unicode::get_keywords_for_locale(locale, "nu"sv);
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ). // 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); return create_array_from_list_or_restricted(vm, move(list), move(restricted));
} }
// 1.1.6 TimeZonesOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-time-zones-of-locale // 1.1.6 TimeZonesOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-time-zones-of-locale
// NOTE: Our implementation takes a region rather than a Locale object to avoid needlessly parsing the locale twice. // NOTE: Our implementation takes a region rather than a Locale object to avoid needlessly parsing the locale twice.
Array* time_zones_of_locale(GlobalObject& global_object, StringView region) Array* time_zones_of_locale(VM& vm, StringView region)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm();
// 1. Let locale be loc.[[Locale]]. // 1. Let locale be loc.[[Locale]].
// 2. Assert: locale matches the unicode_locale_id production. // 2. Assert: locale matches the unicode_locale_id production.

View file

@ -81,12 +81,12 @@ struct WeekInfo {
Vector<u8> weekend; // [[Weekend]] Vector<u8> weekend; // [[Weekend]]
}; };
Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale); Array* calendars_of_locale(VM&, Locale const&);
Array* collations_of_locale(GlobalObject& global_object, Locale const& locale); Array* collations_of_locale(VM&, Locale const& locale);
Array* hour_cycles_of_locale(GlobalObject& global_object, Locale const& locale); Array* hour_cycles_of_locale(VM&, Locale const& locale);
Array* numbering_systems_of_locale(GlobalObject& global_object, Locale const& locale); Array* numbering_systems_of_locale(VM&, Locale const&);
Array* time_zones_of_locale(GlobalObject& global_object, StringView region); Array* time_zones_of_locale(VM&, StringView region);
StringView character_direction_of_locale(Locale const& locale); StringView character_direction_of_locale(Locale const&);
WeekInfo week_info_of_locale(Locale const& locale); WeekInfo week_info_of_locale(Locale const&);
} }

View file

@ -26,9 +26,10 @@ struct LocaleAndKeys {
}; };
// Note: This is not an AO in the spec. This just serves to abstract very similar steps in ApplyOptionsToTag and the Intl.Locale constructor. // Note: This is not an AO in the spec. This just serves to abstract very similar steps in ApplyOptionsToTag and the Intl.Locale constructor.
static ThrowCompletionOr<Optional<String>> get_string_option(GlobalObject& global_object, Object const& options, PropertyKey const& property, Function<bool(StringView)> validator, Span<StringView const> values = {}) static ThrowCompletionOr<Optional<String>> get_string_option(VM& vm, Object const& options, PropertyKey const& property, Function<bool(StringView)> validator, Span<StringView const> values = {})
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto option = TRY(get_option(global_object, options, property, OptionType::String, values, Empty {})); auto option = TRY(get_option(global_object, options, property, OptionType::String, values, Empty {}));
if (option.is_undefined()) if (option.is_undefined())
@ -41,10 +42,8 @@ static ThrowCompletionOr<Optional<String>> get_string_option(GlobalObject& globa
} }
// 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag // 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag
static ThrowCompletionOr<String> apply_options_to_tag(GlobalObject& global_object, StringView tag, Object const& options) static ThrowCompletionOr<String> apply_options_to_tag(VM& vm, StringView tag, Object const& options)
{ {
auto& vm = global_object.vm();
// 1. Assert: Type(tag) is String. // 1. Assert: Type(tag) is String.
// 2. Assert: Type(options) is Object. // 2. Assert: Type(options) is Object.
@ -56,17 +55,17 @@ static ThrowCompletionOr<String> apply_options_to_tag(GlobalObject& global_objec
// 4. Let language be ? GetOption(options, "language", "string", undefined, undefined). // 4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
// 5. If language is not undefined, then // 5. If language is not undefined, then
// a. If language does not match the unicode_language_subtag production, throw a RangeError exception. // a. If language does not match the unicode_language_subtag production, throw a RangeError exception.
auto language = TRY(get_string_option(global_object, options, vm.names.language, Unicode::is_unicode_language_subtag)); auto language = TRY(get_string_option(vm, options, vm.names.language, Unicode::is_unicode_language_subtag));
// 6. Let script be ? GetOption(options, "script", "string", undefined, undefined). // 6. Let script be ? GetOption(options, "script", "string", undefined, undefined).
// 7. If script is not undefined, then // 7. If script is not undefined, then
// a. If script does not match the unicode_script_subtag production, throw a RangeError exception. // a. If script does not match the unicode_script_subtag production, throw a RangeError exception.
auto script = TRY(get_string_option(global_object, options, vm.names.script, Unicode::is_unicode_script_subtag)); auto script = TRY(get_string_option(vm, options, vm.names.script, Unicode::is_unicode_script_subtag));
// 8. Let region be ? GetOption(options, "region", "string", undefined, undefined). // 8. Let region be ? GetOption(options, "region", "string", undefined, undefined).
// 9. If region is not undefined, then // 9. If region is not undefined, then
// a. If region does not match the unicode_region_subtag production, throw a RangeError exception. // a. If region does not match the unicode_region_subtag production, throw a RangeError exception.
auto region = TRY(get_string_option(global_object, options, vm.names.region, Unicode::is_unicode_region_subtag)); auto region = TRY(get_string_option(vm, options, vm.names.region, Unicode::is_unicode_region_subtag));
// 10. Set tag to ! CanonicalizeUnicodeLocaleId(tag). // 10. Set tag to ! CanonicalizeUnicodeLocaleId(tag).
auto canonicalized_tag = Intl::canonicalize_unicode_locale_id(*locale_id); auto canonicalized_tag = Intl::canonicalize_unicode_locale_id(*locale_id);
@ -283,10 +282,10 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
} }
// 10. Set options to ? CoerceOptionsToObject(options). // 10. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(global_object, options_value)); auto* options = TRY(coerce_options_to_object(vm, options_value));
// 11. Set tag to ? ApplyOptionsToTag(tag, options). // 11. Set tag to ? ApplyOptionsToTag(tag, options).
tag = TRY(apply_options_to_tag(global_object, tag, *options)); tag = TRY(apply_options_to_tag(vm, tag, *options));
// 12. Let opt be a new Record. // 12. Let opt be a new Record.
LocaleAndKeys opt {}; LocaleAndKeys opt {};
@ -295,21 +294,21 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
// 14. If calendar is not undefined, then // 14. If calendar is not undefined, then
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. // a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 15. Set opt.[[ca]] to calendar. // 15. Set opt.[[ca]] to calendar.
opt.ca = TRY(get_string_option(global_object, *options, vm.names.calendar, Unicode::is_type_identifier)); opt.ca = TRY(get_string_option(vm, *options, vm.names.calendar, Unicode::is_type_identifier));
// 16. Let collation be ? GetOption(options, "collation", "string", undefined, undefined). // 16. Let collation be ? GetOption(options, "collation", "string", undefined, undefined).
// 17. If collation is not undefined, then // 17. If collation is not undefined, then
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. // a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 18. Set opt.[[co]] to collation. // 18. Set opt.[[co]] to collation.
opt.co = TRY(get_string_option(global_object, *options, vm.names.collation, Unicode::is_type_identifier)); opt.co = TRY(get_string_option(vm, *options, vm.names.collation, Unicode::is_type_identifier));
// 19. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined). // 19. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
// 20. Set opt.[[hc]] to hc. // 20. Set opt.[[hc]] to hc.
opt.hc = TRY(get_string_option(global_object, *options, vm.names.hourCycle, nullptr, AK::Array { "h11"sv, "h12"sv, "h23"sv, "h24"sv })); opt.hc = TRY(get_string_option(vm, *options, vm.names.hourCycle, nullptr, AK::Array { "h11"sv, "h12"sv, "h23"sv, "h24"sv }));
// 21. Let kf be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined). // 21. Let kf be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined).
// 22. Set opt.[[kf]] to kf. // 22. Set opt.[[kf]] to kf.
opt.kf = TRY(get_string_option(global_object, *options, vm.names.caseFirst, nullptr, AK::Array { "upper"sv, "lower"sv, "false"sv })); opt.kf = TRY(get_string_option(vm, *options, vm.names.caseFirst, nullptr, AK::Array { "upper"sv, "lower"sv, "false"sv }));
// 23. Let kn be ? GetOption(options, "numeric", "boolean", undefined, undefined). // 23. Let kn be ? GetOption(options, "numeric", "boolean", undefined, undefined).
auto kn = TRY(get_option(global_object, *options, vm.names.numeric, OptionType::Boolean, {}, Empty {})); auto kn = TRY(get_option(global_object, *options, vm.names.numeric, OptionType::Boolean, {}, Empty {}));
@ -323,7 +322,7 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
// 27. If numberingSystem is not undefined, then // 27. If numberingSystem is not undefined, then
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. // a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 28. Set opt.[[nu]] to numberingSystem. // 28. Set opt.[[nu]] to numberingSystem.
opt.nu = TRY(get_string_option(global_object, *options, vm.names.numberingSystem, Unicode::is_type_identifier)); opt.nu = TRY(get_string_option(vm, *options, vm.names.numberingSystem, Unicode::is_type_identifier));
// 29. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys). // 29. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
auto result = apply_unicode_extension_to_tag(tag, move(opt), relevant_extension_keys); auto result = apply_unicode_extension_to_tag(tag, move(opt), relevant_extension_keys);

View file

@ -225,7 +225,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \
{ \ { \
auto* locale_object = TRY(typed_this_object(global_object)); \ auto* locale_object = TRY(typed_this_object(global_object)); \
return keyword##_of_locale(global_object, *locale_object); \ return keyword##_of_locale(vm, *locale_object); \
} }
JS_ENUMERATE_LOCALE_INFO_PROPERTIES JS_ENUMERATE_LOCALE_INFO_PROPERTIES
#undef __JS_ENUMERATE #undef __JS_ENUMERATE
@ -245,7 +245,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::time_zones)
return js_undefined(); return js_undefined();
// 5. Return ! TimeZonesOfLocale(loc). // 5. Return ! TimeZonesOfLocale(loc).
return time_zones_of_locale(global_object, locale->language_id.region.value()); return time_zones_of_locale(vm, locale->language_id.region.value());
} }
// 1.4.21 get Intl.Locale.prototype.textInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.textInfo // 1.4.21 get Intl.Locale.prototype.textInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.textInfo

View file

@ -301,10 +301,8 @@ String MathematicalValue::to_string() const
[](auto) -> String { VERIFY_NOT_REACHED(); }); [](auto) -> String { VERIFY_NOT_REACHED(); });
} }
Value MathematicalValue::to_value(GlobalObject& global_object) const Value MathematicalValue::to_value(VM& vm) const
{ {
auto& vm = global_object.vm();
return m_value.visit( return m_value.visit(
[](double value) { [](double value) {
return Value(value); return Value(value);

View file

@ -88,7 +88,7 @@ public:
bool is_zero() const; bool is_zero() const;
String to_string() const; String to_string() const;
Value to_value(GlobalObject&) const; Value to_value(VM&) const;
private: private:
using ValueType = Variant<double, Crypto::SignedBigInteger, Symbol>; using ValueType = Variant<double, Crypto::SignedBigInteger, Symbol>;

View file

@ -242,10 +242,8 @@ void NumberFormatBase::set_trailing_zero_display(StringView trailing_zero_displa
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
Value NumberFormat::use_grouping_to_value(GlobalObject& global_object) const Value NumberFormat::use_grouping_to_value(VM& vm) const
{ {
auto& vm = global_object.vm();
switch (m_use_grouping) { switch (m_use_grouping) {
case UseGrouping::Always: case UseGrouping::Always:
return js_string(vm, "always"sv); return js_string(vm, "always"sv);
@ -519,7 +517,7 @@ FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, Mathe
// 15.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-partitionnumberpattern // 15.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-partitionnumberpattern
// 1.1.6 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberpattern // 1.1.6 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberpattern
Vector<PatternPartition> partition_number_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number) Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number)
{ {
// 1. Let exponent be 0. // 1. Let exponent be 0.
int exponent = 0; int exponent = 0;
@ -574,7 +572,7 @@ Vector<PatternPartition> partition_number_pattern(GlobalObject& global_object, N
Unicode::NumberFormat found_pattern {}; Unicode::NumberFormat found_pattern {};
// 6. Let pattern be GetNumberFormatPattern(numberFormat, x). // 6. Let pattern be GetNumberFormatPattern(numberFormat, x).
auto pattern = get_number_format_pattern(global_object, number_format, number, found_pattern); auto pattern = get_number_format_pattern(vm, number_format, number, found_pattern);
if (!pattern.has_value()) if (!pattern.has_value())
return {}; return {};
@ -887,11 +885,11 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
} }
// 15.5.6 FormatNumeric ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumber // 15.5.6 FormatNumeric ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumber
String format_numeric(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number) String format_numeric(VM& vm, NumberFormat& number_format, MathematicalValue number)
{ {
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x). // 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
// Note: Our implementation of PartitionNumberPattern does not throw. // Note: Our implementation of PartitionNumberPattern does not throw.
auto parts = partition_number_pattern(global_object, number_format, move(number)); auto parts = partition_number_pattern(vm, number_format, move(number));
// 2. Let result be the empty String. // 2. Let result be the empty String.
StringBuilder result; StringBuilder result;
@ -907,14 +905,14 @@ String format_numeric(GlobalObject& global_object, NumberFormat& number_format,
} }
// 15.5.7 FormatNumericToParts ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumbertoparts // 15.5.7 FormatNumericToParts ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumbertoparts
Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number) Array* format_numeric_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue number)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x). // 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
// Note: Our implementation of PartitionNumberPattern does not throw. // Note: Our implementation of PartitionNumberPattern does not throw.
auto parts = partition_number_pattern(global_object, number_format, move(number)); auto parts = partition_number_pattern(vm, number_format, move(number));
// 2. Let result be ! ArrayCreate(0). // 2. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));
@ -1261,7 +1259,7 @@ RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction,
// 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern // 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern
// 1.1.14 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern // 1.1.14 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern
Optional<Variant<StringView, String>> get_number_format_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue const& number, Unicode::NumberFormat& found_pattern) Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, Unicode::NumberFormat& found_pattern)
{ {
// 1. Let localeData be %NumberFormat%.[[LocaleData]]. // 1. Let localeData be %NumberFormat%.[[LocaleData]].
// 2. Let dataLocale be numberFormat.[[DataLocale]]. // 2. Let dataLocale be numberFormat.[[DataLocale]].
@ -1288,7 +1286,7 @@ Optional<Variant<StringView, String>> get_number_format_pattern(GlobalObject& gl
// e. Let patterns be patterns.[[<unit>]]. // e. Let patterns be patterns.[[<unit>]].
// f. Let patterns be patterns.[[<unitDisplay>]]. // f. Let patterns be patterns.[[<unitDisplay>]].
auto formats = Unicode::get_unit_formats(number_format.data_locale(), number_format.unit(), number_format.unit_display()); auto formats = Unicode::get_unit_formats(number_format.data_locale(), number_format.unit(), number_format.unit_display());
auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(global_object)); auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(vm));
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end())
patterns = move(*it); patterns = move(*it);
@ -1311,7 +1309,7 @@ Optional<Variant<StringView, String>> get_number_format_pattern(GlobalObject& gl
// Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]]. // Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]].
if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) { if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) {
auto formats = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::CurrencyUnit); auto formats = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::CurrencyUnit);
auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(global_object)); auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(vm));
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) { if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) {
patterns = move(*it); patterns = move(*it);
@ -1580,8 +1578,11 @@ int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude)
} }
// 1.1.18 ToIntlMathematicalValue ( value ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-tointlmathematicalvalue // 1.1.18 ToIntlMathematicalValue ( value ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-tointlmathematicalvalue
ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(GlobalObject& global_object, Value value) ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM& vm, Value value)
{ {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let primValue be ? ToPrimitive(value, number). // 1. Let primValue be ? ToPrimitive(value, number).
auto primitive_value = TRY(value.to_primitive(global_object, Value::PreferredType::Number)); auto primitive_value = TRY(value.to_primitive(global_object, Value::PreferredType::Number));
@ -1720,10 +1721,8 @@ RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, Mathem
} }
// 1.1.21 PartitionNumberRangePattern ( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberrangepattern // 1.1.21 PartitionNumberRangePattern ( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberrangepattern
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end)
{ {
auto& vm = global_object.vm();
// 1. If x is NaN or y is NaN, throw a RangeError exception. // 1. If x is NaN or y is NaN, throw a RangeError exception.
if (start.is_nan()) if (start.is_nan())
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "start"sv); return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "start"sv);
@ -1734,11 +1733,11 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
Vector<PatternPartitionWithSource> result; Vector<PatternPartitionWithSource> result;
// 3. Let xResult be ? PartitionNumberPattern(numberFormat, x). // 3. Let xResult be ? PartitionNumberPattern(numberFormat, x).
auto raw_start_result = partition_number_pattern(global_object, number_format, move(start)); auto raw_start_result = partition_number_pattern(vm, number_format, move(start));
auto start_result = PatternPartitionWithSource::create_from_parent_list(move(raw_start_result)); auto start_result = PatternPartitionWithSource::create_from_parent_list(move(raw_start_result));
// 4. Let yResult be ? PartitionNumberPattern(numberFormat, y). // 4. Let yResult be ? PartitionNumberPattern(numberFormat, y).
auto raw_end_result = partition_number_pattern(global_object, number_format, move(end)); auto raw_end_result = partition_number_pattern(vm, number_format, move(end));
auto end_result = PatternPartitionWithSource::create_from_parent_list(move(raw_end_result)); auto end_result = PatternPartitionWithSource::create_from_parent_list(move(raw_end_result));
// 5. If xResult is equal to yResult, return FormatApproximately(numberFormat, xResult). // 5. If xResult is equal to yResult, return FormatApproximately(numberFormat, xResult).
@ -1806,10 +1805,10 @@ Vector<PatternPartitionWithSource> collapse_number_range(Vector<PatternPartition
} }
// 1.1.24 FormatNumericRange( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrange // 1.1.24 FormatNumericRange( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrange
ThrowCompletionOr<String> format_numeric_range(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) ThrowCompletionOr<String> format_numeric_range(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end)
{ {
// 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y). // 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y).
auto parts = TRY(partition_number_range_pattern(global_object, number_format, move(start), move(end))); auto parts = TRY(partition_number_range_pattern(vm, number_format, move(start), move(end)));
// 2. Let result be the empty String. // 2. Let result be the empty String.
StringBuilder result; StringBuilder result;
@ -1825,13 +1824,13 @@ ThrowCompletionOr<String> format_numeric_range(GlobalObject& global_object, Numb
} }
// 1.1.25 FormatNumericRangeToParts( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrangetoparts // 1.1.25 FormatNumericRangeToParts( numberFormat, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-formatnumericrangetoparts
ThrowCompletionOr<Array*> format_numeric_range_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) ThrowCompletionOr<Array*> format_numeric_range_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y). // 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y).
auto parts = TRY(partition_number_range_pattern(global_object, number_format, move(start), move(end))); auto parts = TRY(partition_number_range_pattern(vm, number_format, move(start), move(end)));
// 2. Let result be ! ArrayCreate(0). // 2. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));

View file

@ -209,7 +209,7 @@ public:
void set_unit_display(StringView unit_display) { m_unit_display = Unicode::style_from_string(unit_display); } void set_unit_display(StringView unit_display) { m_unit_display = Unicode::style_from_string(unit_display); }
UseGrouping use_grouping() const { return m_use_grouping; } UseGrouping use_grouping() const { return m_use_grouping; }
Value use_grouping_to_value(GlobalObject&) const; Value use_grouping_to_value(VM&) const;
void set_use_grouping(StringOrBoolean const& use_grouping); void set_use_grouping(StringOrBoolean const& use_grouping);
Notation notation() const { return m_notation; } Notation notation() const { return m_notation; }
@ -274,23 +274,23 @@ enum class RoundingDecision {
int currency_digits(StringView currency); int currency_digits(StringView currency);
FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, MathematicalValue number); FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, MathematicalValue number);
Vector<PatternPartition> partition_number_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number); Vector<PatternPartition> partition_number_pattern(VM&, NumberFormat&, MathematicalValue number);
Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_format, MathematicalValue const& number, String formatted_string, int exponent); Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat&, MathematicalValue const& number, String formatted_string, int exponent);
String format_numeric(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number); String format_numeric(VM&, NumberFormat&, MathematicalValue number);
Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number); Array* format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number);
RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode); RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode); RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
Optional<Variant<StringView, String>> get_number_format_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue const& number, Unicode::NumberFormat& found_pattern); Optional<Variant<StringView, String>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, Unicode::NumberFormat& found_pattern);
Optional<StringView> get_notation_sub_pattern(NumberFormat& number_format, int exponent); Optional<StringView> get_notation_sub_pattern(NumberFormat&, int exponent);
int compute_exponent(NumberFormat& number_format, MathematicalValue number); int compute_exponent(NumberFormat&, MathematicalValue number);
int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude); int compute_exponent_for_magnitude(NumberFormat&, int magnitude);
ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(GlobalObject& global_object, Value value); ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM&, Value value);
NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode rounding_mode, bool is_negative); NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode, bool is_negative);
RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, MathematicalValue const& r1, MathematicalValue const& r2, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode); RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, MathematicalValue const& r1, MathematicalValue const& r2, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end); ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end);
Vector<PatternPartitionWithSource> format_approximately(NumberFormat& number_format, Vector<PatternPartitionWithSource> result); Vector<PatternPartitionWithSource> format_approximately(NumberFormat&, Vector<PatternPartitionWithSource> result);
Vector<PatternPartitionWithSource> collapse_number_range(Vector<PatternPartitionWithSource> result); Vector<PatternPartitionWithSource> collapse_number_range(Vector<PatternPartitionWithSource> result);
ThrowCompletionOr<String> format_numeric_range(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end); ThrowCompletionOr<String> format_numeric_range(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end);
ThrowCompletionOr<Array*> format_numeric_range_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end); ThrowCompletionOr<Array*> format_numeric_range_to_parts(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end);
} }

View file

@ -54,7 +54,7 @@ ThrowCompletionOr<Object*> NumberFormatConstructor::construct(FunctionObject& ne
auto* number_format = TRY(ordinary_create_from_constructor<NumberFormat>(global_object, new_target, &GlobalObject::intl_number_format_prototype)); auto* number_format = TRY(ordinary_create_from_constructor<NumberFormat>(global_object, new_target, &GlobalObject::intl_number_format_prototype));
// 3. Perform ? InitializeNumberFormat(numberFormat, locales, options). // 3. Perform ? InitializeNumberFormat(numberFormat, locales, options).
TRY(initialize_number_format(global_object, *number_format, locales, options)); TRY(initialize_number_format(vm, *number_format, locales, options));
// 4. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then // 4. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// a. Let this be the this value. // a. Let this be the this value.
@ -73,23 +73,24 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %NumberFormat%.[[AvailableLocales]]. // 1. Let availableLocales be %NumberFormat%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
// 15.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/ecma402/#sec-initializenumberformat // 15.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/ecma402/#sec-initializenumberformat
// 1.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-initializenumberformat // 1.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-initializenumberformat
ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_object, NumberFormat& number_format, Value locales_value, Value options_value) ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat& number_format, Value locales_value, Value options_value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(global_object, options_value)); auto* options = TRY(coerce_options_to_object(vm, options_value));
// 3. Let opt be a new Record. // 3. Let opt be a new Record.
LocaleOptions opt {}; LocaleOptions opt {};
@ -128,7 +129,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
number_format.set_numbering_system(result.nu.release_value()); number_format.set_numbering_system(result.nu.release_value());
// 14. Perform ? SetNumberFormatUnitOptions(numberFormat, options). // 14. Perform ? SetNumberFormatUnitOptions(numberFormat, options).
TRY(set_number_format_unit_options(global_object, number_format, *options)); TRY(set_number_format_unit_options(vm, number_format, *options));
// 15. Let style be numberFormat.[[Style]]. // 15. Let style be numberFormat.[[Style]].
auto style = number_format.style(); auto style = number_format.style();
@ -169,10 +170,10 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
number_format.set_notation(notation.as_string().string()); number_format.set_notation(notation.as_string().string());
// 20. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation). // 20. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation).
TRY(set_number_format_digit_options(global_object, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format.notation())); TRY(set_number_format_digit_options(vm, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format.notation()));
// 21. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1). // 21. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1).
auto rounding_increment = TRY(get_number_option(global_object, *options, vm.names.roundingIncrement, 1, 5000, 1)); auto rounding_increment = TRY(get_number_option(vm, *options, vm.names.roundingIncrement, 1, 5000, 1));
// 22. If roundingIncrement is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a RangeError exception. // 22. If roundingIncrement is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a RangeError exception.
static constexpr auto sanctioned_rounding_increments = AK::Array { 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 }; static constexpr auto sanctioned_rounding_increments = AK::Array { 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 };
@ -213,7 +214,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
} }
// 31. Let useGrouping be ? GetStringOrBooleanOption(options, "useGrouping", « "min2", "auto", "always" », "always", false, defaultUseGrouping). // 31. Let useGrouping be ? GetStringOrBooleanOption(options, "useGrouping", « "min2", "auto", "always" », "always", false, defaultUseGrouping).
auto use_grouping = TRY(get_string_or_boolean_option(global_object, *options, vm.names.useGrouping, { "min2"sv, "auto"sv, "always"sv }, "always"sv, false, default_use_grouping)); auto use_grouping = TRY(get_string_or_boolean_option(vm, *options, vm.names.useGrouping, { "min2"sv, "auto"sv, "always"sv }, "always"sv, false, default_use_grouping));
// 32. Set numberFormat.[[UseGrouping]] to useGrouping. // 32. Set numberFormat.[[UseGrouping]] to useGrouping.
number_format.set_use_grouping(use_grouping); number_format.set_use_grouping(use_grouping);
@ -236,12 +237,13 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
// 15.1.3 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/ecma402/#sec-setnfdigitoptions // 15.1.3 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/ecma402/#sec-setnfdigitoptions
// 1.1.1 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-setnfdigitoptions // 1.1.1 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-setnfdigitoptions
ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_object, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation) ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1). // 1. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1).
auto min_integer_digits = TRY(get_number_option(global_object, options, vm.names.minimumIntegerDigits, 1, 21, 1)); auto min_integer_digits = TRY(get_number_option(vm, options, vm.names.minimumIntegerDigits, 1, 21, 1));
// 2. Let mnfd be ? Get(options, "minimumFractionDigits"). // 2. Let mnfd be ? Get(options, "minimumFractionDigits").
auto min_fraction_digits = TRY(options.get(vm.names.minimumFractionDigits)); auto min_fraction_digits = TRY(options.get(vm.names.minimumFractionDigits));
@ -296,10 +298,10 @@ ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_obj
// a. If hasSd is true, then // a. If hasSd is true, then
if (has_significant_digits) { if (has_significant_digits) {
// i. Set mnsd to ? DefaultNumberOption(mnsd, 1, 21, 1). // i. Set mnsd to ? DefaultNumberOption(mnsd, 1, 21, 1).
auto min_digits = TRY(default_number_option(global_object, min_significant_digits, 1, 21, 1)); auto min_digits = TRY(default_number_option(vm, min_significant_digits, 1, 21, 1));
// ii. Set mxsd to ? DefaultNumberOption(mxsd, mnsd, 21, 21). // ii. Set mxsd to ? DefaultNumberOption(mxsd, mnsd, 21, 21).
auto max_digits = TRY(default_number_option(global_object, max_significant_digits, *min_digits, 21, 21)); auto max_digits = TRY(default_number_option(vm, max_significant_digits, *min_digits, 21, 21));
// iii. Set intlObj.[[MinimumSignificantDigits]] to mnsd. // iii. Set intlObj.[[MinimumSignificantDigits]] to mnsd.
intl_object.set_min_significant_digits(*min_digits); intl_object.set_min_significant_digits(*min_digits);
@ -322,10 +324,10 @@ ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_obj
// a. If hasFd is true, then // a. If hasFd is true, then
if (has_fraction_digits) { if (has_fraction_digits) {
// i. Set mnfd to ? DefaultNumberOption(mnfd, 0, 20, undefined). // i. Set mnfd to ? DefaultNumberOption(mnfd, 0, 20, undefined).
auto min_digits = TRY(default_number_option(global_object, min_fraction_digits, 0, 20, {})); auto min_digits = TRY(default_number_option(vm, min_fraction_digits, 0, 20, {}));
// ii. Set mxfd to ? DefaultNumberOption(mxfd, 0, 20, undefined). // ii. Set mxfd to ? DefaultNumberOption(mxfd, 0, 20, undefined).
auto max_digits = TRY(default_number_option(global_object, max_fraction_digits, 0, 20, {})); auto max_digits = TRY(default_number_option(vm, max_fraction_digits, 0, 20, {}));
// iii. If mnfd is undefined, set mnfd to min(mnfdDefault, mxfd). // iii. If mnfd is undefined, set mnfd to min(mnfdDefault, mxfd).
if (!min_digits.has_value()) if (!min_digits.has_value())
@ -399,9 +401,10 @@ ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_obj
} }
// 15.1.4 SetNumberFormatUnitOptions ( intlObj, options ), https://tc39.es/ecma402/#sec-setnumberformatunitoptions // 15.1.4 SetNumberFormatUnitOptions ( intlObj, options ), https://tc39.es/ecma402/#sec-setnumberformatunitoptions
ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_object, NumberFormat& intl_object, Object const& options) ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& intl_object, Object const& options)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: Type(intlObj) is Object. // 1. Assert: Type(intlObj) is Object.
// 2. Assert: Type(options) is Object. // 2. Assert: Type(options) is Object.

View file

@ -28,8 +28,8 @@ private:
JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); JS_DECLARE_NATIVE_FUNCTION(supported_locales_of);
}; };
ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_object, NumberFormat& number_format, Value locales_value, Value options_value); ThrowCompletionOr<NumberFormat*> initialize_number_format(VM&, NumberFormat&, Value locales_value, Value options_value);
ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_object, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation); ThrowCompletionOr<void> set_number_format_digit_options(VM&, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation);
ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_object, NumberFormat& intl_object, Object const& options); ThrowCompletionOr<void> set_number_format_unit_options(VM&, NumberFormat& intl_object, Object const& options);
} }

View file

@ -34,8 +34,7 @@ void NumberFormatFunction::initialize(Realm& realm)
ThrowCompletionOr<Value> NumberFormatFunction::call() ThrowCompletionOr<Value> NumberFormatFunction::call()
{ {
auto& global_object = this->global_object(); auto& vm = this->vm();
auto& vm = global_object.vm();
// 1. Let nf be F.[[NumberFormat]]. // 1. Let nf be F.[[NumberFormat]].
// 2. Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot. // 2. Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot.
@ -43,11 +42,11 @@ ThrowCompletionOr<Value> NumberFormatFunction::call()
auto value = vm.argument(0); auto value = vm.argument(0);
// 4. Let x be ? ToIntlMathematicalValue(value). // 4. Let x be ? ToIntlMathematicalValue(value).
auto mathematical_value = TRY(to_intl_mathematical_value(global_object, value)); auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
// 5. Return ? FormatNumeric(nf, x). // 5. Return ? FormatNumeric(nf, x).
// Note: Our implementation of FormatNumeric does not throw. // Note: Our implementation of FormatNumeric does not throw.
auto formatted = format_numeric(global_object, m_number_format, move(mathematical_value)); auto formatted = format_numeric(vm, m_number_format, move(mathematical_value));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }

View file

@ -73,11 +73,11 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts)
auto* number_format = TRY(typed_this_object(global_object)); auto* number_format = TRY(typed_this_object(global_object));
// 3. Let x be ? ToIntlMathematicalValue(value). // 3. Let x be ? ToIntlMathematicalValue(value).
auto mathematical_value = TRY(to_intl_mathematical_value(global_object, value)); auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
// 4. Return ? FormatNumericToParts(nf, x). // 4. Return ? FormatNumericToParts(nf, x).
// Note: Our implementation of FormatNumericToParts does not throw. // Note: Our implementation of FormatNumericToParts does not throw.
return format_numeric_to_parts(global_object, *number_format, move(mathematical_value)); return format_numeric_to_parts(vm, *number_format, move(mathematical_value));
} }
// 1.4.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formatrange // 1.4.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formatrange
@ -97,13 +97,13 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range)
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv); return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
// 4. Let x be ? ToIntlMathematicalValue(start). // 4. Let x be ? ToIntlMathematicalValue(start).
auto x = TRY(to_intl_mathematical_value(global_object, start)); auto x = TRY(to_intl_mathematical_value(vm, start));
// 5. Let y be ? ToIntlMathematicalValue(end). // 5. Let y be ? ToIntlMathematicalValue(end).
auto y = TRY(to_intl_mathematical_value(global_object, end)); auto y = TRY(to_intl_mathematical_value(vm, end));
// 6. Return ? FormatNumericRange(nf, x, y). // 6. Return ? FormatNumericRange(nf, x, y).
auto formatted = TRY(format_numeric_range(global_object, *number_format, move(x), move(y))); auto formatted = TRY(format_numeric_range(vm, *number_format, move(x), move(y)));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }
@ -124,13 +124,13 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv); return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
// 4. Let x be ? ToIntlMathematicalValue(start). // 4. Let x be ? ToIntlMathematicalValue(start).
auto x = TRY(to_intl_mathematical_value(global_object, start)); auto x = TRY(to_intl_mathematical_value(vm, start));
// 5. Let y be ? ToIntlMathematicalValue(end). // 5. Let y be ? ToIntlMathematicalValue(end).
auto y = TRY(to_intl_mathematical_value(global_object, end)); auto y = TRY(to_intl_mathematical_value(vm, end));
// 6. Return ? FormatNumericRangeToParts(nf, x, y). // 6. Return ? FormatNumericRangeToParts(nf, x, y).
return TRY(format_numeric_range_to_parts(global_object, *number_format, move(x), move(y))); return TRY(format_numeric_range_to_parts(vm, *number_format, move(x), move(y)));
} }
// 15.3.5 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions // 15.3.5 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
@ -174,7 +174,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
MUST(options->create_data_property_or_throw(vm.names.minimumSignificantDigits, Value(number_format->min_significant_digits()))); MUST(options->create_data_property_or_throw(vm.names.minimumSignificantDigits, Value(number_format->min_significant_digits())));
if (number_format->has_max_significant_digits()) if (number_format->has_max_significant_digits())
MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(number_format->max_significant_digits()))); MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(number_format->max_significant_digits())));
MUST(options->create_data_property_or_throw(vm.names.useGrouping, number_format->use_grouping_to_value(global_object))); MUST(options->create_data_property_or_throw(vm.names.useGrouping, number_format->use_grouping_to_value(vm)));
MUST(options->create_data_property_or_throw(vm.names.notation, js_string(vm, number_format->notation_string()))); MUST(options->create_data_property_or_throw(vm.names.notation, js_string(vm, number_format->notation_string())));
if (number_format->has_compact_display()) if (number_format->has_compact_display())
MUST(options->create_data_property_or_throw(vm.names.compactDisplay, js_string(vm, number_format->compact_display_string()))); MUST(options->create_data_property_or_throw(vm.names.compactDisplay, js_string(vm, number_format->compact_display_string())));

View file

@ -137,10 +137,8 @@ Unicode::PluralCategory plural_rule_select_range(StringView locale, Unicode::Plu
} }
// 1.1.6 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolvepluralrange // 1.1.6 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolvepluralrange
ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(GlobalObject& global_object, PluralRules const& plural_rules, Value start, Value end) ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(VM& vm, PluralRules const& plural_rules, Value start, Value end)
{ {
auto& vm = global_object.vm();
// 1. Assert: Type(pluralRules) is Object. // 1. Assert: Type(pluralRules) is Object.
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot. // 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
// 3. Assert: Type(x) is Number. // 3. Assert: Type(x) is Number.

View file

@ -32,9 +32,9 @@ private:
Unicode::PluralOperands get_operands(String const& string); Unicode::PluralOperands get_operands(String const& string);
Unicode::PluralCategory plural_rule_select(StringView locale, Unicode::PluralForm type, Value number, Unicode::PluralOperands operands); Unicode::PluralCategory plural_rule_select(StringView locale, Unicode::PluralForm type, Value number, Unicode::PluralOperands operands);
Unicode::PluralCategory resolve_plural(PluralRules const& plural_rules, Value number); Unicode::PluralCategory resolve_plural(PluralRules const&, Value number);
Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Unicode::PluralForm type, Value number); Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Unicode::PluralForm type, Value number);
Unicode::PluralCategory plural_rule_select_range(StringView locale, Unicode::PluralForm, Unicode::PluralCategory start, Unicode::PluralCategory end); Unicode::PluralCategory plural_rule_select_range(StringView locale, Unicode::PluralForm, Unicode::PluralCategory start, Unicode::PluralCategory end);
ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(GlobalObject& global_object, PluralRules const& plural_rules, Value start, Value end); ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(VM&, PluralRules const&, Value start, Value end);
} }

View file

@ -55,7 +55,7 @@ ThrowCompletionOr<Object*> PluralRulesConstructor::construct(FunctionObject& new
auto* plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(global_object, new_target, &GlobalObject::intl_plural_rules_prototype)); auto* plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(global_object, new_target, &GlobalObject::intl_plural_rules_prototype));
// 3. Return ? InitializePluralRules(pluralRules, locales, options). // 3. Return ? InitializePluralRules(pluralRules, locales, options).
return TRY(initialize_plural_rules(global_object, *plural_rules, locales, options)); return TRY(initialize_plural_rules(vm, *plural_rules, locales, options));
} }
// 16.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-intl.pluralrules.supportedlocalesof // 16.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-intl.pluralrules.supportedlocalesof
@ -67,22 +67,23 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesConstructor::supported_locales_of)
// 1. Let availableLocales be %PluralRules%.[[AvailableLocales]]. // 1. Let availableLocales be %PluralRules%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
// 16.1.2 InitializePluralRules ( pluralRules, locales, options ), https://tc39.es/ecma402/#sec-initializepluralrules // 16.1.2 InitializePluralRules ( pluralRules, locales, options ), https://tc39.es/ecma402/#sec-initializepluralrules
ThrowCompletionOr<PluralRules*> initialize_plural_rules(GlobalObject& global_object, PluralRules& plural_rules, Value locales_value, Value options_value) ThrowCompletionOr<PluralRules*> initialize_plural_rules(VM& vm, PluralRules& plural_rules, Value locales_value, Value options_value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(global_object, options_value)); auto* options = TRY(coerce_options_to_object(vm, options_value));
// 3. Let opt be a new Record. // 3. Let opt be a new Record.
LocaleOptions opt {}; LocaleOptions opt {};
@ -100,7 +101,7 @@ ThrowCompletionOr<PluralRules*> initialize_plural_rules(GlobalObject& global_obj
plural_rules.set_type(type.as_string().string()); plural_rules.set_type(type.as_string().string());
// 8. Perform ? SetNumberFormatDigitOptions(pluralRules, options, +0𝔽, 3𝔽, "standard"). // 8. Perform ? SetNumberFormatDigitOptions(pluralRules, options, +0𝔽, 3𝔽, "standard").
TRY(set_number_format_digit_options(global_object, plural_rules, *options, 0, 3, NumberFormat::Notation::Standard)); TRY(set_number_format_digit_options(vm, plural_rules, *options, 0, 3, NumberFormat::Notation::Standard));
// 9. Let localeData be %PluralRules%.[[LocaleData]]. // 9. Let localeData be %PluralRules%.[[LocaleData]].
// 10. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], localeData). // 10. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], localeData).

View file

@ -27,6 +27,6 @@ private:
JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); JS_DECLARE_NATIVE_FUNCTION(supported_locales_of);
}; };
ThrowCompletionOr<PluralRules*> initialize_plural_rules(GlobalObject& global_object, PluralRules& plural_rules, Value locales_value, Value options_value); ThrowCompletionOr<PluralRules*> initialize_plural_rules(VM&, PluralRules&, Value locales_value, Value options_value);
} }

View file

@ -71,7 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
auto y = TRY(end.to_number(global_object)); auto y = TRY(end.to_number(global_object));
// 6. Return ? ResolvePluralRange(pr, x, y). // 6. Return ? ResolvePluralRange(pr, x, y).
auto plurality = TRY(resolve_plural_range(global_object, *plural_rules, x, y)); auto plurality = TRY(resolve_plural_range(vm, *plural_rules, x, y));
return js_string(vm, Unicode::plural_category_to_string(plurality)); return js_string(vm, Unicode::plural_category_to_string(plurality));
} }

View file

@ -54,10 +54,8 @@ StringView RelativeTimeFormat::numeric_string() const
} }
// 17.5.1 SingularRelativeTimeUnit ( unit ), https://tc39.es/ecma402/#sec-singularrelativetimeunit // 17.5.1 SingularRelativeTimeUnit ( unit ), https://tc39.es/ecma402/#sec-singularrelativetimeunit
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(GlobalObject& global_object, StringView unit) ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(VM& vm, StringView unit)
{ {
auto& vm = global_object.vm();
// 1. Assert: Type(unit) is String. // 1. Assert: Type(unit) is String.
// 2. If unit is "seconds", return "second". // 2. If unit is "seconds", return "second".
@ -93,9 +91,10 @@ ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(GlobalObject& g
} }
// 17.5.2 PartitionRelativeTimePattern ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-PartitionRelativeTimePattern // 17.5.2 PartitionRelativeTimePattern ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-PartitionRelativeTimePattern
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit) ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(VM& vm, RelativeTimeFormat& relative_time_format, double value, StringView unit)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: relativeTimeFormat has an [[InitializedRelativeTimeFormat]] internal slot. // 1. Assert: relativeTimeFormat has an [[InitializedRelativeTimeFormat]] internal slot.
// 2. Assert: Type(value) is Number. // 2. Assert: Type(value) is Number.
@ -106,7 +105,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaNOrInfinity); return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaNOrInfinity);
// 5. Let unit be ? SingularRelativeTimeUnit(unit). // 5. Let unit be ? SingularRelativeTimeUnit(unit).
auto time_unit = TRY(singular_relative_time_unit(global_object, unit)); auto time_unit = TRY(singular_relative_time_unit(vm, unit));
// 6. Let localeData be %RelativeTimeFormat%.[[LocaleData]]. // 6. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
// 7. Let dataLocale be relativeTimeFormat.[[DataLocale]]. // 7. Let dataLocale be relativeTimeFormat.[[DataLocale]].
@ -178,7 +177,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
auto patterns = find_patterns_for_tense_or_number(tense); auto patterns = find_patterns_for_tense_or_number(tense);
// 20. Let fv be ! PartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], value). // 20. Let fv be ! PartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], value).
auto value_partitions = partition_number_pattern(global_object, relative_time_format.number_format(), Value(value)); auto value_partitions = partition_number_pattern(vm, relative_time_format.number_format(), Value(value));
// 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value). // 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value).
auto plurality = resolve_plural(relative_time_format.plural_rules(), Value(value)); auto plurality = resolve_plural(relative_time_format.plural_rules(), Value(value));
@ -226,10 +225,10 @@ Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView
} }
// 17.5.4 FormatRelativeTime ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-FormatRelativeTime // 17.5.4 FormatRelativeTime ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-FormatRelativeTime
ThrowCompletionOr<String> format_relative_time(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit) ThrowCompletionOr<String> format_relative_time(VM& vm, RelativeTimeFormat& relative_time_format, double value, StringView unit)
{ {
// 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit). // 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit).
auto parts = TRY(partition_relative_time_pattern(global_object, relative_time_format, value, unit)); auto parts = TRY(partition_relative_time_pattern(vm, relative_time_format, value, unit));
// 2. Let result be an empty String. // 2. Let result be an empty String.
StringBuilder result; StringBuilder result;
@ -245,13 +244,13 @@ ThrowCompletionOr<String> format_relative_time(GlobalObject& global_object, Rela
} }
// 17.5.5 FormatRelativeTimeToParts ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-FormatRelativeTimeToParts // 17.5.5 FormatRelativeTimeToParts ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-FormatRelativeTimeToParts
ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit) ThrowCompletionOr<Array*> format_relative_time_to_parts(VM& vm, RelativeTimeFormat& relative_time_format, double value, StringView unit)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit). // 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit).
auto parts = TRY(partition_relative_time_pattern(global_object, relative_time_format, value, unit)); auto parts = TRY(partition_relative_time_pattern(vm, relative_time_format, value, unit));
// 2. Let result be ! ArrayCreate(0). // 2. Let result be ! ArrayCreate(0).
auto* result = MUST(Array::create(realm, 0)); auto* result = MUST(Array::create(realm, 0));

View file

@ -81,10 +81,10 @@ struct PatternPartitionWithUnit : public PatternPartition {
StringView unit; StringView unit;
}; };
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(GlobalObject& global_object, StringView unit); ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(VM&, StringView unit);
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit); ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(VM&, RelativeTimeFormat&, double value, StringView unit);
Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts); Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts);
ThrowCompletionOr<String> format_relative_time(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit); ThrowCompletionOr<String> format_relative_time(VM&, RelativeTimeFormat&, double value, StringView unit);
ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit); ThrowCompletionOr<Array*> format_relative_time_to_parts(VM&, RelativeTimeFormat&, double value, StringView unit);
} }

View file

@ -58,7 +58,7 @@ ThrowCompletionOr<Object*> RelativeTimeFormatConstructor::construct(FunctionObje
auto* relative_time_format = TRY(ordinary_create_from_constructor<RelativeTimeFormat>(global_object, new_target, &GlobalObject::intl_relative_time_format_prototype)); auto* relative_time_format = TRY(ordinary_create_from_constructor<RelativeTimeFormat>(global_object, new_target, &GlobalObject::intl_relative_time_format_prototype));
// 3. Return ? InitializeRelativeTimeFormat(relativeTimeFormat, locales, options). // 3. Return ? InitializeRelativeTimeFormat(relativeTimeFormat, locales, options).
return TRY(initialize_relative_time_format(global_object, *relative_time_format, locales, options)); return TRY(initialize_relative_time_format(vm, *relative_time_format, locales, options));
} }
// 17.2.2 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.supportedLocalesOf // 17.2.2 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.supportedLocalesOf
@ -70,22 +70,23 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %RelativeTimeFormat%.[[AvailableLocales]]. // 1. Let availableLocales be %RelativeTimeFormat%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
// 17.1.2 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options ), https://tc39.es/ecma402/#sec-InitializeRelativeTimeFormat // 17.1.2 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options ), https://tc39.es/ecma402/#sec-InitializeRelativeTimeFormat
ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, Value locales_value, Value options_value) ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, RelativeTimeFormat& relative_time_format, Value locales_value, Value options_value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales_value)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
auto* options = TRY(coerce_options_to_object(global_object, options_value)); auto* options = TRY(coerce_options_to_object(vm, options_value));
// 3. Let opt be a new Record. // 3. Let opt be a new Record.
LocaleOptions opt {}; LocaleOptions opt {};

View file

@ -27,6 +27,6 @@ private:
JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); JS_DECLARE_NATIVE_FUNCTION(supported_locales_of);
}; };
ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, Value locales_value, Value options_value); ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, RelativeTimeFormat& relative_time_format, Value locales_value, Value options_value);
} }

View file

@ -45,7 +45,7 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format)
auto unit = TRY(vm.argument(1).to_string(global_object)); auto unit = TRY(vm.argument(1).to_string(global_object));
// 5. Return ? FormatRelativeTime(relativeTimeFormat, value, unit). // 5. Return ? FormatRelativeTime(relativeTimeFormat, value, unit).
auto formatted = TRY(format_relative_time(global_object, *relative_time_format, value.as_double(), unit)); auto formatted = TRY(format_relative_time(vm, *relative_time_format, value.as_double(), unit));
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }
@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format_to_parts)
auto unit = TRY(vm.argument(1).to_string(global_object)); auto unit = TRY(vm.argument(1).to_string(global_object));
// 5. Return ? FormatRelativeTimeToParts(relativeTimeFormat, value, unit). // 5. Return ? FormatRelativeTimeToParts(relativeTimeFormat, value, unit).
return TRY(format_relative_time_to_parts(global_object, *relative_time_format, value.as_double(), unit)); return TRY(format_relative_time_to_parts(vm, *relative_time_format, value.as_double(), unit));
} }
// 17.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions // 17.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions

View file

@ -60,7 +60,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
iterator->set_iterated_string_next_segment_code_unit_index(end_index); iterator->set_iterated_string_next_segment_code_unit_index(end_index);
// 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex). // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex).
auto* segment_data = create_segment_data_object(global_object, segmenter, string, start_index, end_index); auto* segment_data = create_segment_data_object(vm, segmenter, string, start_index, end_index);
// 10. Return CreateIterResultObject(segmentData, false). // 10. Return CreateIterResultObject(segmentData, false).
return create_iterator_result_object(global_object, segment_data, false); return create_iterator_result_object(global_object, segment_data, false);

View file

@ -45,10 +45,10 @@ StringView Segmenter::segmenter_granularity_string() const
} }
// 18.7.1 CreateSegmentDataObject ( segmenter, string, startIndex, endIndex ), https://tc39.es/ecma402/#sec-createsegmentdataobject // 18.7.1 CreateSegmentDataObject ( segmenter, string, startIndex, endIndex ), https://tc39.es/ecma402/#sec-createsegmentdataobject
Object* create_segment_data_object(GlobalObject& global_object, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index) Object* create_segment_data_object(VM& vm, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let len be the length of string. // 1. Let len be the length of string.
auto length = string.length_in_code_units(); auto length = string.length_in_code_units();

View file

@ -36,7 +36,7 @@ private:
SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]] SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]]
}; };
Object* create_segment_data_object(GlobalObject&, Segmenter const&, Utf16View const&, double start_index, double end_index); Object* create_segment_data_object(VM&, Segmenter const&, Utf16View const&, double start_index, double end_index);
enum class Direction { enum class Direction {
Before, Before,
After, After,

View file

@ -55,7 +55,7 @@ ThrowCompletionOr<Object*> SegmenterConstructor::construct(FunctionObject& new_t
auto* segmenter = TRY(ordinary_create_from_constructor<Segmenter>(global_object, new_target, &GlobalObject::intl_segmenter_prototype)); auto* segmenter = TRY(ordinary_create_from_constructor<Segmenter>(global_object, new_target, &GlobalObject::intl_segmenter_prototype));
// 4. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 4. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 5. Set options to ? GetOptionsObject(options). // 5. Set options to ? GetOptionsObject(options).
auto* options = TRY(Temporal::get_options_object(global_object, options_value)); auto* options = TRY(Temporal::get_options_object(global_object, options_value));
@ -96,10 +96,10 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterConstructor::supported_locales_of)
// 1. Let availableLocales be %Segmenter%.[[AvailableLocales]]. // 1. Let availableLocales be %Segmenter%.[[AvailableLocales]].
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options).
return TRY(supported_locales(global_object, requested_locales, options)); return TRY(supported_locales(vm, requested_locales, options));
} }
} }

View file

@ -58,7 +58,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing)
auto end_index = find_boundary(segmenter, string, n, Direction::After, segments->boundaries_cache()); auto end_index = find_boundary(segmenter, string, n, Direction::After, segments->boundaries_cache());
// 10. Return ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex). // 10. Return ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex).
return create_segment_data_object(global_object, segmenter, string, start_index, end_index); return create_segment_data_object(vm, segmenter, string, start_index, end_index);
} }
// 18.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator // 18.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator

View file

@ -331,7 +331,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string)
// 3. Return ? FormatNumeric(numberFormat, x). // 3. Return ? FormatNumeric(numberFormat, x).
// Note: Our implementation of FormatNumeric does not throw. // Note: Our implementation of FormatNumeric does not throw.
auto formatted = Intl::format_numeric(global_object, *number_format, number_value); auto formatted = Intl::format_numeric(vm, *number_format, number_value);
return js_string(vm, move(formatted)); return js_string(vm, move(formatted));
} }

View file

@ -326,8 +326,10 @@ enum class TargetCase {
// 19.1.2.1 TransformCase ( S, locales, targetCase ), https://tc39.es/ecma402/#sec-transform-case // 19.1.2.1 TransformCase ( S, locales, targetCase ), https://tc39.es/ecma402/#sec-transform-case
static ThrowCompletionOr<String> transform_case(GlobalObject& global_object, StringView string, Value locales, TargetCase target_case) static ThrowCompletionOr<String> transform_case(GlobalObject& global_object, StringView string, Value locales, TargetCase target_case)
{ {
auto& vm = global_object.vm();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(Intl::canonicalize_locale_list(global_object, locales)); auto requested_locales = TRY(Intl::canonicalize_locale_list(vm, locales));
Optional<Unicode::LocaleID> requested_locale; Optional<Unicode::LocaleID> requested_locale;

View file

@ -753,7 +753,7 @@ static void print_intl_number_format(JS::Intl::NumberFormat const& number_format
print_value(JS::Value(number_format.max_significant_digits()), seen_objects); print_value(JS::Value(number_format.max_significant_digits()), seen_objects);
} }
js_out("\n useGrouping: "); js_out("\n useGrouping: ");
print_value(number_format.use_grouping_to_value(number_format.global_object()), seen_objects); print_value(number_format.use_grouping_to_value(number_format.vm()), seen_objects);
js_out("\n roundingType: "); js_out("\n roundingType: ");
print_value(js_string(number_format.vm(), number_format.rounding_type_string()), seen_objects); print_value(js_string(number_format.vm(), number_format.rounding_type_string()), seen_objects);
js_out("\n roundingMode: "); js_out("\n roundingMode: ");
@ -798,7 +798,7 @@ static void print_intl_date_time_format(JS::Intl::DateTimeFormat& date_time_form
print_value(js_string(date_time_format.vm(), date_time_format.time_style_string()), seen_objects); print_value(js_string(date_time_format.vm(), date_time_format.time_style_string()), seen_objects);
} }
JS::Intl::for_each_calendar_field(date_time_format.global_object(), date_time_format, [&](auto& option, auto const& property, auto const&) -> JS::ThrowCompletionOr<void> { JS::Intl::for_each_calendar_field(date_time_format.vm(), date_time_format, [&](auto& option, auto const& property, auto const&) -> JS::ThrowCompletionOr<void> {
using ValueType = typename RemoveReference<decltype(option)>::ValueType; using ValueType = typename RemoveReference<decltype(option)>::ValueType;
if (!option.has_value()) if (!option.has_value())