diff options
author | Linus Groh <mail@linusgroh.de> | 2022-03-25 18:33:55 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-03-25 18:33:55 +0000 |
commit | a5ea0666930870b3d37f31e349893d378ef2eee5 (patch) | |
tree | b292b3f871be51046f697b136ae8f185720c02e7 | |
parent | 9950f06623d1e27442397bb3e4f1762b3ad28242 (diff) | |
download | serenity-a5ea0666930870b3d37f31e349893d378ef2eee5.zip |
LibJS: Fix number types in GetISOPartsFromEpoch
This is an editorial change in the Temporal spec.
See: https://github.com/tc39/proposal-temporal/commit/c5b645d
This means we now have to pass a global object and construct a BigInt
object just for the assertion, but oh well. We might want to have an
assertion macro that's optimized away in release builds at a later
point, however.
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp | 29 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h | 2 |
2 files changed, 17 insertions, 14 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 854e15c4ee..521d463ce8 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -100,37 +100,40 @@ ThrowCompletionOr<TimeZone*> create_temporal_time_zone(GlobalObject& global_obje } // 11.6.2 GetISOPartsFromEpoch ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-getisopartsfromepoch -ISODateTime get_iso_parts_from_epoch(BigInt const& epoch_nanoseconds) +ISODateTime get_iso_parts_from_epoch(GlobalObject& global_object, Crypto::SignedBigInteger const& epoch_nanoseconds) { - // 1. Assert: epochNanoseconds is an integer. + auto& vm = global_object.vm(); + + // 1. Assert: ! IsValidEpochNanoseconds(ℤ(epochNanoseconds)) is true. + VERIFY(is_valid_epoch_nanoseconds(*js_bigint(vm, epoch_nanoseconds))); // 2. Let remainderNs be epochNanoseconds modulo 10^6. - auto remainder_ns_bigint = modulo(epoch_nanoseconds.big_integer(), Crypto::UnsignedBigInteger { 1'000'000 }); + auto remainder_ns_bigint = modulo(epoch_nanoseconds, Crypto::UnsignedBigInteger { 1'000'000 }); auto remainder_ns = remainder_ns_bigint.to_double(); - // 3. Let epochMilliseconds be (epochNanoseconds − remainderNs) / 10^6. - auto epoch_milliseconds_bigint = epoch_nanoseconds.big_integer().minus(remainder_ns_bigint).divided_by(Crypto::UnsignedBigInteger { 1'000'000 }).quotient; + // 3. Let epochMilliseconds be 𝔽((epochNanoseconds − remainderNs) / 10^6). + auto epoch_milliseconds_bigint = epoch_nanoseconds.minus(remainder_ns_bigint).divided_by(Crypto::UnsignedBigInteger { 1'000'000 }).quotient; auto epoch_milliseconds = epoch_milliseconds_bigint.to_double(); - // 4. Let year be ! YearFromTime(epochMilliseconds). + // 4. Let year be ℝ(! YearFromTime(epochMilliseconds)). auto year = year_from_time(epoch_milliseconds); - // 5. Let month be ! MonthFromTime(epochMilliseconds) + 1. + // 5. Let month be ℝ(! MonthFromTime(epochMilliseconds)) + 1. auto month = static_cast<u8>(month_from_time(epoch_milliseconds) + 1); - // 6. Let day be ! DateFromTime(epochMilliseconds). + // 6. Let day be ℝ(! DateFromTime(epochMilliseconds)). auto day = date_from_time(epoch_milliseconds); - // 7. Let hour be ! HourFromTime(epochMilliseconds). + // 7. Let hour be ℝ(! HourFromTime(epochMilliseconds)). auto hour = hour_from_time(epoch_milliseconds); - // 8. Let minute be ! MinFromTime(epochMilliseconds). + // 8. Let minute be ℝ(! MinFromTime(epochMilliseconds)). auto minute = min_from_time(epoch_milliseconds); - // 9. Let second be ! SecFromTime(epochMilliseconds). + // 9. Let second be ℝ(! SecFromTime(epochMilliseconds)). auto second = sec_from_time(epoch_milliseconds); - // 10. Let millisecond be ! msFromTime(epochMilliseconds). + // 10. Let millisecond be ℝ(! msFromTime(epochMilliseconds)). auto millisecond = ms_from_time(epoch_milliseconds); // 11. Let microsecond be floor(remainderNs / 1000) modulo 1000. @@ -509,7 +512,7 @@ ThrowCompletionOr<PlainDateTime*> builtin_time_zone_get_plain_date_time_for(Glob auto offset_nanoseconds = TRY(get_offset_nanoseconds_for(global_object, time_zone, instant)); // 3. Let result be ! GetISOPartsFromEpoch(ℝ(instant.[[Nanoseconds]])). - auto result = get_iso_parts_from_epoch(instant.nanoseconds()); + auto result = get_iso_parts_from_epoch(global_object, instant.nanoseconds().big_integer()); // 4. Set result to ! BalanceISODateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]] + offsetNanoseconds). result = balance_iso_date_time(result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond + offset_nanoseconds); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h index 77432aeb39..6ea07c54d5 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h @@ -40,7 +40,7 @@ String canonicalize_time_zone_name(String const& time_zone); String default_time_zone(); ThrowCompletionOr<String> parse_temporal_time_zone(GlobalObject&, String const&); ThrowCompletionOr<TimeZone*> create_temporal_time_zone(GlobalObject&, String const& identifier, FunctionObject const* new_target = nullptr); -ISODateTime get_iso_parts_from_epoch(BigInt const& epoch_nanoseconds); +ISODateTime get_iso_parts_from_epoch(GlobalObject&, Crypto::SignedBigInteger const& epoch_nanoseconds); MarkedVector<BigInt*> get_iana_time_zone_epoch_value(GlobalObject&, StringView time_zone_identifier, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond); i64 get_iana_time_zone_offset_nanoseconds(BigInt const& epoch_nanoseconds, String const& time_zone_identifier); BigInt* get_iana_time_zone_next_transition(GlobalObject&, BigInt const& epoch_nanoseconds, StringView time_zone_identifier); |