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
Notes: sideshowbarker 2024-07-17 08:00:56 +09:00
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)));
// 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));
}

View file

@ -1009,13 +1009,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string)
return js_string(vm, "Invalid Date"sv);
// 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 »).
auto* date_format = TRY(construct_date_time_format(global_object, locales, options));
// 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));
}
@ -1034,13 +1034,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string)
return js_string(vm, "Invalid Date"sv);
// 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 »).
auto* date_format = TRY(construct_date_time_format(global_object, locales, options));
// 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));
}
@ -1059,13 +1059,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string)
return js_string(vm, "Invalid Date"sv);
// 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 »).
auto* time_format = TRY(construct_date_time_format(global_object, locales, options));
// 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));
}

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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If locales is undefined, then
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 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").
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
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
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.
// 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).
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
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.
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
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.
@ -673,7 +678,7 @@ ThrowCompletionOr<Optional<int>> get_number_option(GlobalObject& global_object,
auto value = TRY(options.get(property));
// 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

View file

@ -95,23 +95,23 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
String canonicalize_unicode_locale_id(Unicode::LocaleID& locale);
bool is_well_formed_currency_code(StringView currency);
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);
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);
Vector<String> lookup_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<Object*> coerce_options_to_object(GlobalObject& global_object, 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<Optional<int>> default_number_option(GlobalObject& global_object, 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<Array*> supported_locales(VM&, Vector<String> const& requested_locales, Value options);
ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
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(VM&, Value value, 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);
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.

View file

@ -15,15 +15,16 @@
namespace JS::Intl {
// 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).
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).
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").
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));
// 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
@ -189,10 +190,10 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorConstructor::supported_locales_of)
// 1. Let availableLocales be %Collator%.[[AvailableLocales]].
// 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).
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let x be TimeClip(x).
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]]).
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.
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));
// 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.
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
case Unicode::CalendarPatternStyle::Numeric:
// 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;
// ix. Else if f is "2-digit", then
case Unicode::CalendarPatternStyle::TwoDigit:
// 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.
// 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
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]]).
auto pattern_parts = partition_pattern(date_time_format.pattern());
// 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.
return result;
}
// 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).
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.
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 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).
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
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).
start = time_clip(start);
@ -938,10 +936,10 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime);
// 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]]).
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]].
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);
// 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));
// 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);
// 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));
// 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
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).
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.
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 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).
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
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.
@ -1248,7 +1246,7 @@ ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double t
// 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.
// 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/Vector.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Object.h>
#include <LibUnicode/DateTimeFormat.h>
@ -180,24 +179,22 @@ struct LocalTime {
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> 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);
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>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double time);
ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, double time);
ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end);
ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end);
ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end);
ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double time, StringView calendar, StringView time_zone);
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(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<String> format_date_time(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<Array*> format_date_time_to_parts(VM&, DateTimeFormat&, double time);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<String> format_date_time_range(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<Array*> format_date_time_range_to_parts(VM&, DateTimeFormat&, double start, double end);
ThrowCompletionOr<LocalTime> to_local_time(VM&, double time, StringView calendar, StringView time_zone);
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 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 };

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));
// 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
// 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]].
// 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).
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
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).
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").
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.
LocaleOptions opt {};
@ -250,7 +251,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
PropertyKey const* explicit_format_component = nullptr;
// 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;
// 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
if constexpr (IsIntegral<ValueType>) {
// 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.
if (value.has_value()) {

View file

@ -27,6 +27,6 @@ private:
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).
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));
}

View file

@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts)
}
// 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
@ -111,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range)
auto end_date_number = TRY(end_date.to_number(global_object)).as_double();
// 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));
}
@ -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();
// 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
@ -190,7 +190,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
}
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;
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
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
if (type == DisplayNames::Type::Language) {
// 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]]
};
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);
}

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));
// 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.
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()
// 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).
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));
// 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]].
// 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
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.
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
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).
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let result be a new empty List.
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
// 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]].
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);
// 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
// iv. Let parts be ! MakePartsList(template, unit, num).

View file

@ -218,10 +218,10 @@ struct DurationUnitOptions {
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&);
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<Vector<PatternPartition>> partition_duration_format_pattern(GlobalObject& global_object, DurationFormat const& duration_format, Temporal::DurationRecord const& duration);
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(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));
// 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).
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;
// 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]].
(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).
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.
return duration_format;
@ -150,10 +150,10 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %DurationFormat%.[[AvailableLocales]].
// 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).
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));
// 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.
if (!is_valid_duration_record(record))
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
// 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.
StringBuilder result;
@ -71,14 +71,14 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
auto* duration_format = TRY(typed_this_object(global_object));
// 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.
if (!is_valid_duration_record(record))
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
// 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).
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);
// 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() };
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let parts be ! CreatePartsFromList(listFormat, 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
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
if (iterable.is_undefined()) {

View file

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

View file

@ -55,10 +55,9 @@ Locale::Locale(Unicode::LocaleID const& locale_id, Object& prototype)
}
// 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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
// 1. If restricted is not undefined, then
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
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]].
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);
// 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
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]].
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);
// 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
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]].
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);
// 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
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]].
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);
// 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
// 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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
// 1. Let locale be loc.[[Locale]].
// 2. Assert: locale matches the unicode_locale_id production.

View file

@ -81,12 +81,12 @@ struct WeekInfo {
Vector<u8> weekend; // [[Weekend]]
};
Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale);
Array* collations_of_locale(GlobalObject& global_object, Locale const& locale);
Array* hour_cycles_of_locale(GlobalObject& global_object, Locale const& locale);
Array* numbering_systems_of_locale(GlobalObject& global_object, Locale const& locale);
Array* time_zones_of_locale(GlobalObject& global_object, StringView region);
StringView character_direction_of_locale(Locale const& locale);
WeekInfo week_info_of_locale(Locale const& locale);
Array* calendars_of_locale(VM&, Locale const&);
Array* collations_of_locale(VM&, Locale const& locale);
Array* hour_cycles_of_locale(VM&, Locale const& locale);
Array* numbering_systems_of_locale(VM&, Locale const&);
Array* time_zones_of_locale(VM&, StringView region);
StringView character_direction_of_locale(Locale const&);
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.
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 {}));
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
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.
// 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).
// 5. If language is not undefined, then
// 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).
// 7. If script is not undefined, then
// 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).
// 9. If region is not undefined, then
// 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).
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).
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).
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.
LocaleAndKeys opt {};
@ -295,21 +294,21 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
// 14. If calendar is not undefined, then
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 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).
// 17. If collation is not undefined, then
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 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).
// 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).
// 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).
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
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 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).
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) \
{ \
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
#undef __JS_ENUMERATE
@ -245,7 +245,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::time_zones)
return js_undefined();
// 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

View file

@ -301,10 +301,8 @@ String MathematicalValue::to_string() const
[](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(
[](double value) {
return Value(value);

View file

@ -88,7 +88,7 @@ public:
bool is_zero() const;
String to_string() const;
Value to_value(GlobalObject&) const;
Value to_value(VM&) const;
private:
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();
}
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) {
case UseGrouping::Always:
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
// 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.
int exponent = 0;
@ -574,7 +572,7 @@ Vector<PatternPartition> partition_number_pattern(GlobalObject& global_object, N
Unicode::NumberFormat found_pattern {};
// 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())
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
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).
// 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.
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
// 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).
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
// 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]].
// 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>]].
// f. Let patterns be patterns.[[<unitDisplay>]].
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())
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]].
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 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()) {
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
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).
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
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.
if (start.is_nan())
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "start"sv);
@ -1734,11 +1733,11 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
Vector<PatternPartitionWithSource> result;
// 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));
// 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));
// 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
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).
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.
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 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).
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); }
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);
Notation notation() const { return m_notation; }
@ -274,23 +274,23 @@ enum class RoundingDecision {
int currency_digits(StringView currency);
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_notation_sub_pattern(NumberFormat& number_format, MathematicalValue const& number, String formatted_string, int exponent);
String format_numeric(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number);
Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number);
Vector<PatternPartition> partition_number_pattern(VM&, NumberFormat&, MathematicalValue number);
Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat&, MathematicalValue const& number, String formatted_string, int exponent);
String format_numeric(VM&, NumberFormat&, 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_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<StringView> get_notation_sub_pattern(NumberFormat& number_format, int exponent);
int compute_exponent(NumberFormat& number_format, MathematicalValue number);
int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude);
ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(GlobalObject& global_object, Value value);
NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode rounding_mode, bool is_negative);
Optional<Variant<StringView, String>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, Unicode::NumberFormat& found_pattern);
Optional<StringView> get_notation_sub_pattern(NumberFormat&, int exponent);
int compute_exponent(NumberFormat&, MathematicalValue number);
int compute_exponent_for_magnitude(NumberFormat&, int magnitude);
ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM&, Value value);
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);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end);
Vector<PatternPartitionWithSource> format_approximately(NumberFormat& number_format, Vector<PatternPartitionWithSource> result);
ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pattern(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end);
Vector<PatternPartitionWithSource> format_approximately(NumberFormat&, 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<Array*> format_numeric_range_to_parts(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(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));
// 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
// 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]].
// 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).
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
// 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).
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).
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.
LocaleOptions opt {};
@ -128,7 +129,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
number_format.set_numbering_system(result.nu.release_value());
// 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]].
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());
// 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).
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.
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).
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.
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
// 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).
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").
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
if (has_significant_digits) {
// 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).
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.
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
if (has_fraction_digits) {
// 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).
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).
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
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.
// 2. Assert: Type(options) is Object.

View file

@ -28,8 +28,8 @@ private:
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<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_unit_options(GlobalObject& global_object, NumberFormat& intl_object, Object const& options);
ThrowCompletionOr<NumberFormat*> initialize_number_format(VM&, NumberFormat&, Value locales_value, Value options_value);
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(VM&, NumberFormat& intl_object, Object const& options);
}

View file

@ -34,8 +34,7 @@ void NumberFormatFunction::initialize(Realm& realm)
ThrowCompletionOr<Value> NumberFormatFunction::call()
{
auto& global_object = this->global_object();
auto& vm = global_object.vm();
auto& vm = this->vm();
// 1. Let nf be F.[[NumberFormat]].
// 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);
// 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).
// 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));
}

View file

@ -73,11 +73,11 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts)
auto* number_format = TRY(typed_this_object(global_object));
// 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).
// 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
@ -97,13 +97,13 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range)
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
// 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).
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).
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));
}
@ -124,13 +124,13 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
// 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).
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).
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
@ -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())));
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.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())));
if (number_format->has_compact_display())
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
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.
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
// 3. Assert: Type(x) is Number.

View file

@ -32,9 +32,9 @@ private:
Unicode::PluralOperands get_operands(String const& string);
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 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));
// 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
@ -67,22 +67,23 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesConstructor::supported_locales_of)
// 1. Let availableLocales be %PluralRules%.[[AvailableLocales]].
// 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).
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
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).
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).
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.
LocaleOptions opt {};
@ -100,7 +101,7 @@ ThrowCompletionOr<PluralRules*> initialize_plural_rules(GlobalObject& global_obj
plural_rules.set_type(type.as_string().string());
// 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]].
// 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);
};
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));
// 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));
}

View file

@ -54,10 +54,8 @@ StringView RelativeTimeFormat::numeric_string() const
}
// 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.
// 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
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.
// 2. Assert: Type(value) is Number.
@ -106,7 +105,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaNOrInfinity);
// 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]].
// 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);
// 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).
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
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).
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.
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 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).
auto* result = MUST(Array::create(realm, 0));

View file

@ -81,10 +81,10 @@ struct PatternPartitionWithUnit : public PatternPartition {
StringView unit;
};
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(GlobalObject& global_object, StringView unit);
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit);
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(VM&, 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);
ThrowCompletionOr<String> format_relative_time(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit);
ThrowCompletionOr<Array*> format_relative_time_to_parts(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(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));
// 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
@ -70,22 +70,23 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatConstructor::supported_locales_of)
// 1. Let availableLocales be %RelativeTimeFormat%.[[AvailableLocales]].
// 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).
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
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).
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).
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.
LocaleOptions opt {};

View file

@ -27,6 +27,6 @@ private:
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));
// 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));
}
@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format_to_parts)
auto unit = TRY(vm.argument(1).to_string(global_object));
// 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

View file

@ -60,7 +60,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
iterator->set_iterated_string_next_segment_code_unit_index(end_index);
// 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).
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
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 = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let len be the length of string.
auto length = string.length_in_code_units();

View file

@ -36,7 +36,7 @@ private:
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 {
Before,
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));
// 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).
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]].
// 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).
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());
// 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

View file

@ -331,7 +331,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string)
// 3. Return ? FormatNumeric(numberFormat, x).
// 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));
}

View file

@ -326,8 +326,10 @@ enum class TargetCase {
// 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)
{
auto& vm = global_object.vm();
// 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;

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);
}
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: ");
print_value(js_string(number_format.vm(), number_format.rounding_type_string()), seen_objects);
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);
}
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;
if (!option.has_value())