mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 11:48:13 +00:00
LibCrypto+LibJS: Remove the create_from methods from BigInteger
Instead we just use a specific constructor. With this set of constructors using curly braces for constructing is highly recommended. As then it will not do too many implicit conversions which could lead to unexpected loss of data or calling the much slower double constructor. Also to ensure we don't feed (Un)SignedBigInteger infinities we throw RangeError earlier for Durations.
This commit is contained in:
parent
528891bf69
commit
791855deab
19 changed files with 77 additions and 82 deletions
|
@ -174,7 +174,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
|
||||||
return m_machine.store().get(*v)->value().value().visit(
|
return m_machine.store().get(*v)->value().value().visit(
|
||||||
[&](auto const& value) -> JS::Value { return JS::Value(static_cast<double>(value)); },
|
[&](auto const& value) -> JS::Value { return JS::Value(static_cast<double>(value)); },
|
||||||
[&](i32 value) { return JS::Value(static_cast<double>(value)); },
|
[&](i32 value) { return JS::Value(static_cast<double>(value)); },
|
||||||
[&](i64 value) -> JS::Value { return JS::js_bigint(vm, Crypto::SignedBigInteger::create_from(value)); },
|
[&](i64 value) -> JS::Value { return JS::js_bigint(vm, Crypto::SignedBigInteger { value }); },
|
||||||
[&](Wasm::Reference const& reference) -> JS::Value {
|
[&](Wasm::Reference const& reference) -> JS::Value {
|
||||||
return reference.ref().visit(
|
return reference.ref().visit(
|
||||||
[&](const Wasm::Reference::Null&) -> JS::Value { return JS::js_null(); },
|
[&](const Wasm::Reference::Null&) -> JS::Value { return JS::js_null(); },
|
||||||
|
@ -253,7 +253,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
||||||
result.values().first().value().visit(
|
result.values().first().value().visit(
|
||||||
[&](auto const& value) { return_value = JS::Value(static_cast<double>(value)); },
|
[&](auto const& value) { return_value = JS::Value(static_cast<double>(value)); },
|
||||||
[&](i32 value) { return_value = JS::Value(static_cast<double>(value)); },
|
[&](i32 value) { return_value = JS::Value(static_cast<double>(value)); },
|
||||||
[&](i64 value) { return_value = JS::Value(JS::js_bigint(vm, Crypto::SignedBigInteger::create_from(value))); },
|
[&](i64 value) { return_value = JS::Value(JS::js_bigint(vm, Crypto::SignedBigInteger { value })); },
|
||||||
[&](Wasm::Reference const& reference) {
|
[&](Wasm::Reference const& reference) {
|
||||||
reference.ref().visit(
|
reference.ref().visit(
|
||||||
[&](const Wasm::Reference::Null&) { return_value = JS::js_null(); },
|
[&](const Wasm::Reference::Null&) { return_value = JS::js_null(); },
|
||||||
|
|
|
@ -45,6 +45,12 @@ public:
|
||||||
|
|
||||||
explicit SignedBigInteger(double value);
|
explicit SignedBigInteger(double value);
|
||||||
|
|
||||||
|
explicit SignedBigInteger(i64 value)
|
||||||
|
: m_sign(value < 0)
|
||||||
|
, m_unsigned_data(value < 0 ? static_cast<u64>(-(value + 1)) + 1 : static_cast<u64>(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static SignedBigInteger create_invalid()
|
[[nodiscard]] static SignedBigInteger create_invalid()
|
||||||
{
|
{
|
||||||
return { UnsignedBigInteger::create_invalid(), false };
|
return { UnsignedBigInteger::create_invalid(), false };
|
||||||
|
@ -53,19 +59,6 @@ public:
|
||||||
[[nodiscard]] static SignedBigInteger import_data(StringView data) { return import_data((u8 const*)data.characters_without_null_termination(), data.length()); }
|
[[nodiscard]] static SignedBigInteger import_data(StringView data) { return import_data((u8 const*)data.characters_without_null_termination(), data.length()); }
|
||||||
[[nodiscard]] static SignedBigInteger import_data(u8 const* ptr, size_t length);
|
[[nodiscard]] static SignedBigInteger import_data(u8 const* ptr, size_t length);
|
||||||
|
|
||||||
[[nodiscard]] static SignedBigInteger create_from(i64 value)
|
|
||||||
{
|
|
||||||
auto sign = false;
|
|
||||||
u64 unsigned_value;
|
|
||||||
if (value < 0) {
|
|
||||||
unsigned_value = static_cast<u64>(-(value + 1)) + 1;
|
|
||||||
sign = true;
|
|
||||||
} else {
|
|
||||||
unsigned_value = value;
|
|
||||||
}
|
|
||||||
return SignedBigInteger { UnsignedBigInteger::create_from(unsigned_value), sign };
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||||
|
|
||||||
[[nodiscard]] static SignedBigInteger from_base(u16 N, StringView str);
|
[[nodiscard]] static SignedBigInteger from_base(u16 N, StringView str);
|
||||||
|
|
|
@ -41,6 +41,14 @@ public:
|
||||||
|
|
||||||
explicit UnsignedBigInteger(double value);
|
explicit UnsignedBigInteger(double value);
|
||||||
|
|
||||||
|
explicit UnsignedBigInteger(u64 value)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(u64) == sizeof(Word) * 2);
|
||||||
|
m_words.resize_and_keep_capacity(2);
|
||||||
|
m_words[0] = static_cast<Word>(value & 0xFFFFFFFF);
|
||||||
|
m_words[1] = static_cast<Word>((value >> 32) & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
UnsignedBigInteger() = default;
|
UnsignedBigInteger() = default;
|
||||||
|
|
||||||
[[nodiscard]] static UnsignedBigInteger create_invalid();
|
[[nodiscard]] static UnsignedBigInteger create_invalid();
|
||||||
|
@ -51,16 +59,6 @@ public:
|
||||||
return UnsignedBigInteger(ptr, length);
|
return UnsignedBigInteger(ptr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static UnsignedBigInteger create_from(u64 value)
|
|
||||||
{
|
|
||||||
VERIFY(sizeof(Word) == 4);
|
|
||||||
UnsignedBigInteger integer;
|
|
||||||
integer.m_words.resize(2);
|
|
||||||
integer.m_words[0] = static_cast<Word>(value & 0xFFFFFFFF);
|
|
||||||
integer.m_words[1] = static_cast<Word>((value >> 32) & 0xFFFFFFFF);
|
|
||||||
return integer;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||||
|
|
||||||
[[nodiscard]] static UnsignedBigInteger from_base(u16 N, StringView str);
|
[[nodiscard]] static UnsignedBigInteger from_base(u16 N, StringView str);
|
||||||
|
|
|
@ -108,10 +108,13 @@ static Value raw_bytes_to_numeric(VM& vm, ByteBuffer raw_value, bool is_little_e
|
||||||
UnderlyingBufferDataType int_value = 0;
|
UnderlyingBufferDataType int_value = 0;
|
||||||
raw_value.span().copy_to({ &int_value, sizeof(UnderlyingBufferDataType) });
|
raw_value.span().copy_to({ &int_value, sizeof(UnderlyingBufferDataType) });
|
||||||
if constexpr (sizeof(UnderlyingBufferDataType) == 8) {
|
if constexpr (sizeof(UnderlyingBufferDataType) == 8) {
|
||||||
if constexpr (IsSigned<UnderlyingBufferDataType>)
|
if constexpr (IsSigned<UnderlyingBufferDataType>) {
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger::create_from(int_value));
|
static_assert(IsSame<UnderlyingBufferDataType, i64>);
|
||||||
else
|
return js_bigint(vm, Crypto::SignedBigInteger { int_value });
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger { Crypto::UnsignedBigInteger::create_from(int_value) });
|
} else {
|
||||||
|
static_assert(IsOneOf<UnderlyingBufferDataType, u64, double>);
|
||||||
|
return js_bigint(vm, Crypto::SignedBigInteger { Crypto::UnsignedBigInteger { int_value } });
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Value(int_value);
|
return Value(int_value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ ThrowCompletionOr<BigInt*> number_to_bigint(VM& vm, Value number)
|
||||||
return vm.throw_completion<RangeError>(ErrorType::BigIntFromNonIntegral);
|
return vm.throw_completion<RangeError>(ErrorType::BigIntFromNonIntegral);
|
||||||
|
|
||||||
// 2. Return the BigInt value that represents ℝ(number).
|
// 2. Return the BigInt value that represents ℝ(number).
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger::create_from((i64)number.as_double()));
|
return js_bigint(vm, Crypto::SignedBigInteger { number.as_double() });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ MathematicalValue MathematicalValue::plus(Checked<i32> addition) const
|
||||||
return MathematicalValue { value + addition.value() };
|
return MathematicalValue { value + addition.value() };
|
||||||
},
|
},
|
||||||
[&](Crypto::SignedBigInteger const& value) {
|
[&](Crypto::SignedBigInteger const& value) {
|
||||||
return MathematicalValue { value.plus(Crypto::SignedBigInteger::create_from(addition.value())) };
|
return MathematicalValue { value.plus(Crypto::SignedBigInteger { addition.value() }) };
|
||||||
},
|
},
|
||||||
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ MathematicalValue MathematicalValue::minus(Checked<i32> subtraction) const
|
||||||
return MathematicalValue { value - subtraction.value() };
|
return MathematicalValue { value - subtraction.value() };
|
||||||
},
|
},
|
||||||
[&](Crypto::SignedBigInteger const& value) {
|
[&](Crypto::SignedBigInteger const& value) {
|
||||||
return MathematicalValue { value.minus(Crypto::SignedBigInteger::create_from(subtraction.value())) };
|
return MathematicalValue { value.minus(Crypto::SignedBigInteger { subtraction.value() }) };
|
||||||
},
|
},
|
||||||
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ MathematicalValue MathematicalValue::multiplied_by(Checked<i32> multiplier) cons
|
||||||
return MathematicalValue { value * multiplier.value() };
|
return MathematicalValue { value * multiplier.value() };
|
||||||
},
|
},
|
||||||
[&](Crypto::SignedBigInteger const& value) {
|
[&](Crypto::SignedBigInteger const& value) {
|
||||||
return MathematicalValue { value.multiplied_by(Crypto::SignedBigInteger::create_from(multiplier.value())) };
|
return MathematicalValue { value.multiplied_by(Crypto::SignedBigInteger { multiplier.value() }) };
|
||||||
},
|
},
|
||||||
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ MathematicalValue MathematicalValue::divided_by(Checked<i32> divisor) const
|
||||||
return MathematicalValue { value / divisor.value() };
|
return MathematicalValue { value / divisor.value() };
|
||||||
},
|
},
|
||||||
[&](Crypto::SignedBigInteger const& value) {
|
[&](Crypto::SignedBigInteger const& value) {
|
||||||
return MathematicalValue { value.divided_by(Crypto::SignedBigInteger::create_from(divisor.value())).quotient };
|
return MathematicalValue { value.divided_by(Crypto::SignedBigInteger { divisor.value() }).quotient };
|
||||||
},
|
},
|
||||||
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
[](auto) -> MathematicalValue { VERIFY_NOT_REACHED(); });
|
||||||
}
|
}
|
||||||
|
@ -177,8 +177,8 @@ static Crypto::SignedBigInteger bigint_power(Checked<i32> exponent)
|
||||||
{
|
{
|
||||||
VERIFY(exponent >= 0);
|
VERIFY(exponent >= 0);
|
||||||
|
|
||||||
static auto base = Crypto::SignedBigInteger::create_from(10);
|
static auto base = Crypto::SignedBigInteger { 10 };
|
||||||
auto result = Crypto::SignedBigInteger::create_from(1);
|
auto result = Crypto::SignedBigInteger { 1 };
|
||||||
|
|
||||||
for (i32 i = 0; i < exponent; ++i)
|
for (i32 i = 0; i < exponent; ++i)
|
||||||
result = result.multiplied_by(base);
|
result = result.multiplied_by(base);
|
||||||
|
@ -224,7 +224,7 @@ bool MathematicalValue::modulo_is_zero(Checked<i32> mod) const
|
||||||
return result.is_equal_to(MathematicalValue { 0.0 });
|
return result.is_equal_to(MathematicalValue { 0.0 });
|
||||||
},
|
},
|
||||||
[&](Crypto::SignedBigInteger const& value) {
|
[&](Crypto::SignedBigInteger const& value) {
|
||||||
return modulo(value, Crypto::SignedBigInteger::create_from(mod.value())).is_zero();
|
return modulo(value, Crypto::SignedBigInteger { mod.value() }).is_zero();
|
||||||
},
|
},
|
||||||
[](auto) -> bool { VERIFY_NOT_REACHED(); });
|
[](auto) -> bool { VERIFY_NOT_REACHED(); });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ Crypto::SignedBigInteger round_number_to_increment(Crypto::SignedBigInteger cons
|
||||||
if (increment == 1)
|
if (increment == 1)
|
||||||
return x;
|
return x;
|
||||||
|
|
||||||
auto increment_big_int = Crypto::UnsignedBigInteger::create_from(increment);
|
auto increment_big_int = Crypto::UnsignedBigInteger { increment };
|
||||||
|
|
||||||
// 1. Let quotient be x / increment.
|
// 1. Let quotient be x / increment.
|
||||||
auto division_result = x.divided_by(increment_big_int);
|
auto division_result = x.divided_by(increment_big_int);
|
||||||
|
@ -1137,7 +1137,7 @@ Crypto::SignedBigInteger round_number_to_increment_as_if_positive(Crypto::Signed
|
||||||
if (increment == 1)
|
if (increment == 1)
|
||||||
return x;
|
return x;
|
||||||
|
|
||||||
auto increment_big_int = Crypto::UnsignedBigInteger::create_from(increment);
|
auto increment_big_int = Crypto::UnsignedBigInteger { increment };
|
||||||
|
|
||||||
// 1. Let quotient be x / increment.
|
// 1. Let quotient be x / increment.
|
||||||
auto division_result = x.divided_by(increment_big_int);
|
auto division_result = x.divided_by(increment_big_int);
|
||||||
|
|
|
@ -175,8 +175,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_add)
|
||||||
auto overflow = TRY(to_temporal_overflow(vm, options));
|
auto overflow = TRY(to_temporal_overflow(vm, options));
|
||||||
|
|
||||||
// 8. Let balanceResult be ? BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
|
// 8. Let balanceResult be ? BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
auto balance_result = TRY(balance_duration(vm, duration->days(), duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger { duration->nanoseconds() }, "day"sv));
|
||||||
auto balance_result = TRY(balance_duration(vm, duration->days(), duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger::create_from(duration->nanoseconds()), "day"sv));
|
|
||||||
|
|
||||||
// 9. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]], overflow).
|
// 9. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]], overflow).
|
||||||
auto result = TRY(add_iso_date(vm, date->iso_year(), date->iso_month(), date->iso_day(), duration->years(), duration->months(), duration->weeks(), balance_result.days, overflow));
|
auto result = TRY(add_iso_date(vm, date->iso_year(), date->iso_month(), date->iso_day(), duration->years(), duration->months(), duration->weeks(), balance_result.days, overflow));
|
||||||
|
|
|
@ -395,24 +395,21 @@ Crypto::SignedBigInteger total_duration_nanoseconds(double days, double hours, d
|
||||||
|
|
||||||
auto result_nanoseconds = nanoseconds;
|
auto result_nanoseconds = nanoseconds;
|
||||||
|
|
||||||
// TODO: Add a way to create SignedBigIntegers from doubles with full precision and remove this restriction
|
|
||||||
VERIFY(AK::is_within_range<i64>(days) && AK::is_within_range<i64>(hours) && AK::is_within_range<i64>(minutes) && AK::is_within_range<i64>(seconds) && AK::is_within_range<i64>(milliseconds) && AK::is_within_range<i64>(microseconds));
|
|
||||||
|
|
||||||
// 1. If days ≠ 0, then
|
// 1. If days ≠ 0, then
|
||||||
if (days != 0) {
|
if (days != 0) {
|
||||||
// a. Set nanoseconds to nanoseconds - offsetShift.
|
// a. Set nanoseconds to nanoseconds - offsetShift.
|
||||||
result_nanoseconds = result_nanoseconds.minus(Crypto::SignedBigInteger::create_from(offset_shift));
|
result_nanoseconds = result_nanoseconds.minus(Crypto::SignedBigInteger { offset_shift });
|
||||||
}
|
}
|
||||||
// 2. Set hours to hours + days × 24.
|
// 2. Set hours to hours + days × 24.
|
||||||
auto total_hours = Crypto::SignedBigInteger::create_from(hours).plus(Crypto::SignedBigInteger::create_from(days).multiplied_by(Crypto::UnsignedBigInteger(24)));
|
auto total_hours = Crypto::SignedBigInteger { hours }.plus(Crypto::SignedBigInteger { days }.multiplied_by(Crypto::UnsignedBigInteger(24)));
|
||||||
// 3. Set minutes to minutes + hours × 60.
|
// 3. Set minutes to minutes + hours × 60.
|
||||||
auto total_minutes = Crypto::SignedBigInteger::create_from(minutes).plus(total_hours.multiplied_by(Crypto::UnsignedBigInteger(60)));
|
auto total_minutes = Crypto::SignedBigInteger { minutes }.plus(total_hours.multiplied_by(Crypto::UnsignedBigInteger(60)));
|
||||||
// 4. Set seconds to seconds + minutes × 60.
|
// 4. Set seconds to seconds + minutes × 60.
|
||||||
auto total_seconds = Crypto::SignedBigInteger::create_from(seconds).plus(total_minutes.multiplied_by(Crypto::UnsignedBigInteger(60)));
|
auto total_seconds = Crypto::SignedBigInteger { seconds }.plus(total_minutes.multiplied_by(Crypto::UnsignedBigInteger(60)));
|
||||||
// 5. Set milliseconds to milliseconds + seconds × 1000.
|
// 5. Set milliseconds to milliseconds + seconds × 1000.
|
||||||
auto total_milliseconds = Crypto::SignedBigInteger::create_from(milliseconds).plus(total_seconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
auto total_milliseconds = Crypto::SignedBigInteger { milliseconds }.plus(total_seconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
||||||
// 6. Set microseconds to microseconds + milliseconds × 1000.
|
// 6. Set microseconds to microseconds + milliseconds × 1000.
|
||||||
auto total_microseconds = Crypto::SignedBigInteger::create_from(microseconds).plus(total_milliseconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
auto total_microseconds = Crypto::SignedBigInteger { microseconds }.plus(total_milliseconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
||||||
// 7. Return nanoseconds + microseconds × 1000.
|
// 7. Return nanoseconds + microseconds × 1000.
|
||||||
return result_nanoseconds.plus(total_microseconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
return result_nanoseconds.plus(total_microseconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
|
||||||
}
|
}
|
||||||
|
@ -422,6 +419,11 @@ ThrowCompletionOr<TimeDurationRecord> balance_duration(VM& vm, double days, doub
|
||||||
{
|
{
|
||||||
// 1. If relativeTo is not present, set relativeTo to undefined.
|
// 1. If relativeTo is not present, set relativeTo to undefined.
|
||||||
|
|
||||||
|
// NOTE: If any of the inputs is not finite this will mean that we have infinities,
|
||||||
|
// so the duration will never be valid. Also
|
||||||
|
if (!isfinite(days) || !isfinite(hours) || !isfinite(minutes) || !isfinite(seconds) || !isfinite(milliseconds) || !isfinite(microseconds))
|
||||||
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
|
||||||
Crypto::SignedBigInteger total_nanoseconds;
|
Crypto::SignedBigInteger total_nanoseconds;
|
||||||
// 2. If Type(relativeTo) is Object and relativeTo has an [[InitializedTemporalZonedDateTime]] internal slot, then
|
// 2. If Type(relativeTo) is Object and relativeTo has an [[InitializedTemporalZonedDateTime]] internal slot, then
|
||||||
if (relative_to && is<ZonedDateTime>(*relative_to)) {
|
if (relative_to && is<ZonedDateTime>(*relative_to)) {
|
||||||
|
@ -986,8 +988,10 @@ ThrowCompletionOr<DurationRecord> add_duration(VM& vm, double years1, double mon
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Let result be ? BalanceDuration(d1 + d2, h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
// b. Let result be ? BalanceDuration(d1 + d2, h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
VERIFY(trunc(nanoseconds1 + nanoseconds2) == nanoseconds1 + nanoseconds2);
|
||||||
auto result = TRY(balance_duration(vm, days1 + days2, hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit));
|
if (!isfinite(nanoseconds1 + nanoseconds2))
|
||||||
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
auto result = TRY(balance_duration(vm, days1 + days2, hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger { nanoseconds1 + nanoseconds2 }, largest_unit));
|
||||||
|
|
||||||
// c. Return ! CreateDurationRecord(0, 0, 0, result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
// c. Return ! CreateDurationRecord(0, 0, 0, result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
||||||
return MUST(create_duration_record(vm, 0, 0, 0, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
return MUST(create_duration_record(vm, 0, 0, 0, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
||||||
|
@ -1028,8 +1032,10 @@ ThrowCompletionOr<DurationRecord> add_duration(VM& vm, double years1, double mon
|
||||||
auto* date_difference = TRY(calendar_date_until(vm, calendar, &relative_to, end, *difference_options));
|
auto* date_difference = TRY(calendar_date_until(vm, calendar, &relative_to, end, *difference_options));
|
||||||
|
|
||||||
// k. Let result be ? BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
// k. Let result be ? BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
VERIFY(trunc(nanoseconds1 + nanoseconds2) == nanoseconds1 + nanoseconds2);
|
||||||
auto result = TRY(balance_duration(vm, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit));
|
if (!isfinite(nanoseconds1 + nanoseconds2))
|
||||||
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
auto result = TRY(balance_duration(vm, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger { nanoseconds1 + nanoseconds2 }, largest_unit));
|
||||||
|
|
||||||
// l. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
// l. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
||||||
return MUST(create_duration_record(vm, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
return MUST(create_duration_record(vm, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
||||||
|
@ -1145,7 +1151,7 @@ ThrowCompletionOr<RoundedDuration> round_duration(VM& vm, double years, double m
|
||||||
// 6. If unit is one of "year", "month", "week", or "day", then
|
// 6. If unit is one of "year", "month", "week", or "day", then
|
||||||
if (unit.is_one_of("year"sv, "month"sv, "week"sv, "day"sv)) {
|
if (unit.is_one_of("year"sv, "month"sv, "week"sv, "day"sv)) {
|
||||||
// a. Let nanoseconds be ! TotalDurationNanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0).
|
// a. Let nanoseconds be ! TotalDurationNanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0).
|
||||||
auto nanoseconds_bigint = total_duration_nanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, Crypto::SignedBigInteger::create_from((i64)nanoseconds), 0);
|
auto nanoseconds_bigint = total_duration_nanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, Crypto::SignedBigInteger { nanoseconds }, 0);
|
||||||
|
|
||||||
// b. Let intermediate be undefined.
|
// b. Let intermediate be undefined.
|
||||||
ZonedDateTime* intermediate = nullptr;
|
ZonedDateTime* intermediate = nullptr;
|
||||||
|
@ -1160,7 +1166,7 @@ ThrowCompletionOr<RoundedDuration> round_duration(VM& vm, double years, double m
|
||||||
auto result = TRY(nanoseconds_to_days(vm, nanoseconds_bigint, intermediate));
|
auto result = TRY(nanoseconds_to_days(vm, nanoseconds_bigint, intermediate));
|
||||||
|
|
||||||
// e. Set days to days + result.[[Days]] + result.[[Nanoseconds]] / result.[[DayLength]].
|
// e. Set days to days + result.[[Days]] + result.[[Nanoseconds]] / result.[[DayLength]].
|
||||||
auto nanoseconds_division_result = result.nanoseconds.divided_by(Crypto::UnsignedBigInteger::create_from((u64)result.day_length));
|
auto nanoseconds_division_result = result.nanoseconds.divided_by(Crypto::UnsignedBigInteger { result.day_length });
|
||||||
days += result.days + nanoseconds_division_result.quotient.to_double() + nanoseconds_division_result.remainder.to_double() / result.day_length;
|
days += result.days + nanoseconds_division_result.quotient.to_double() + nanoseconds_division_result.remainder.to_double() / result.day_length;
|
||||||
|
|
||||||
// f. Set hours, minutes, seconds, milliseconds, microseconds, and nanoseconds to 0.
|
// f. Set hours, minutes, seconds, milliseconds, microseconds, and nanoseconds to 0.
|
||||||
|
@ -1515,7 +1521,7 @@ ThrowCompletionOr<DurationRecord> adjust_rounded_duration_days(VM& vm, double ye
|
||||||
auto& relative_to = static_cast<ZonedDateTime&>(*relative_to_object);
|
auto& relative_to = static_cast<ZonedDateTime&>(*relative_to_object);
|
||||||
|
|
||||||
// 2. Let timeRemainderNs be ! TotalDurationNanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0).
|
// 2. Let timeRemainderNs be ! TotalDurationNanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0).
|
||||||
auto time_remainder_ns = total_duration_nanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, Crypto::SignedBigInteger::create_from((i64)nanoseconds), 0);
|
auto time_remainder_ns = total_duration_nanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, Crypto::SignedBigInteger { nanoseconds }, 0);
|
||||||
|
|
||||||
i32 direction;
|
i32 direction;
|
||||||
|
|
||||||
|
|
|
@ -149,10 +149,10 @@ JS_DEFINE_NATIVE_FUNCTION(DurationConstructor::compare)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Let ns1 be ! TotalDurationNanoseconds(days1, one.[[Hours]], one.[[Minutes]], one.[[Seconds]], one.[[Milliseconds]], one.[[Microseconds]], one.[[Nanoseconds]], shift1).
|
// 9. Let ns1 be ! TotalDurationNanoseconds(days1, one.[[Hours]], one.[[Minutes]], one.[[Seconds]], one.[[Milliseconds]], one.[[Microseconds]], one.[[Nanoseconds]], shift1).
|
||||||
auto ns1 = total_duration_nanoseconds(days1, one->hours(), one->minutes(), one->seconds(), one->milliseconds(), one->microseconds(), Crypto::SignedBigInteger::create_from((i64)one->nanoseconds()), shift1);
|
auto ns1 = total_duration_nanoseconds(days1, one->hours(), one->minutes(), one->seconds(), one->milliseconds(), one->microseconds(), Crypto::SignedBigInteger { one->nanoseconds() }, shift1);
|
||||||
|
|
||||||
// 10. Let ns2 be ! TotalDurationNanoseconds(days2, two.[[Hours]], two.[[Minutes]], two.[[Seconds]], two.[[Milliseconds]], two.[[Microseconds]], two.[[Nanoseconds]], shift2).
|
// 10. Let ns2 be ! TotalDurationNanoseconds(days2, two.[[Hours]], two.[[Minutes]], two.[[Seconds]], two.[[Milliseconds]], two.[[Microseconds]], two.[[Nanoseconds]], shift2).
|
||||||
auto ns2 = total_duration_nanoseconds(days2, two->hours(), two->minutes(), two->seconds(), two->milliseconds(), two->microseconds(), Crypto::SignedBigInteger::create_from((i64)two->nanoseconds()), shift2);
|
auto ns2 = total_duration_nanoseconds(days2, two->hours(), two->minutes(), two->seconds(), two->milliseconds(), two->microseconds(), Crypto::SignedBigInteger { two->nanoseconds() }, shift2);
|
||||||
|
|
||||||
// 11. If ns1 > ns2, return 1𝔽.
|
// 11. If ns1 > ns2, return 1𝔽.
|
||||||
if (ns1 > ns2)
|
if (ns1 > ns2)
|
||||||
|
|
|
@ -436,8 +436,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 26. Let result be ? BalanceDuration(balanceResult.[[Days]], adjustResult.[[Hours]], adjustResult.[[Minutes]], adjustResult.[[Seconds]], adjustResult.[[Milliseconds]], adjustResult.[[Microseconds]], adjustResult.[[Nanoseconds]], largestUnit, relativeTo).
|
// 26. Let result be ? BalanceDuration(balanceResult.[[Days]], adjustResult.[[Hours]], adjustResult.[[Minutes]], adjustResult.[[Seconds]], adjustResult.[[Milliseconds]], adjustResult.[[Microseconds]], adjustResult.[[Nanoseconds]], largestUnit, relativeTo).
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
auto result = TRY(balance_duration(vm, balance_result.days, adjust_result.hours, adjust_result.minutes, adjust_result.seconds, adjust_result.milliseconds, adjust_result.microseconds, Crypto::SignedBigInteger { adjust_result.nanoseconds }, *largest_unit, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
||||||
auto result = TRY(balance_duration(vm, balance_result.days, adjust_result.hours, adjust_result.minutes, adjust_result.seconds, adjust_result.milliseconds, adjust_result.microseconds, Crypto::SignedBigInteger::create_from(adjust_result.nanoseconds), *largest_unit, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
|
||||||
|
|
||||||
// 27. Return ! CreateTemporalDuration(balanceResult.[[Years]], balanceResult.[[Months]], balanceResult.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
// 27. Return ! CreateTemporalDuration(balanceResult.[[Years]], balanceResult.[[Months]], balanceResult.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
|
||||||
return MUST(create_temporal_duration(vm, balance_result.years, balance_result.months, balance_result.weeks, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
return MUST(create_temporal_duration(vm, balance_result.years, balance_result.months, balance_result.weeks, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds));
|
||||||
|
@ -495,7 +494,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::total)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. Let balanceResult be ? BalanceDuration(unbalanceResult.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], unit, intermediate).
|
// 11. Let balanceResult be ? BalanceDuration(unbalanceResult.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], unit, intermediate).
|
||||||
auto balance_result = TRY(balance_duration(vm, unbalance_result.days, duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger::create_from(duration->nanoseconds()), *unit, intermediate));
|
auto balance_result = TRY(balance_duration(vm, unbalance_result.days, duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger { duration->nanoseconds() }, *unit, intermediate));
|
||||||
|
|
||||||
// 12. Let roundRecord be ? RoundDuration(unbalanceResult.[[Years]], unbalanceResult.[[Months]], unbalanceResult.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]], 1, unit, "trunc", relativeTo).
|
// 12. Let roundRecord be ? RoundDuration(unbalanceResult.[[Years]], unbalanceResult.[[Months]], unbalanceResult.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]], 1, unit, "trunc", relativeTo).
|
||||||
auto round_record = TRY(round_duration(vm, unbalance_result.years, unbalance_result.months, unbalance_result.weeks, balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds, 1, *unit, "trunc"sv, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
auto round_record = TRY(round_duration(vm, unbalance_result.years, unbalance_result.months, unbalance_result.weeks, balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds, 1, *unit, "trunc"sv, relative_to.is_object() ? &relative_to.as_object() : nullptr));
|
||||||
|
|
|
@ -122,7 +122,7 @@ ThrowCompletionOr<BigInt*> parse_temporal_instant(VM& vm, String const& iso_stri
|
||||||
auto offset_nanoseconds = TRY(parse_time_zone_offset_string(vm, *offset_string));
|
auto offset_nanoseconds = TRY(parse_time_zone_offset_string(vm, *offset_string));
|
||||||
|
|
||||||
// 7. Let result be utc - ℤ(offsetNanoseconds).
|
// 7. Let result be utc - ℤ(offsetNanoseconds).
|
||||||
auto* result_ns = js_bigint(vm, utc->big_integer().minus(Crypto::SignedBigInteger::create_from(offset_nanoseconds)));
|
auto* result_ns = js_bigint(vm, utc->big_integer().minus(Crypto::SignedBigInteger { offset_nanoseconds }));
|
||||||
|
|
||||||
// 8. If ! IsValidEpochNanoseconds(result) is false, then
|
// 8. If ! IsValidEpochNanoseconds(result) is false, then
|
||||||
if (!is_valid_epoch_nanoseconds(*result_ns)) {
|
if (!is_valid_epoch_nanoseconds(*result_ns)) {
|
||||||
|
@ -155,15 +155,14 @@ ThrowCompletionOr<BigInt*> add_instant(VM& vm, BigInt const& epoch_nanoseconds,
|
||||||
VERIFY(hours == trunc(hours) && minutes == trunc(minutes) && seconds == trunc(seconds) && milliseconds == trunc(milliseconds) && microseconds == trunc(microseconds) && nanoseconds == trunc(nanoseconds));
|
VERIFY(hours == trunc(hours) && minutes == trunc(minutes) && seconds == trunc(seconds) && milliseconds == trunc(milliseconds) && microseconds == trunc(microseconds) && nanoseconds == trunc(nanoseconds));
|
||||||
|
|
||||||
// 1. Let result be epochNanoseconds + ℤ(nanoseconds) + ℤ(microseconds) × 1000ℤ + ℤ(milliseconds) × 10^6ℤ + ℤ(seconds) × 10^9ℤ + ℤ(minutes) × 60ℤ × 10^9ℤ + ℤ(hours) × 3600ℤ × 10^9ℤ.
|
// 1. Let result be epochNanoseconds + ℤ(nanoseconds) + ℤ(microseconds) × 1000ℤ + ℤ(milliseconds) × 10^6ℤ + ℤ(seconds) × 10^9ℤ + ℤ(minutes) × 60ℤ × 10^9ℤ + ℤ(hours) × 3600ℤ × 10^9ℤ.
|
||||||
// FIXME: Pretty sure i64's are not sufficient for the extreme cases.
|
|
||||||
auto* result = js_bigint(vm,
|
auto* result = js_bigint(vm,
|
||||||
epoch_nanoseconds.big_integer()
|
epoch_nanoseconds.big_integer()
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)nanoseconds))
|
.plus(Crypto::SignedBigInteger { nanoseconds })
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)microseconds).multiplied_by(Crypto::SignedBigInteger { 1'000 }))
|
.plus(Crypto::SignedBigInteger { microseconds }.multiplied_by(Crypto::SignedBigInteger { 1'000 }))
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)milliseconds).multiplied_by(Crypto::SignedBigInteger { 1'000'000 }))
|
.plus(Crypto::SignedBigInteger { milliseconds }.multiplied_by(Crypto::SignedBigInteger { 1'000'000 }))
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)seconds).multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 }))
|
.plus(Crypto::SignedBigInteger { seconds }.multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 }))
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)minutes).multiplied_by(Crypto::SignedBigInteger { 60 }).multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 }))
|
.plus(Crypto::SignedBigInteger { minutes }.multiplied_by(Crypto::SignedBigInteger { 60 }).multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 }))
|
||||||
.plus(Crypto::SignedBigInteger::create_from((i64)hours).multiplied_by(Crypto::SignedBigInteger { 3600 }).multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 })));
|
.plus(Crypto::SignedBigInteger { hours }.multiplied_by(Crypto::SignedBigInteger { 3600 }).multiplied_by(Crypto::SignedBigInteger { 1'000'000'000 })));
|
||||||
|
|
||||||
// 2. If ! IsValidEpochNanoseconds(result) is false, throw a RangeError exception.
|
// 2. If ! IsValidEpochNanoseconds(result) is false, throw a RangeError exception.
|
||||||
if (!is_valid_epoch_nanoseconds(*result))
|
if (!is_valid_epoch_nanoseconds(*result))
|
||||||
|
|
|
@ -162,7 +162,7 @@ BigInt* system_utc_epoch_nanoseconds(VM& vm)
|
||||||
{
|
{
|
||||||
// 1. Let ns be the approximate current UTC date and time, in nanoseconds since the epoch.
|
// 1. Let ns be the approximate current UTC date and time, in nanoseconds since the epoch.
|
||||||
auto now = Time::now_realtime().to_nanoseconds();
|
auto now = Time::now_realtime().to_nanoseconds();
|
||||||
auto ns = Crypto::SignedBigInteger::create_from(now);
|
auto ns = Crypto::SignedBigInteger { now };
|
||||||
|
|
||||||
// 2. Set ns to the result of clamping ns between nsMinInstant and nsMaxInstant.
|
// 2. Set ns to the result of clamping ns between nsMinInstant and nsMaxInstant.
|
||||||
// NOTE: Time::to_nanoseconds() already clamps between -(2^63) and 2^63 - 1, the range of an i64,
|
// NOTE: Time::to_nanoseconds() already clamps between -(2^63) and 2^63 - 1, the range of an i64,
|
||||||
|
|
|
@ -63,7 +63,8 @@ BigInt* get_epoch_from_iso_parts(VM& vm, i32 year, u8 month, u8 day, u8 hour, u8
|
||||||
VERIFY(isfinite(ms));
|
VERIFY(isfinite(ms));
|
||||||
|
|
||||||
// 6. Return ℤ(ℝ(ms) × 10^6 + microsecond × 10^3 + nanosecond).
|
// 6. Return ℤ(ℝ(ms) × 10^6 + microsecond × 10^3 + nanosecond).
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger::create_from(static_cast<i64>(ms)).multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 }).plus(Crypto::SignedBigInteger::create_from((i64)microsecond * 1000)).plus(Crypto::SignedBigInteger(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
|
// nsMinInstant - nsPerDay
|
||||||
|
@ -428,8 +429,7 @@ ThrowCompletionOr<Duration*> difference_temporal_plain_date_time(VM& vm, Differe
|
||||||
auto round_result = TRY(round_duration(vm, diff.years, diff.months, diff.weeks, diff.days, diff.hours, diff.minutes, diff.seconds, diff.milliseconds, diff.microseconds, diff.nanoseconds, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode, relative_to)).duration_record;
|
auto round_result = TRY(round_duration(vm, diff.years, diff.months, diff.weeks, diff.days, diff.hours, diff.minutes, diff.seconds, diff.milliseconds, diff.microseconds, diff.nanoseconds, settings.rounding_increment, settings.smallest_unit, settings.rounding_mode, relative_to)).duration_record;
|
||||||
|
|
||||||
// 8. Let result be ? BalanceDuration(roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], settings.[[LargestUnit]]).
|
// 8. Let result be ? BalanceDuration(roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], settings.[[LargestUnit]]).
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
auto result = MUST(balance_duration(vm, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, Crypto::SignedBigInteger { round_result.nanoseconds }, settings.largest_unit));
|
||||||
auto result = MUST(balance_duration(vm, round_result.days, round_result.hours, round_result.minutes, round_result.seconds, round_result.milliseconds, round_result.microseconds, Crypto::SignedBigInteger::create_from((i64)round_result.nanoseconds), settings.largest_unit));
|
|
||||||
|
|
||||||
// 9. Return ! CreateTemporalDuration(sign × roundResult.[[Years]], sign × roundResult.[[Months]], sign × roundResult.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
// 9. Return ! CreateTemporalDuration(sign × roundResult.[[Years]], sign × roundResult.[[Months]], sign × roundResult.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
|
||||||
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));
|
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));
|
||||||
|
|
|
@ -315,7 +315,7 @@ ThrowCompletionOr<PlainYearMonth*> add_duration_to_or_subtract_duration_from_pla
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let balanceResult be ? BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
|
// 3. Let balanceResult be ? BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
|
||||||
auto balance_result = TRY(balance_duration(vm, duration->days(), duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger::create_from((i64)duration->nanoseconds()), "day"sv));
|
auto balance_result = TRY(balance_duration(vm, duration->days(), duration->hours(), duration->minutes(), duration->seconds(), duration->milliseconds(), duration->microseconds(), Crypto::SignedBigInteger { duration->nanoseconds() }, "day"sv));
|
||||||
|
|
||||||
// 4. Set options to ? GetOptionsObject(options).
|
// 4. Set options to ? GetOptionsObject(options).
|
||||||
auto* options = TRY(get_options_object(vm, options_value));
|
auto* options = TRY(get_options_object(vm, options_value));
|
||||||
|
|
|
@ -182,9 +182,9 @@ i64 get_iana_time_zone_offset_nanoseconds(BigInt const& epoch_nanoseconds, Strin
|
||||||
// get_time_zone_offset(). We can safely assume that the TZDB has no useful information that far
|
// get_time_zone_offset(). We can safely assume that the TZDB has no useful information that far
|
||||||
// into the past and future anyway, so clamp it to the i64 range.
|
// into the past and future anyway, so clamp it to the i64 range.
|
||||||
Time time;
|
Time time;
|
||||||
if (seconds < Crypto::SignedBigInteger::create_from(NumericLimits<i64>::min()))
|
if (seconds < Crypto::SignedBigInteger { NumericLimits<i64>::min() })
|
||||||
time = Time::min();
|
time = Time::min();
|
||||||
else if (seconds > Crypto::SignedBigInteger::create_from(NumericLimits<i64>::max()))
|
else if (seconds > Crypto::SignedBigInteger { NumericLimits<i64>::max() })
|
||||||
time = Time::max();
|
time = Time::max();
|
||||||
else
|
else
|
||||||
time = Time::from_seconds(*seconds.to_base(10).to_int<i64>());
|
time = Time::from_seconds(*seconds.to_base(10).to_int<i64>());
|
||||||
|
|
|
@ -145,8 +145,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_possible_instants_for)
|
||||||
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());
|
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());
|
||||||
|
|
||||||
// b. Let possibleEpochNanoseconds be « epochNanoseconds - ℤ(timeZone.[[OffsetNanoseconds]]) ».
|
// b. Let possibleEpochNanoseconds be « epochNanoseconds - ℤ(timeZone.[[OffsetNanoseconds]]) ».
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
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->big_integer().minus(Crypto::SignedBigInteger::create_from(*time_zone->offset_nanoseconds()))));
|
|
||||||
}
|
}
|
||||||
// 5. Else,
|
// 5. Else,
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -61,8 +61,7 @@ ThrowCompletionOr<BigInt const*> interpret_iso_date_time_offset(VM& vm, i32 year
|
||||||
auto* epoch_nanoseconds = get_epoch_from_iso_parts(vm, 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);
|
||||||
|
|
||||||
// b. Set epochNanoseconds to epochNanoseconds - ℤ(offsetNanoseconds).
|
// b. Set epochNanoseconds to epochNanoseconds - ℤ(offsetNanoseconds).
|
||||||
// FIXME: Narrowing conversion from 'double' to 'i64'
|
auto offset_nanoseconds_bigint = Crypto::SignedBigInteger { offset_nanoseconds };
|
||||||
auto offset_nanoseconds_bigint = Crypto::SignedBigInteger::create_from((i64)offset_nanoseconds);
|
|
||||||
epoch_nanoseconds = js_bigint(vm, epoch_nanoseconds->big_integer().minus(offset_nanoseconds_bigint));
|
epoch_nanoseconds = js_bigint(vm, epoch_nanoseconds->big_integer().minus(offset_nanoseconds_bigint));
|
||||||
|
|
||||||
// c. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
// c. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
||||||
|
|
|
@ -370,7 +370,7 @@ JS::Value to_js_value(JS::VM& vm, Wasm::Value& wasm_value)
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
switch (wasm_value.type().kind()) {
|
switch (wasm_value.type().kind()) {
|
||||||
case Wasm::ValueType::I64:
|
case Wasm::ValueType::I64:
|
||||||
return realm.heap().allocate<JS::BigInt>(realm, ::Crypto::SignedBigInteger::create_from(wasm_value.to<i64>().value()));
|
return realm.heap().allocate<JS::BigInt>(realm, ::Crypto::SignedBigInteger { wasm_value.to<i64>().value() });
|
||||||
case Wasm::ValueType::I32:
|
case Wasm::ValueType::I32:
|
||||||
return JS::Value(wasm_value.to<i32>().value());
|
return JS::Value(wasm_value.to<i32>().value());
|
||||||
case Wasm::ValueType::F64:
|
case Wasm::ValueType::F64:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue