summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2022-03-25 18:33:55 +0000
committerLinus Groh <mail@linusgroh.de>2022-03-25 18:33:55 +0000
commita5ea0666930870b3d37f31e349893d378ef2eee5 (patch)
treeb292b3f871be51046f697b136ae8f185720c02e7
parent9950f06623d1e27442397bb3e4f1762b3ad28242 (diff)
downloadserenity-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.cpp29
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h2
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);