LibJS: Migrate Temporal updates to ECMA-262 AOs to the main AO file

These are going to be included in the ECMA-262 AOs once Temporal reaches
stage 4. There's no need to keep them in the Temporal namespace. Some
upcoming Temporal editorial changes will get awkward without this patch.
This commit is contained in:
Timothy Flynn 2025-02-28 12:15:49 -05:00 committed by Andreas Kling
parent ea52952774
commit a8d6e5c3db
Notes: github-actions[bot] 2025-03-01 13:50:43 +00:00
13 changed files with 183 additions and 218 deletions

View file

@ -36,6 +36,7 @@
#include <LibJS/Runtime/Reference.h>
#include <LibJS/Runtime/StringPrototype.h>
#include <LibJS/Runtime/SuppressedError.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibJS/Runtime/ValueInlines.h>
namespace JS {
@ -1810,4 +1811,127 @@ ThrowCompletionOr<Value> perform_import_call(VM& vm, Value specifier, Value opti
return Value { promise_capability->promise() };
}
// 14.5.2.1 GetOptionsObject ( options ), https://tc39.es/proposal-temporal/#sec-getoptionsobject
ThrowCompletionOr<GC::Ref<Object>> get_options_object(VM& vm, Value options)
{
auto& realm = *vm.current_realm();
// 1. If options is undefined, then
if (options.is_undefined()) {
// a. Return OrdinaryObjectCreate(null).
return Object::create(realm, nullptr);
}
// 2. If options is an Object, then
if (options.is_object()) {
// a. Return options.
return options.as_object();
}
// 3. Throw a TypeError exception.
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Options");
}
// 14.5.2.2 GetOption ( options, property, type, values, default ), https://tc39.es/proposal-temporal/#sec-getoption
ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey const& property, OptionType type, ReadonlySpan<StringView> values, OptionDefault const& default_)
{
VERIFY(property.is_string());
// 1. Let value be ? Get(options, property).
auto value = TRY(options.get(property));
// 2. If value is undefined, then
if (value.is_undefined()) {
// a. If default is REQUIRED, throw a RangeError exception.
if (default_.has<Required>())
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, "undefined"sv, property.as_string());
// b. Return default.
return default_.visit(
[](Required) -> Value { VERIFY_NOT_REACHED(); },
[](Empty) -> Value { return js_undefined(); },
[](bool default_) -> Value { return Value { default_ }; },
[](double default_) -> Value { return Value { default_ }; },
[&](StringView default_) -> Value { return PrimitiveString::create(vm, default_); });
}
// 3. If type is BOOLEAN, then
if (type == OptionType::Boolean) {
// a. Set value to ToBoolean(value).
value = Value { value.to_boolean() };
}
// 4. Else,
else {
// a. Assert: type is STRING.
VERIFY(type == OptionType::String);
// b. Set value to ? ToString(value).
value = TRY(value.to_primitive_string(vm));
}
// 5. If values is not EMPTY and values does not contain value, throw a RangeError exception.
if (!values.is_empty()) {
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
VERIFY(value.is_string());
if (auto value_string = value.as_string().utf8_string(); !values.contains_slow(value_string))
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value_string, property.as_string());
}
// 6. Return value.
return value;
}
// 14.5.2.3 GetRoundingModeOption ( options, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-getroundingmodeoption
ThrowCompletionOr<RoundingMode> get_rounding_mode_option(VM& vm, Object const& options, RoundingMode fallback)
{
// 1. Let allowedStrings be the List of Strings from the "String Identifier" column of Table 26.
static constexpr auto allowed_strings = to_array({ "ceil"sv, "floor"sv, "expand"sv, "trunc"sv, "halfCeil"sv, "halfFloor"sv, "halfExpand"sv, "halfTrunc"sv, "halfEven"sv });
// 2. Let stringFallback be the value from the "String Identifier" column of the row with fallback in its "Rounding Mode" column.
auto string_fallback = allowed_strings[to_underlying(fallback)];
// 3. Let stringValue be ? GetOption(options, "roundingMode", STRING, allowedStrings, stringFallback).
auto string_value = TRY(get_option(vm, options, vm.names.roundingMode, OptionType::String, allowed_strings, string_fallback));
// 4. Return the value from the "Rounding Mode" column of the row with stringValue in its "String Identifier" column.
return static_cast<RoundingMode>(allowed_strings.first_index_of(string_value.as_string().utf8_string_view()).value());
}
// 14.5.2.4 GetRoundingIncrementOption ( options ), https://tc39.es/proposal-temporal/#sec-temporal-getroundingincrementoption
ThrowCompletionOr<u64> get_rounding_increment_option(VM& vm, Object const& options)
{
// 1. Let value be ? Get(options, "roundingIncrement").
auto value = TRY(options.get(vm.names.roundingIncrement));
// 2. If value is undefined, return 1𝔽.
if (value.is_undefined())
return 1;
// 3. Let integerIncrement be ? ToIntegerWithTruncation(value).
auto integer_increment = TRY(Temporal::to_integer_with_truncation(vm, value, ErrorType::OptionIsNotValidValue, value, "roundingIncrement"sv));
// 4. If integerIncrement < 1 or integerIncrement > 10**9, throw a RangeError exception.
if (integer_increment < 1 || integer_increment > 1'000'000'000u)
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value, "roundingIncrement");
// 5. Return integerIncrement.
return static_cast<u64>(integer_increment);
}
// AD-HOC
// FIXME: We should add a generic floor() method to our BigInt classes. But for now, since we know we are only dividing
// by powers of 10, we can implement a very situationally specific method to compute the floor of a division.
Crypto::SignedBigInteger big_floor(Crypto::SignedBigInteger const& numerator, Crypto::UnsignedBigInteger const& denominator)
{
auto result = numerator.divided_by(denominator);
if (result.remainder.is_zero())
return result.quotient;
if (!result.quotient.is_negative() && result.remainder.is_positive())
return result.quotient;
return result.quotient.minus(Crypto::SignedBigInteger { 1 });
}
}

View file

@ -163,35 +163,6 @@ ThrowCompletionOr<GC::Ref<T>> ordinary_create_from_constructor(VM& vm, FunctionO
return realm.create<T>(forward<Args>(args)..., *prototype);
}
// 14.1 MergeLists ( a, b ), https://tc39.es/proposal-temporal/#sec-temporal-mergelists
template<typename T>
Vector<T> merge_lists(Vector<T> const& a, Vector<T> const& b)
{
// 1. Let merged be a new empty List.
Vector<T> merged;
// 2. For each element element of a, do
for (auto const& element : a) {
// a. If merged does not contain element, then
if (!merged.contains_slow(element)) {
// i. Append element to merged.
merged.append(element);
}
}
// 3. For each element element of b, do
for (auto const& element : b) {
// a. If merged does not contain element, then
if (!merged.contains_slow(element)) {
// i. Append element to merged.
merged.append(element);
}
}
// 4. Return merged.
return merged;
}
// 7.3.35 AddValueToKeyedGroup ( groups, key, value ), https://tc39.es/ecma262/#sec-add-value-to-keyed-group
template<typename GroupsType, typename KeyType>
void add_value_to_keyed_group(VM& vm, GroupsType& groups, KeyType key, Value value)
@ -348,4 +319,45 @@ auto remainder(Crypto::BigInteger auto const& x, Crypto::BigInteger auto const&
return x.divided_by(y).remainder;
}
// 14.3 The Year-Week Record Specification Type, https://tc39.es/proposal-temporal/#sec-year-week-record-specification-type
struct YearWeek {
Optional<u8> week;
Optional<i32> year;
};
enum class OptionType {
Boolean,
String,
};
struct Required { };
using OptionDefault = Variant<Required, Empty, bool, StringView, double>;
ThrowCompletionOr<GC::Ref<Object>> get_options_object(VM&, Value options);
ThrowCompletionOr<Value> get_option(VM&, Object const& options, PropertyKey const& property, OptionType type, ReadonlySpan<StringView> values, OptionDefault const&);
template<size_t Size>
ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey const& property, OptionType type, StringView const (&values)[Size], OptionDefault const& default_)
{
return get_option(vm, options, property, type, ReadonlySpan<StringView> { values }, default_);
}
// https://tc39.es/proposal-temporal/#table-temporal-rounding-modes
enum class RoundingMode {
Ceil,
Floor,
Expand,
Trunc,
HalfCeil,
HalfFloor,
HalfExpand,
HalfTrunc,
HalfEven,
};
ThrowCompletionOr<RoundingMode> get_rounding_mode_option(VM&, Object const& options, RoundingMode fallback);
ThrowCompletionOr<u64> get_rounding_increment_option(VM&, Object const& options);
Crypto::SignedBigInteger big_floor(Crypto::SignedBigInteger const& numerator, Crypto::UnsignedBigInteger const& denominator);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -9,6 +9,7 @@
#include <AK/Find.h>
#include <AK/QuickSort.h>
#include <AK/TypeCasts.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/AbstractOperations.h>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -13,7 +13,6 @@
#include <LibJS/Forward.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibJS/Runtime/Value.h>
#include <LibUnicode/Locale.h>
@ -72,9 +71,4 @@ ThrowCompletionOr<StringOrBoolean> get_boolean_or_string_number_format_option(VM
return get_boolean_or_string_number_format_option(vm, options, property, ReadonlySpan<StringView> { string_values }, move(fallback));
}
// NOTE: ECMA-402's GetOption is being removed in favor of a shared ECMA-262 GetOption in the Temporal proposal.
// Until Temporal is merged into ECMA-262, our implementation lives in the Temporal-specific AO file & namespace.
using Temporal::get_option;
using Temporal::OptionType;
}

View file

@ -485,7 +485,7 @@ bool same_temporal_type(FormattableDateTime const& x, FormattableDateTime const&
static double to_epoch_milliseconds(Crypto::SignedBigInteger const& epoch_nanoseconds)
{
return Temporal::big_floor(epoch_nanoseconds, Temporal::NANOSECONDS_PER_MILLISECOND).to_double();
return big_floor(epoch_nanoseconds, Temporal::NANOSECONDS_PER_MILLISECOND).to_double();
}
// 15.9.15 HandleDateTimeTemporalDate ( dateTimeFormat, temporalDate ), https://tc39.es/proposal-temporal/#sec-temporal-handledatetimetemporaldate

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -10,7 +10,6 @@
#include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Intl/DisplayNames.h>
#include <LibJS/Runtime/Intl/DisplayNamesConstructor.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibUnicode/Locale.h>
namespace JS::Intl {
@ -64,7 +63,7 @@ ThrowCompletionOr<GC::Ref<Object>> DisplayNamesConstructor::construct(FunctionOb
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "options"sv);
// 5. Set options to ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 6. Let opt be a new Record.
LocaleOptions opt {};

View file

@ -60,7 +60,7 @@ ThrowCompletionOr<GC::Ref<Object>> DurationFormatConstructor::construct(Function
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 4. Let options be ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 5. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));

View file

@ -10,7 +10,6 @@
#include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Intl/ListFormat.h>
#include <LibJS/Runtime/Intl/ListFormatConstructor.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
namespace JS::Intl {
@ -59,7 +58,7 @@ ThrowCompletionOr<GC::Ref<Object>> ListFormatConstructor::construct(FunctionObje
auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));
// 4. Set options to ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 5. Let opt be a new Record.
LocaleOptions opt {};

View file

@ -5,6 +5,7 @@
*/
#include <LibJS/Runtime/Intl/PluralRules.h>
#include <LibJS/Runtime/VM.h>
namespace JS::Intl {

View file

@ -11,7 +11,6 @@
#include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Intl/Segmenter.h>
#include <LibJS/Runtime/Intl/SegmenterConstructor.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
namespace JS::Intl {
@ -60,7 +59,7 @@ ThrowCompletionOr<GC::Ref<Object>> SegmenterConstructor::construct(FunctionObjec
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
// 5. Set options to ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 6. Let opt be a new Record.
LocaleOptions opt {};

View file

@ -2,13 +2,12 @@
* Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCrypto/BigFraction/BigFraction.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/PropertyKey.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
@ -1799,127 +1798,4 @@ ThrowCompletionOr<DifferenceSettings> get_difference_settings(VM& vm, DurationOp
return DifferenceSettings { .smallest_unit = smallest_unit_value, .largest_unit = largest_unit_value, .rounding_mode = rounding_mode, .rounding_increment = rounding_increment };
}
// 14.4.1.1 GetOptionsObject ( options ), https://tc39.es/proposal-temporal/#sec-getoptionsobject
ThrowCompletionOr<GC::Ref<Object>> get_options_object(VM& vm, Value options)
{
auto& realm = *vm.current_realm();
// 1. If options is undefined, then
if (options.is_undefined()) {
// a. Return OrdinaryObjectCreate(null).
return Object::create(realm, nullptr);
}
// 2. If options is an Object, then
if (options.is_object()) {
// a. Return options.
return options.as_object();
}
// 3. Throw a TypeError exception.
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Options");
}
// 14.4.1.2 GetOption ( options, property, type, values, default ), https://tc39.es/proposal-temporal/#sec-getoption
ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey const& property, OptionType type, ReadonlySpan<StringView> values, OptionDefault const& default_)
{
VERIFY(property.is_string());
// 1. Let value be ? Get(options, property).
auto value = TRY(options.get(property));
// 2. If value is undefined, then
if (value.is_undefined()) {
// a. If default is REQUIRED, throw a RangeError exception.
if (default_.has<Required>())
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, "undefined"sv, property.as_string());
// b. Return default.
return default_.visit(
[](Required) -> Value { VERIFY_NOT_REACHED(); },
[](Empty) -> Value { return js_undefined(); },
[](bool default_) -> Value { return Value { default_ }; },
[](double default_) -> Value { return Value { default_ }; },
[&](StringView default_) -> Value { return PrimitiveString::create(vm, default_); });
}
// 3. If type is BOOLEAN, then
if (type == OptionType::Boolean) {
// a. Set value to ToBoolean(value).
value = Value { value.to_boolean() };
}
// 4. Else,
else {
// a. Assert: type is STRING.
VERIFY(type == OptionType::String);
// b. Set value to ? ToString(value).
value = TRY(value.to_primitive_string(vm));
}
// 5. If values is not EMPTY and values does not contain value, throw a RangeError exception.
if (!values.is_empty()) {
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
VERIFY(value.is_string());
if (auto value_string = value.as_string().utf8_string(); !values.contains_slow(value_string))
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value_string, property.as_string());
}
// 6. Return value.
return value;
}
// 14.4.1.3 GetRoundingModeOption ( options, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-getroundingmodeoption
ThrowCompletionOr<RoundingMode> get_rounding_mode_option(VM& vm, Object const& options, RoundingMode fallback)
{
// 1. Let allowedStrings be the List of Strings from the "String Identifier" column of Table 26.
static constexpr auto allowed_strings = to_array({ "ceil"sv, "floor"sv, "expand"sv, "trunc"sv, "halfCeil"sv, "halfFloor"sv, "halfExpand"sv, "halfTrunc"sv, "halfEven"sv });
// 2. Let stringFallback be the value from the "String Identifier" column of the row with fallback in its "Rounding Mode" column.
auto string_fallback = allowed_strings[to_underlying(fallback)];
// 3. Let stringValue be ? GetOption(options, "roundingMode", STRING, allowedStrings, stringFallback).
auto string_value = TRY(get_option(vm, options, vm.names.roundingMode, OptionType::String, allowed_strings, string_fallback));
// 4. Return the value from the "Rounding Mode" column of the row with stringValue in its "String Identifier" column.
return static_cast<RoundingMode>(allowed_strings.first_index_of(string_value.as_string().utf8_string_view()).value());
}
// 14.4.1.4 GetRoundingIncrementOption ( options ), https://tc39.es/proposal-temporal/#sec-temporal-getroundingincrementoption
ThrowCompletionOr<u64> get_rounding_increment_option(VM& vm, Object const& options)
{
// 1. Let value be ? Get(options, "roundingIncrement").
auto value = TRY(options.get(vm.names.roundingIncrement));
// 2. If value is undefined, return 1𝔽.
if (value.is_undefined())
return 1;
// 3. Let integerIncrement be ? ToIntegerWithTruncation(value).
auto integer_increment = TRY(to_integer_with_truncation(vm, value, ErrorType::OptionIsNotValidValue, value, "roundingIncrement"sv));
// 4. If integerIncrement < 1 or integerIncrement > 10**9, throw a RangeError exception.
if (integer_increment < 1 || integer_increment > 1'000'000'000u)
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value, "roundingIncrement");
// 5. Return integerIncrement.
return static_cast<u64>(integer_increment);
}
// AD-HOC
// FIXME: We should add a generic floor() method to our BigInt classes. But for now, since we know we are only dividing
// by powers of 10, we can implement a very situationally specific method to compute the floor of a division.
Crypto::SignedBigInteger big_floor(Crypto::SignedBigInteger const& numerator, Crypto::UnsignedBigInteger const& denominator)
{
auto result = numerator.divided_by(denominator);
if (result.remainder.is_zero())
return result.quotient;
if (!result.quotient.is_negative() && result.remainder.is_positive())
return result.quotient;
return result.quotient.minus(Crypto::SignedBigInteger { 1 });
}
}

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -13,6 +13,7 @@
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/Temporal/ISO8601.h>
#include <LibJS/Runtime/Temporal/ISORecords.h>
@ -113,19 +114,6 @@ enum class UnitGroup {
DateTime,
};
// https://tc39.es/proposal-temporal/#table-unsigned-rounding-modes
enum class RoundingMode {
Ceil,
Floor,
Expand,
Trunc,
HalfCeil,
HalfFloor,
HalfExpand,
HalfTrunc,
HalfEven,
};
// https://tc39.es/proposal-temporal/#table-unsigned-rounding-modes
enum class UnsignedRoundingMode {
HalfEven,
@ -142,7 +130,6 @@ enum class Sign {
};
struct Auto { };
struct Required { };
struct Unset { };
using Precision = Variant<Auto, u8>;
using RoundingIncrement = Variant<Unset, u64>;
@ -271,31 +258,4 @@ ThrowCompletionOr<double> to_integer_if_integral(VM& vm, Value argument, ErrorTy
return number.as_double();
}
// 14.2 The Year-Week Record Specification Type, https://tc39.es/proposal-temporal/#sec-year-week-record-specification-type
struct YearWeek {
Optional<u8> week;
Optional<i32> year;
};
enum class OptionType {
Boolean,
String,
};
using OptionDefault = Variant<Required, Empty, bool, StringView, double>;
ThrowCompletionOr<GC::Ref<Object>> get_options_object(VM&, Value options);
ThrowCompletionOr<Value> get_option(VM&, Object const& options, PropertyKey const& property, OptionType type, ReadonlySpan<StringView> values, OptionDefault const&);
template<size_t Size>
ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey const& property, OptionType type, StringView const (&values)[Size], OptionDefault const& default_)
{
return get_option(vm, options, property, type, ReadonlySpan<StringView> { values }, default_);
}
ThrowCompletionOr<RoundingMode> get_rounding_mode_option(VM&, Object const& options, RoundingMode fallback);
ThrowCompletionOr<u64> get_rounding_increment_option(VM&, Object const& options);
Crypto::SignedBigInteger big_floor(Crypto::SignedBigInteger const& numerator, Crypto::UnsignedBigInteger const& denominator);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -7,7 +7,7 @@
#include <AK/Base64.h>
#include <AK/StringBuilder.h>
#include <AK/StringUtils.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/TypedArray.h>
#include <LibJS/Runtime/Uint8Array.h>
#include <LibJS/Runtime/VM.h>
@ -87,7 +87,7 @@ JS_DEFINE_NATIVE_FUNCTION(Uint8ArrayPrototypeHelpers::to_base64)
auto typed_array = TRY(validate_uint8_array(vm));
// 3. Let opts be ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 4. Let alphabet be ? Get(opts, "alphabet").
// 5. If alphabet is undefined, set alphabet to "base64".
@ -159,7 +159,7 @@ JS_DEFINE_NATIVE_FUNCTION(Uint8ArrayConstructorHelpers::from_base64)
return vm.throw_completion<TypeError>(ErrorType::NotAString, string_value);
// 2. Let opts be ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 3. Let alphabet be ? Get(opts, "alphabet").
// 4. If alphabet is undefined, set alphabet to "base64".
@ -214,7 +214,7 @@ JS_DEFINE_NATIVE_FUNCTION(Uint8ArrayPrototypeHelpers::set_from_base64)
return vm.throw_completion<TypeError>(ErrorType::NotAString, string_value);
// 4. Let opts be ? GetOptionsObject(options).
auto options = TRY(Temporal::get_options_object(vm, options_value));
auto options = TRY(get_options_object(vm, options_value));
// 5. Let alphabet be ? Get(opts, "alphabet").
// 6. If alphabet is undefined, set alphabet to "base64".