diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-10-14 09:47:17 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-10-15 18:05:02 +0200 |
commit | 1a84dbcb07c2edec252b414e273107d50fe2deff (patch) | |
tree | d2f65a81a6a7f9135a4f9f1a2d9b898e4fb0e8a0 /Userland/Libraries/LibJS/Runtime | |
parent | 4fbec2e8b3141ca5b895d7c9bb17f8b0cf22bca2 (diff) | |
download | serenity-1a84dbcb07c2edec252b414e273107d50fe2deff.zip |
LibJS: Replace GetEpochFromISOParts with GetUTCEpochNanoseconds
This is an editorial change in the Temporal spec. See:
https://github.com/tc39/proposal-temporal/commit/1b051cc
Note that since Date's implementation of this AO uses Crypto bigints
rather than allocating JS bigints, this change has the fallout of
removing some unused VM parameters and adding an overload of the
IsValidEpochNanoseconds AO for use without a JS::BigInt.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
11 files changed, 56 insertions, 72 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp index 48a12782eb..c8da9ebb02 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp @@ -9,6 +9,7 @@ #include <LibCrypto/BigInt/SignedBigInteger.h> #include <LibJS/Runtime/AbstractOperations.h> #include <LibJS/Runtime/Completion.h> +#include <LibJS/Runtime/Date.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/Temporal/AbstractOperations.h> #include <LibJS/Runtime/Temporal/Calendar.h> @@ -37,10 +38,16 @@ void Instant::visit_edges(Cell::Visitor& visitor) // 8.5.1 IsValidEpochNanoseconds ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidepochnanoseconds bool is_valid_epoch_nanoseconds(BigInt const& epoch_nanoseconds) { + return is_valid_epoch_nanoseconds(epoch_nanoseconds.big_integer()); +} + +// 8.5.1 IsValidEpochNanoseconds ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidepochnanoseconds +bool is_valid_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds) +{ // 1. Assert: Type(epochNanoseconds) is BigInt. // 2. If โ(epochNanoseconds) < nsMinInstant or โ(epochNanoseconds) > nsMaxInstant, then - if (epoch_nanoseconds.big_integer() < ns_min_instant || epoch_nanoseconds.big_integer() > ns_max_instant) { + if (epoch_nanoseconds < ns_min_instant || epoch_nanoseconds > ns_max_instant) { // a. Return false. return false; } @@ -115,23 +122,23 @@ ThrowCompletionOr<BigInt*> parse_temporal_instant(VM& vm, String const& iso_stri // 4. Assert: offsetString is not undefined. VERIFY(offset_string.has_value()); - // 5. Let utc be GetEpochFromISOParts(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]). - auto* utc = get_epoch_from_iso_parts(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond); + // 5. Let utc be GetUTCEpochNanoseconds(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]). + auto utc = get_utc_epoch_nanoseconds(result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond); // 6. Let offsetNanoseconds be ? ParseTimeZoneOffsetString(offsetString). auto offset_nanoseconds = TRY(parse_time_zone_offset_string(vm, *offset_string)); // 7. Let result be utc - โค(offsetNanoseconds). - auto* result_ns = js_bigint(vm, utc->big_integer().minus(Crypto::SignedBigInteger { offset_nanoseconds })); + auto result_ns = utc.minus(Crypto::SignedBigInteger { offset_nanoseconds }); // 8. If ! IsValidEpochNanoseconds(result) is false, then - if (!is_valid_epoch_nanoseconds(*result_ns)) { + if (!is_valid_epoch_nanoseconds(result_ns)) { // a. Throw a RangeError exception. return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidEpochNanoseconds); } // 9. Return result. - return result_ns; + return js_bigint(vm, move(result_ns)); } // 8.5.5 CompareEpochNanoseconds ( epochNanosecondsOne, epochNanosecondsTwo ), https://tc39.es/proposal-temporal/#sec-temporal-compareepochnanoseconds diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.h b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.h index 0403db891b..3ec4dca6cd 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Instant.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Instant.h @@ -42,6 +42,7 @@ static auto const ns_max_instant = "8640000000000000000000"_sbigint; static auto const ns_min_instant = "-8640000000000000000000"_sbigint; bool is_valid_epoch_nanoseconds(BigInt const& epoch_nanoseconds); +bool is_valid_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds); ThrowCompletionOr<Instant*> create_temporal_instant(VM&, BigInt const& nanoseconds, FunctionObject const* new_target = nullptr); ThrowCompletionOr<Instant*> to_temporal_instant(VM&, Value item); ThrowCompletionOr<BigInt*> parse_temporal_instant(VM&, String const& iso_string); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index c9986cfa20..88551078de 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -62,7 +62,7 @@ ThrowCompletionOr<PlainDate*> create_temporal_date(VM& vm, i32 iso_year, u8 iso_ return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainDate); // 6. If ISODateTimeWithinLimits(isoYear, isoMonth, isoDay, 12, 0, 0, 0, 0, 0) is false, throw a RangeError exception. - if (!iso_date_time_within_limits(vm, iso_year, iso_month, iso_day, 12, 0, 0, 0, 0, 0)) + if (!iso_date_time_within_limits(iso_year, iso_month, iso_day, 12, 0, 0, 0, 0, 0)) return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainDate); // 7. If newTarget is not present, set newTarget to %Temporal.PlainDate%. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp index 173cb5874b..18453bad8a 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp @@ -44,42 +44,19 @@ void PlainDateTime::visit_edges(Visitor& visitor) visitor.visit(&m_calendar); } -// 5.5.1 GetEpochFromISOParts ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-getepochfromisoparts -BigInt* get_epoch_from_iso_parts(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond) -{ - // 1. Assert: IsValidISODate(year, month, day) is true. - VERIFY(is_valid_iso_date(year, month, day)); - - // 2. Let date be MakeDay(๐ฝ(year), ๐ฝ(month - 1), ๐ฝ(day)). - auto date = make_day(year, month - 1, day); - - // 3. Let time be MakeTime(๐ฝ(hour), ๐ฝ(minute), ๐ฝ(second), ๐ฝ(millisecond)). - auto time = make_time(hour, minute, second, millisecond); - - // 4. Let ms be MakeDate(date, time). - auto ms = make_date(date, time); - - // 5. Assert: ms is finite. - VERIFY(isfinite(ms)); - - // 6. Return โค(โ(ms) ร 10^6 + microsecond ร 10^3 + nanosecond). - i32 signed_nanoseconds = nanosecond; - return js_bigint(vm, Crypto::SignedBigInteger { ms }.multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 }).plus(Crypto::SignedBigInteger { microsecond * 1000 }).plus(Crypto::SignedBigInteger { signed_nanoseconds })); -} - // nsMinInstant - nsPerDay auto const DATETIME_NANOSECONDS_MIN = "-8640000086400000000000"_sbigint; // nsMaxInstant + nsPerDay auto const DATETIME_NANOSECONDS_MAX = "8640000086400000000000"_sbigint; -// 5.5.2 ISODateTimeWithinLimits ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-isodatetimewithinlimits -bool iso_date_time_within_limits(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond) +// 5.5.1 ISODateTimeWithinLimits ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-isodatetimewithinlimits +bool iso_date_time_within_limits(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond) { // 1. Assert: IsValidISODate(year, month, day) is true. VERIFY(is_valid_iso_date(year, month, day)); - // 2. Let ns be โ(GetEpochFromISOParts(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)). - auto ns = get_epoch_from_iso_parts(vm, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)->big_integer(); + // 2. Let ns be โ(GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)). + auto ns = get_utc_epoch_nanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond); // 3. If ns โค nsMinInstant - nsPerDay, then if (ns <= DATETIME_NANOSECONDS_MIN) { @@ -96,7 +73,7 @@ bool iso_date_time_within_limits(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 return true; } -// 5.5.3 InterpretTemporalDateTimeFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-interprettemporaldatetimefields +// 5.5.2 InterpretTemporalDateTimeFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-interprettemporaldatetimefields ThrowCompletionOr<ISODateTime> interpret_temporal_date_time_fields(VM& vm, Object& calendar, Object& fields, Object const& options) { // 1. Let timeResult be ? ToTemporalTimeRecord(fields). @@ -125,7 +102,7 @@ ThrowCompletionOr<ISODateTime> interpret_temporal_date_time_fields(VM& vm, Objec }; } -// 5.5.4 ToTemporalDateTime ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldatetime +// 5.5.3 ToTemporalDateTime ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldatetime ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(VM& vm, Value item, Object const* options) { // 1. If options is not present, set options to undefined. @@ -206,7 +183,7 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(VM& vm, Value item, Obje return create_temporal_date_time(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar); } -// 5.5.5 BalanceISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-balanceisodatetime +// 5.5.4 BalanceISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-balanceisodatetime ISODateTime balance_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, i64 nanosecond) { // NOTE: The only use of this AO is in BuiltinTimeZoneGetPlainDateTimeFor, where we know that all values @@ -225,7 +202,7 @@ ISODateTime balance_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute return ISODateTime { .year = balanced_date.year, .month = balanced_date.month, .day = balanced_date.day, .hour = balanced_time.hour, .minute = balanced_time.minute, .second = balanced_time.second, .millisecond = balanced_time.millisecond, .microsecond = balanced_time.microsecond, .nanosecond = balanced_time.nanosecond }; } -// 5.5.6 CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporaldatetime +// 5.5.5 CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporaldatetime ThrowCompletionOr<PlainDateTime*> create_temporal_date_time(VM& vm, i32 iso_year, u8 iso_month, u8 iso_day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Object& calendar, FunctionObject const* new_target) { auto& realm = *vm.current_realm(); @@ -242,7 +219,7 @@ ThrowCompletionOr<PlainDateTime*> create_temporal_date_time(VM& vm, i32 iso_year return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainDateTime); // 5. If ISODateTimeWithinLimits(isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond) is false, then - if (!iso_date_time_within_limits(vm, iso_year, iso_month, iso_day, hour, minute, second, millisecond, microsecond, nanosecond)) { + if (!iso_date_time_within_limits(iso_year, iso_month, iso_day, hour, minute, second, millisecond, microsecond, nanosecond)) { // a. Throw a RangeError exception. return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainDateTime); } @@ -268,7 +245,7 @@ ThrowCompletionOr<PlainDateTime*> create_temporal_date_time(VM& vm, i32 iso_year return object; } -// 5.5.7 TemporalDateTimeToString ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar, precision, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporaldatetimetostring +// 5.5.6 TemporalDateTimeToString ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar, precision, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporaldatetimetostring ThrowCompletionOr<String> temporal_date_time_to_string(VM& vm, i32 iso_year, u8 iso_month, u8 iso_day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Object const* calendar, Variant<StringView, u8> const& precision, StringView show_calendar) { // 1. Assert: isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, and nanosecond are integers. @@ -289,7 +266,7 @@ ThrowCompletionOr<String> temporal_date_time_to_string(VM& vm, i32 iso_year, u8 return String::formatted("{}-{:02}-{:02}T{:02}:{:02}{}{}", pad_iso_year(iso_year), iso_month, iso_day, hour, minute, seconds, calendar_string); } -// 5.5.8 CompareISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2 ), https://tc39.es/proposal-temporal/#sec-temporal-compareisodatetime +// 5.5.7 CompareISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2 ), https://tc39.es/proposal-temporal/#sec-temporal-compareisodatetime i8 compare_iso_date_time(i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2) { // 1. Assert: y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, and ns2 are integers. @@ -307,11 +284,11 @@ i8 compare_iso_date_time(i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 return compare_temporal_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2); } -// 5.5.9 AddDateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddatetime +// 5.5.8 AddDateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddatetime ThrowCompletionOr<TemporalPlainDateTime> add_date_time(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options) { // 1. Assert: ISODateTimeWithinLimits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond) is true. - VERIFY(iso_date_time_within_limits(vm, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)); + VERIFY(iso_date_time_within_limits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)); // 2. Let timeResult be ! AddTime(hour, minute, second, millisecond, microsecond, nanosecond, hours, minutes, seconds, milliseconds, microseconds, nanoseconds). auto time_result = add_time(hour, minute, second, millisecond, microsecond, nanosecond, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); @@ -329,13 +306,13 @@ ThrowCompletionOr<TemporalPlainDateTime> add_date_time(VM& vm, i32 year, u8 mont return TemporalPlainDateTime { .year = added_date->iso_year(), .month = added_date->iso_month(), .day = added_date->iso_day(), .hour = time_result.hour, .minute = time_result.minute, .second = time_result.second, .millisecond = time_result.millisecond, .microsecond = time_result.microsecond, .nanosecond = time_result.nanosecond }; } -// 5.5.10 RoundISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, roundingMode [ , dayLength ] ), https://tc39.es/proposal-temporal/#sec-temporal-roundisodatetime -ISODateTime round_iso_date_time(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, u64 increment, StringView unit, StringView rounding_mode, Optional<double> day_length) +// 5.5.9 RoundISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, roundingMode [ , dayLength ] ), https://tc39.es/proposal-temporal/#sec-temporal-roundisodatetime +ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, u64 increment, StringView unit, StringView rounding_mode, Optional<double> day_length) { // 1. Assert: year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond are integers. // 2. Assert: ISODateTimeWithinLimits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond) is true. - VERIFY(iso_date_time_within_limits(vm, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)); + VERIFY(iso_date_time_within_limits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)); // 3. If dayLength is not present, set dayLength to nsPerDay. if (!day_length.has_value()) @@ -351,14 +328,14 @@ ISODateTime round_iso_date_time(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8 return ISODateTime { .year = balance_result.year, .month = balance_result.month, .day = balance_result.day, .hour = rounded_time.hour, .minute = rounded_time.minute, .second = rounded_time.second, .millisecond = rounded_time.millisecond, .microsecond = rounded_time.microsecond, .nanosecond = rounded_time.nanosecond }; } -// 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit, options ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime +// 5.5.10 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit, options ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime ThrowCompletionOr<DurationRecord> difference_iso_date_time(VM& vm, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object const& options) { // 1. Assert: ISODateTimeWithinLimits(y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1) is true. - VERIFY(iso_date_time_within_limits(vm, year1, month1, day1, hour1, minute1, second1, millisecond1, microsecond1, nanosecond1)); + VERIFY(iso_date_time_within_limits(year1, month1, day1, hour1, minute1, second1, millisecond1, microsecond1, nanosecond1)); // 2. Assert: ISODateTimeWithinLimits(y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2) is true. - VERIFY(iso_date_time_within_limits(vm, year2, month2, day2, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2)); + VERIFY(iso_date_time_within_limits(year2, month2, day2, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2)); // 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2). auto time_difference = difference_time(vm, hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2); @@ -403,7 +380,7 @@ ThrowCompletionOr<DurationRecord> difference_iso_date_time(VM& vm, i32 year1, u8 return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds); } -// 5.5.12 DifferenceTemporalPlainDateTime ( operation, dateTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaindatetime +// 5.5.11 DifferenceTemporalPlainDateTime ( operation, dateTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaindatetime ThrowCompletionOr<Duration*> difference_temporal_plain_date_time(VM& vm, DifferenceOperation operation, PlainDateTime& date_time, Value other_value, Value options_value) { // 1. If operation is since, let sign be -1. Otherwise, let sign be 1. @@ -435,7 +412,7 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_date_time(VM& vm, Differe return MUST(create_temporal_duration(vm, sign * round_result.years, sign * round_result.months, sign * round_result.weeks, sign * result.days, sign * result.hours, sign * result.minutes, sign * result.seconds, sign * result.milliseconds, sign * result.microseconds, sign * result.nanoseconds)); } -// 5.5.13 AddDurationToOrSubtractDurationFromPlainDateTime ( operation, dateTime, temporalDurationLike, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoorsubtractdurationfromplaindatetime +// 5.5.12 AddDurationToOrSubtractDurationFromPlainDateTime ( operation, dateTime, temporalDurationLike, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoorsubtractdurationfromplaindatetime ThrowCompletionOr<PlainDateTime*> add_duration_to_or_subtract_duration_from_plain_date_time(VM& vm, ArithmeticOperation operation, PlainDateTime& date_time, Value temporal_duration_like, Value options_value) { // 1. If operation is subtract, let sign be -1. Otherwise, let sign be 1. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h index 8122772d2e..7b3f0aa046 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h @@ -64,8 +64,7 @@ struct TemporalPlainDateTime { u16 nanosecond; }; -BigInt* get_epoch_from_iso_parts(VM&, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond); -bool iso_date_time_within_limits(VM&, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond); +bool iso_date_time_within_limits(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond); ThrowCompletionOr<ISODateTime> interpret_temporal_date_time_fields(VM&, Object& calendar, Object& fields, Object const& options); ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(VM&, Value item, Object const* options = nullptr); ISODateTime balance_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, i64 nanosecond); @@ -73,7 +72,7 @@ ThrowCompletionOr<PlainDateTime*> create_temporal_date_time(VM&, i32 iso_year, u ThrowCompletionOr<String> temporal_date_time_to_string(VM&, i32 iso_year, u8 iso_month, u8 iso_day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Object const* calendar, Variant<StringView, u8> const& precision, StringView show_calendar); i8 compare_iso_date_time(i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2); ThrowCompletionOr<TemporalPlainDateTime> add_date_time(VM&, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options); -ISODateTime round_iso_date_time(VM&, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, u64 increment, StringView unit, StringView rounding_mode, Optional<double> day_length = {}); +ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond, u64 increment, StringView unit, StringView rounding_mode, Optional<double> day_length = {}); ThrowCompletionOr<DurationRecord> difference_iso_date_time(VM&, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object const& options); ThrowCompletionOr<Duration*> difference_temporal_plain_date_time(VM&, DifferenceOperation, PlainDateTime&, Value other, Value options); ThrowCompletionOr<PlainDateTime*> add_duration_to_or_subtract_duration_from_plain_date_time(VM&, ArithmeticOperation, PlainDateTime&, Value temporal_duration_like, Value options_value); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp index 93a4a36a90..22cae0abd9 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp @@ -557,7 +557,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::round) auto rounding_increment = TRY(to_temporal_date_time_rounding_increment(vm, *round_to, *smallest_unit)); // 9. Let result be ! RoundISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode). - auto result = round_iso_date_time(vm, date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode); + auto result = round_iso_date_time(date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode); // 10. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], dateTime.[[Calendar]]). return TRY(create_temporal_date_time(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, date_time->calendar())); @@ -604,7 +604,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_string) auto show_calendar = TRY(to_show_calendar_option(vm, *options)); // 7. Let result be ! RoundISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], precision.[[Increment]], precision.[[Unit]], roundingMode). - auto result = round_iso_date_time(vm, date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), precision.increment, precision.unit, rounding_mode); + auto result = round_iso_date_time(date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond(), precision.increment, precision.unit, rounding_mode); // 8. Return ? TemporalDateTimeToString(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], dateTime.[[Calendar]], precision.[[Precision]], showCalendar). return js_string(vm, TRY(temporal_date_time_to_string(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, &date_time->calendar(), precision.precision, show_calendar))); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp index fa3d6dc632..16979bc13e 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp @@ -154,7 +154,7 @@ ThrowCompletionOr<PlainMonthDay*> create_temporal_month_day(VM& vm, u8 iso_month return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainMonthDay); // 4. If ISODateTimeWithinLimits(referenceISOYear, isoMonth, isoDay, 12, 0, 0, 0, 0, 0) is false, throw a RangeError exception. - if (!iso_date_time_within_limits(vm, reference_iso_year, iso_month, iso_day, 12, 0, 0, 0, 0, 0)) + if (!iso_date_time_within_limits(reference_iso_year, iso_month, iso_day, 12, 0, 0, 0, 0, 0)) return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidPlainMonthDay); // 5. If newTarget is not present, set newTarget to %Temporal.PlainMonthDay%. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 095e7b699c..2fea28895a 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -159,7 +159,7 @@ MarkedVector<BigInt*> get_iana_time_zone_epoch_value(VM& vm, [[maybe_unused]] St // FIXME: Implement this properly for non-UTC timezones. auto list = MarkedVector<BigInt*> { vm.heap() }; - list.append(get_epoch_from_iso_parts(vm, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)); + list.append(js_bigint(vm, get_utc_epoch_nanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond))); return list; } @@ -584,11 +584,11 @@ ThrowCompletionOr<Instant*> disambiguate_possible_instants(VM& vm, MarkedVector< return vm.throw_completion<RangeError>(ErrorType::TemporalDisambiguatePossibleInstantsRejectZero); } - // 7. Let epochNanoseconds be GetEpochFromISOParts(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]]). - auto* epoch_nanoseconds = get_epoch_from_iso_parts(vm, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.iso_hour(), date_time.iso_minute(), date_time.iso_second(), date_time.iso_millisecond(), date_time.iso_microsecond(), date_time.iso_nanosecond()); + // 7. Let epochNanoseconds be GetUTCEpochNanoseconds(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]]). + auto epoch_nanoseconds = get_utc_epoch_nanoseconds(date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.iso_hour(), date_time.iso_minute(), date_time.iso_second(), date_time.iso_millisecond(), date_time.iso_microsecond(), date_time.iso_nanosecond()); // 8. Let dayBeforeNs be epochNanoseconds - โค(nsPerDay). - auto* day_before_ns = js_bigint(vm, epoch_nanoseconds->big_integer().minus(ns_per_day_bigint)); + auto* day_before_ns = js_bigint(vm, epoch_nanoseconds.minus(ns_per_day_bigint)); // 9. If ! IsValidEpochNanoseconds(dayBeforeNs) is false, throw a RangeError exception. if (!is_valid_epoch_nanoseconds(*day_before_ns)) @@ -598,7 +598,7 @@ ThrowCompletionOr<Instant*> disambiguate_possible_instants(VM& vm, MarkedVector< auto* day_before = MUST(create_temporal_instant(vm, *day_before_ns)); // 11. Let dayAfterNs be epochNanoseconds + โค(nsPerDay). - auto* day_after_ns = js_bigint(vm, epoch_nanoseconds->big_integer().plus(ns_per_day_bigint)); + auto* day_after_ns = js_bigint(vm, epoch_nanoseconds.plus(ns_per_day_bigint)); // 12. If ! IsValidEpochNanoseconds(dayAfterNs) is false, throw a RangeError exception. if (!is_valid_epoch_nanoseconds(*day_after_ns)) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp index fc463bfbda..17ab8fd163 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp @@ -6,6 +6,7 @@ #include <AK/TypeCasts.h> #include <LibJS/Runtime/Array.h> +#include <LibJS/Runtime/Date.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/Temporal/AbstractOperations.h> #include <LibJS/Runtime/Temporal/Calendar.h> @@ -141,11 +142,11 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_possible_instants_for) // 4. If timeZone.[[OffsetNanoseconds]] is not undefined, then if (time_zone->offset_nanoseconds().has_value()) { - // a. Let epochNanoseconds be GetEpochFromISOParts(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]]). - auto* epoch_nanoseconds = get_epoch_from_iso_parts(vm, date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond()); + // a. Let epochNanoseconds be GetUTCEpochNanoseconds(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]]). + auto epoch_nanoseconds = get_utc_epoch_nanoseconds(date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond()); // b. Let possibleEpochNanoseconds be ยซ epochNanoseconds - โค(timeZone.[[OffsetNanoseconds]]) ยป. - possible_epoch_nanoseconds.append(js_bigint(vm, epoch_nanoseconds->big_integer().minus(Crypto::SignedBigInteger { *time_zone->offset_nanoseconds() }))); + possible_epoch_nanoseconds.append(js_bigint(vm, epoch_nanoseconds.minus(Crypto::SignedBigInteger { *time_zone->offset_nanoseconds() }))); } // 5. Else, else { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index 7acba1931c..1c695e6312 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -57,19 +57,18 @@ ThrowCompletionOr<BigInt const*> interpret_iso_date_time_offset(VM& vm, i32 year // 4. If offsetBehaviour is exact or offsetOption is "use", then if (offset_behavior == OffsetBehavior::Exact || offset_option == "use"sv) { - // a. Let epochNanoseconds be GetEpochFromISOParts(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond). - auto* epoch_nanoseconds = get_epoch_from_iso_parts(vm, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond); + // a. Let epochNanoseconds be GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond). + auto epoch_nanoseconds = get_utc_epoch_nanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond); // b. Set epochNanoseconds to epochNanoseconds - โค(offsetNanoseconds). - auto offset_nanoseconds_bigint = Crypto::SignedBigInteger { offset_nanoseconds }; - epoch_nanoseconds = js_bigint(vm, epoch_nanoseconds->big_integer().minus(offset_nanoseconds_bigint)); + epoch_nanoseconds = epoch_nanoseconds.minus(Crypto::SignedBigInteger { offset_nanoseconds }); // c. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception. - if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) + if (!is_valid_epoch_nanoseconds(epoch_nanoseconds)) return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidEpochNanoseconds); // d. Return epochNanoseconds. - return epoch_nanoseconds; + return js_bigint(vm, move(epoch_nanoseconds)); } // 5. Assert: offsetBehaviour is option. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp index 1d5c914c5b..2e57b226ba 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp @@ -1027,7 +1027,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::round) } // 20. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode, dayLengthNs). - auto round_result = round_iso_date_time(vm, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode, day_length_ns); + auto round_result = round_iso_date_time(temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), rounding_increment, *smallest_unit, rounding_mode, day_length_ns); // 21. Let offsetNanoseconds be ? GetOffsetNanosecondsFor(timeZone, instant). auto offset_nanoseconds = TRY(get_offset_nanoseconds_for(vm, &time_zone, *instant)); |