1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 07:27:45 +00:00

LibJS: Remove assertions that are now part of structured headers

This is an editorial change in the Temporal spec.

See:
- 7fbdd28
- f666243
- 8c7d066
- 307d108
- d9ca402

In practical terms this means we can now get rid of a couple of awkward
assertion steps that were no-ops anyway, since the types are enforced
by the compiler.
This commit is contained in:
Linus Groh 2022-03-09 23:51:53 +01:00
parent 97bd4cebab
commit 64e43c89bc
5 changed files with 86 additions and 106 deletions

View file

@ -70,9 +70,7 @@ ThrowCompletionOr<DurationRecord> to_temporal_duration_record(GlobalObject& glob
{
auto& vm = global_object.vm();
// 1. Assert: Type(temporalDurationLike) is Object.
// 2. If temporalDurationLike has an [[InitializedTemporalDuration]] internal slot, then
// 1. If temporalDurationLike has an [[InitializedTemporalDuration]] internal slot, then
if (is<Duration>(temporal_duration_like)) {
auto& duration = static_cast<Duration const&>(temporal_duration_like);
@ -80,13 +78,13 @@ ThrowCompletionOr<DurationRecord> to_temporal_duration_record(GlobalObject& glob
return DurationRecord { .years = duration.years(), .months = duration.months(), .weeks = duration.weeks(), .days = duration.days(), .hours = duration.hours(), .minutes = duration.minutes(), .seconds = duration.seconds(), .milliseconds = duration.milliseconds(), .microseconds = duration.microseconds(), .nanoseconds = duration.nanoseconds() };
}
// 3. Let result be a new Duration Record.
// 2. Let result be a new Duration Record.
auto result = DurationRecord {};
// 4. Let any be false.
// 3. Let any be false.
auto any = false;
// 5. For each row of Table 7, except the header row, in table order, do
// 4. For each row of Table 7, except the header row, in table order, do
for (auto& [field, property] : temporal_duration_like_properties<DurationRecord, double>(vm)) {
// a. Let prop be the Property Name value of the current row.
@ -111,13 +109,13 @@ ThrowCompletionOr<DurationRecord> to_temporal_duration_record(GlobalObject& glob
}
}
// 6. If any is false, then
// 5. If any is false, then
if (!any) {
// a. Throw a TypeError exception.
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalInvalidDurationLikeObject);
}
// 7. Return result.
// 6. Return result.
return result;
}
@ -287,10 +285,7 @@ ThrowCompletionOr<Duration*> create_temporal_duration(GlobalObject& global_objec
// 7.5.12 CreateNegatedTemporalDuration ( duration ), https://tc39.es/proposal-temporal/#sec-temporal-createnegatedtemporalduration
Duration* create_negated_temporal_duration(GlobalObject& global_object, Duration const& duration)
{
// 1. Assert: Type(duration) is Object.
// 2. Assert: duration has an [[InitializedTemporalDuration]] internal slot.
// 3. Return ! CreateTemporalDuration(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]]).
// 1. Return ! CreateTemporalDuration(duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]]).
return MUST(create_temporal_duration(global_object, -duration.years(), -duration.months(), -duration.weeks(), -duration.days(), -duration.hours(), -duration.minutes(), -duration.seconds(), -duration.milliseconds(), -duration.microseconds(), -duration.nanoseconds()));
}
@ -327,31 +322,30 @@ BigInt* total_duration_nanoseconds(GlobalObject& global_object, double days, dou
{
auto& vm = global_object.vm();
// 1. Assert: offsetShift is an integer.
VERIFY(offset_shift == trunc(offset_shift));
// 2. Set nanoseconds to (nanoseconds).
// 1. Set nanoseconds to (nanoseconds).
auto result_nanoseconds = nanoseconds.big_integer();
// 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));
// 3. If days ≠ 0, then
// 2. If days ≠ 0, then
if (days != 0) {
// a. Set nanoseconds to nanoseconds offsetShift.
result_nanoseconds = result_nanoseconds.minus(Crypto::SignedBigInteger::create_from(offset_shift));
}
// 4. Set hours to (hours) + (days) × 24.
// 3. 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)));
// 5. Set minutes to (minutes) + hours × 60.
// 4. Set minutes to (minutes) + hours × 60.
auto total_minutes = Crypto::SignedBigInteger::create_from(minutes).plus(total_hours.multiplied_by(Crypto::UnsignedBigInteger(60)));
// 6. Set seconds to (seconds) + minutes × 60.
// 5. Set seconds to (seconds) + minutes × 60.
auto total_seconds = Crypto::SignedBigInteger::create_from(seconds).plus(total_minutes.multiplied_by(Crypto::UnsignedBigInteger(60)));
// 7. Set milliseconds to (milliseconds) + seconds × 1000.
// 6. Set milliseconds to (milliseconds) + seconds × 1000.
auto total_milliseconds = Crypto::SignedBigInteger::create_from(milliseconds).plus(total_seconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
// 8. Set microseconds to (microseconds) + milliseconds × 1000.
// 7. Set microseconds to (microseconds) + milliseconds × 1000.
auto total_microseconds = Crypto::SignedBigInteger::create_from(microseconds).plus(total_milliseconds.multiplied_by(Crypto::UnsignedBigInteger(1000)));
// 9. Return nanoseconds + microseconds × 1000.
// 8. Return nanoseconds + microseconds × 1000.
return js_bigint(vm, result_nanoseconds.plus(total_microseconds.multiplied_by(Crypto::UnsignedBigInteger(1000))));
}
@ -900,20 +894,20 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
{
auto& vm = global_object.vm();
// FIXME: 1. Assert: y1, mon1, w1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, w2, d2, h2, min2, s2, ms2, mus2, ns2 are integer Number values.
VERIFY(all_of(AK::Array { years1, months1, weeks1, days1, hours1, minutes1, seconds1, milliseconds1, microseconds1, nanoseconds1, years2, months2, weeks2, days2, hours2, minutes2, seconds2, milliseconds2, microseconds2, nanoseconds2 }, [](auto value) { return value == trunc(value); }));
// 2. Let largestUnit1 be ! DefaultTemporalLargestUnit(y1, mon1, w1, d1, h1, min1, s1, ms1, mus1).
// 1. Let largestUnit1 be ! DefaultTemporalLargestUnit(y1, mon1, w1, d1, h1, min1, s1, ms1, mus1).
auto largest_unit1 = default_temporal_largest_unit(years1, months1, weeks1, days1, hours1, minutes1, seconds1, milliseconds1, microseconds1);
// 3. Let largestUnit2 be ! DefaultTemporalLargestUnit(y2, mon2, w2, d2, h2, min2, s2, ms2, mus2).
// 2. Let largestUnit2 be ! DefaultTemporalLargestUnit(y2, mon2, w2, d2, h2, min2, s2, ms2, mus2).
auto largest_unit2 = default_temporal_largest_unit(years2, months2, weeks2, days2, hours2, minutes2, seconds2, milliseconds2, microseconds2);
// 4. Let largestUnit be ! LargerOfTwoTemporalUnits(largestUnit1, largestUnit2).
// 3. Let largestUnit be ! LargerOfTwoTemporalUnits(largestUnit1, largestUnit2).
auto largest_unit = larger_of_two_temporal_units(largest_unit1, largest_unit2);
double years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds;
// 5. If relativeTo is undefined, then
// 4. If relativeTo is undefined, then
if (relative_to_value.is_undefined()) {
// a. If largestUnit is one of "year", "month", or "week", then
if (largest_unit.is_one_of("year"sv, "month"sv, "week"sv)) {
@ -956,7 +950,7 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
// l. Let nanoseconds be result.[[Nanoseconds]].
nanoseconds = result.nanoseconds;
}
// 6. Else if relativeTo has an [[InitializedTemporalDate]] internal slot, then
// 5. Else if relativeTo has an [[InitializedTemporalDate]] internal slot, then
else if (is<PlainDate>(relative_to_value.as_object())) {
auto& relative_to = static_cast<PlainDate&>(relative_to_value.as_object());
@ -1031,7 +1025,7 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
// w. Let nanoseconds be result.[[Nanoseconds]].
nanoseconds = result.nanoseconds;
}
// 7. Else,
// 6. Else,
else {
// a. Assert: relativeTo has an [[InitializedTemporalZonedDateTime]] internal slot.
auto& relative_to = verify_cast<ZonedDateTime>(relative_to_value.as_object());
@ -1123,30 +1117,27 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
}
}
// 8. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
// 7. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
if (!is_valid_duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
// 9. Return the Record { [[Years]]: years, [[Months]]: months, [[Weeks]]: weeks, [[Days]]: days, [[Hours]]: hours, [[Minutes]]: minutes, [[Seconds]]: seconds, [[Milliseconds]]: milliseconds, [[Microseconds]]: microseconds, [[Nanoseconds]]: nanoseconds }.
// 8. Return the Record { [[Years]]: years, [[Months]]: months, [[Weeks]]: weeks, [[Days]]: days, [[Hours]]: hours, [[Minutes]]: minutes, [[Seconds]]: seconds, [[Milliseconds]]: milliseconds, [[Microseconds]]: microseconds, [[Nanoseconds]]: nanoseconds }.
return DurationRecord { .years = years, .months = months, .weeks = weeks, .days = days, .hours = hours, .minutes = minutes, .seconds = seconds, .milliseconds = milliseconds, .microseconds = microseconds, .nanoseconds = nanoseconds };
}
// 7.5.20 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate
ThrowCompletionOr<MoveRelativeDateResult> move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration)
{
// 1. Assert: Type(relativeTo) is Object.
// 2. Assert: relativeTo has an [[InitializedTemporalDate]] internal slot.
// 3. Let options be ! OrdinaryObjectCreate(null).
// 1. Let options be ! OrdinaryObjectCreate(null).
auto* options = Object::create(global_object, nullptr);
// 4. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options).
// 2. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options).
auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration, options));
// 5. Let days be ! DaysUntil(relativeTo, newDate).
// 3. Let days be ! DaysUntil(relativeTo, newDate).
auto days = days_until(global_object, relative_to, *new_date);
// 6. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }.
// 4. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }.
return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days };
}
@ -1699,85 +1690,84 @@ ThrowCompletionOr<DurationRecord> to_limited_temporal_duration(GlobalObject& glo
// 7.5.25 TemporalDurationToString ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, precision ), https://tc39.es/proposal-temporal/#sec-temporal-temporaldurationtostring
String temporal_duration_to_string(double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Variant<StringView, u8> const& precision)
{
// 1. Assert: precision is not "minute".
if (precision.has<StringView>())
VERIFY(precision.get<StringView>() != "minute"sv);
VERIFY(precision.get<StringView>() == "auto"sv);
// 2. Set seconds to the mathematical value of seconds.
// 3. Set milliseconds to the mathematical value of milliseconds.
// 4. Set microseconds to the mathematical value of microseconds.
// 5. Set nanoseconds to the mathematical value of nanoseconds.
// 1. Set seconds to the mathematical value of seconds.
// 2. Set milliseconds to the mathematical value of milliseconds.
// 3. Set microseconds to the mathematical value of microseconds.
// 4. Set nanoseconds to the mathematical value of nanoseconds.
// 6. Let sign be ! DurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
// 5. Let sign be ! DurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
auto sign = duration_sign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds);
// 7. Set microseconds to microseconds + the integral part of nanoseconds / 1000.
// 6. Set microseconds to microseconds + the integral part of nanoseconds / 1000.
microseconds += trunc(nanoseconds / 1000);
// 8. Set nanoseconds to remainder(nanoseconds, 1000).
// 7. Set nanoseconds to remainder(nanoseconds, 1000).
nanoseconds = fmod(nanoseconds, 1000);
// 9. Set milliseconds to milliseconds + the integral part of microseconds / 1000.
// 8. Set milliseconds to milliseconds + the integral part of microseconds / 1000.
milliseconds += trunc(microseconds / 1000);
// 10. Set microseconds to remainder(microseconds, 1000).
// 9. Set microseconds to remainder(microseconds, 1000).
microseconds = fmod(microseconds, 1000);
// 11. Set seconds to seconds + the integral part of milliseconds / 1000.
// 10. Set seconds to seconds + the integral part of milliseconds / 1000.
seconds += trunc(milliseconds / 1000);
// 12. Set milliseconds to remainder(milliseconds, 1000).
// 11. Set milliseconds to remainder(milliseconds, 1000).
milliseconds = fmod(milliseconds, 1000);
// 13. Let datePart be "".
// 12. Let datePart be "".
StringBuilder date_part;
// 14. If years is not 0, then
// 13. If years is not 0, then
if (years != 0) {
// a. Set datePart to the string concatenation of abs(years) formatted as a decimal number and the code unit 0x0059 (LATIN CAPITAL LETTER Y).
date_part.appendff("{}", fabs(years));
date_part.append('Y');
}
// 15. If months is not 0, then
// 14. If months is not 0, then
if (months != 0) {
// a. Set datePart to the string concatenation of datePart, abs(months) formatted as a decimal number, and the code unit 0x004D (LATIN CAPITAL LETTER M).
date_part.appendff("{}", fabs(months));
date_part.append('M');
}
// 16. If weeks is not 0, then
// 15. If weeks is not 0, then
if (weeks != 0) {
// a. Set datePart to the string concatenation of datePart, abs(weeks) formatted as a decimal number, and the code unit 0x0057 (LATIN CAPITAL LETTER W).
date_part.appendff("{}", fabs(weeks));
date_part.append('W');
}
// 17. If days is not 0, then
// 16. If days is not 0, then
if (days != 0) {
// a. Set datePart to the string concatenation of datePart, abs(days) formatted as a decimal number, and the code unit 0x0044 (LATIN CAPITAL LETTER D).
date_part.appendff("{}", fabs(days));
date_part.append('D');
}
// 18. Let timePart be "".
// 17. Let timePart be "".
StringBuilder time_part;
// 19. If hours is not 0, then
// 18. If hours is not 0, then
if (hours != 0) {
// a. Set timePart to the string concatenation of abs(hours) formatted as a decimal number and the code unit 0x0048 (LATIN CAPITAL LETTER H).
time_part.appendff("{}", fabs(hours));
time_part.append('H');
}
// 20. If minutes is not 0, then
// 19. If minutes is not 0, then
if (minutes != 0) {
// a. Set timePart to the string concatenation of timePart, abs(minutes) formatted as a decimal number, and the code unit 0x004D (LATIN CAPITAL LETTER M).
time_part.appendff("{}", fabs(minutes));
time_part.append('M');
}
// 21. If any of seconds, milliseconds, microseconds, and nanoseconds are not 0; or years, months, weeks, days, hours, and minutes are all 0; or precision is not "auto"; then
// 20. If any of seconds, milliseconds, microseconds, and nanoseconds are not 0; or years, months, weeks, days, hours, and minutes are all 0; or precision is not "auto"; then
if ((seconds != 0 || milliseconds != 0 || microseconds != 0 || nanoseconds != 0) || (years == 0 && months == 0 && weeks == 0 && days == 0 && hours == 0 && minutes == 0) || (!precision.has<StringView>() || precision.get<StringView>() != "auto"sv)) {
// a. Let fraction be abs(milliseconds) × 10^6 + abs(microseconds) × 10^3 + abs(nanoseconds).
auto fraction = fabs(milliseconds) * 1'000'000 + fabs(microseconds) * 1'000 + fabs(nanoseconds);
@ -1820,23 +1810,23 @@ String temporal_duration_to_string(double years, double months, double weeks, do
time_part.append('S');
}
// 22. Let signPart be the code unit 0x002D (HYPHEN-MINUS) if sign < 0, and otherwise the empty String.
// 21. Let signPart be the code unit 0x002D (HYPHEN-MINUS) if sign < 0, and otherwise the empty String.
auto sign_part = sign < 0 ? "-"sv : ""sv;
// 23. Let result be the string concatenation of signPart, the code unit 0x0050 (LATIN CAPITAL LETTER P) and datePart.
// 22. Let result be the string concatenation of signPart, the code unit 0x0050 (LATIN CAPITAL LETTER P) and datePart.
StringBuilder result;
result.append(sign_part);
result.append('P');
result.append(date_part.string_view());
// 24. If timePart is not "", then
// 23. If timePart is not "", then
if (!time_part.is_empty()) {
// a. Set result to the string concatenation of result, the code unit 0x0054 (LATIN CAPITAL LETTER T), and timePart.
result.append('T');
result.append(time_part.string_view());
}
// 25. Return result.
// 24. Return result.
return result.to_string();
}

View file

@ -158,13 +158,10 @@ String temporal_duration_to_string(double years, double months, double weeks, do
template<typename EarlierObjectType, typename LaterObjectType>
double days_until(GlobalObject& global_object, EarlierObjectType& earlier, LaterObjectType& later)
{
// 1. Assert: earlier and later both have [[ISOYear]], [[ISOMonth]], and [[ISODay]] internal slots.
// NOTE: We could enforce this via concepts, but the compiler would complain anyway if either of the types doesn't have the methods used below.
// 2. Let difference be ! DifferenceISODate(earlier.[[ISOYear]], earlier.[[ISOMonth]], earlier.[[ISODay]], later.[[ISOYear]], later.[[ISOMonth]], later.[[ISODay]], "day").
// 1. Let difference be ! DifferenceISODate(earlier.[[ISOYear]], earlier.[[ISOMonth]], earlier.[[ISODay]], later.[[ISOYear]], later.[[ISOMonth]], later.[[ISODay]], "day").
auto difference = difference_iso_date(global_object, earlier.iso_year(), earlier.iso_month(), earlier.iso_day(), later.iso_year(), later.iso_month(), later.iso_day(), "day"sv);
// 3. Return difference.[[Days]].
// 2. Return difference.[[Days]].
return difference.days;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -151,10 +151,9 @@ ThrowCompletionOr<BigInt*> add_instant(GlobalObject& global_object, BigInt const
{
auto& vm = global_object.vm();
// 1. Assert: hours, minutes, seconds, milliseconds, microseconds, and nanoseconds are integer Number values.
VERIFY(hours == trunc(hours) && minutes == trunc(minutes) && seconds == trunc(seconds) && milliseconds == trunc(milliseconds) && microseconds == trunc(microseconds) && nanoseconds == trunc(nanoseconds));
// 2. 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,
epoch_nanoseconds.big_integer()
@ -165,11 +164,11 @@ ThrowCompletionOr<BigInt*> add_instant(GlobalObject& global_object, BigInt const
.plus(Crypto::SignedBigInteger::create_from((i64)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 })));
// 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))
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidEpochNanoseconds);
// 4. Return result.
// 3. Return result.
return result;
}

View file

@ -315,21 +315,19 @@ i8 compare_iso_date_time(i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8
// 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
ThrowCompletionOr<TemporalPlainDateTime> add_date_time(GlobalObject& global_object, 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: year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
// 2. Let timeResult be ! AddTime(hour, minute, second, millisecond, microsecond, nanosecond, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
// 1. 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);
// 3. Let datePart be ? CreateTemporalDate(year, month, day, calendar).
// 2. Let datePart be ? CreateTemporalDate(year, month, day, calendar).
auto* date_part = TRY(create_temporal_date(global_object, year, month, day, calendar));
// 4. Let dateDuration be ? CreateTemporalDuration(years, months, weeks, days + timeResult.[[Days]], 0, 0, 0, 0, 0, 0).
// 3. Let dateDuration be ? CreateTemporalDuration(years, months, weeks, days + timeResult.[[Days]], 0, 0, 0, 0, 0, 0).
auto* date_duration = TRY(create_temporal_duration(global_object, years, months, weeks, days + time_result.days, 0, 0, 0, 0, 0, 0));
// 5. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
// 4. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options));
// 6. Return the Record { [[Year]]: addedDate.[[ISOYear]], [[Month]]: addedDate.[[ISOMonth]], [[Day]]: addedDate.[[ISODay]], [[Hour]]: timeResult.[[Hour]], [[Minute]]: timeResult.[[Minute]], [[Second]]: timeResult.[[Second]], [[Millisecond]]: timeResult.[[Millisecond]], [[Microsecond]]: timeResult.[[Microsecond]], [[Nanosecond]]: timeResult.[[Nanosecond]] }.
// 5. Return the Record { [[Year]]: addedDate.[[ISOYear]], [[Month]]: addedDate.[[ISOMonth]], [[Day]]: addedDate.[[ISODay]], [[Hour]]: timeResult.[[Hour]], [[Minute]]: timeResult.[[Minute]], [[Second]]: timeResult.[[Second]], [[Millisecond]]: timeResult.[[Millisecond]], [[Microsecond]]: timeResult.[[Microsecond]], [[Nanosecond]]: timeResult.[[Nanosecond]] }.
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 };
}
@ -357,25 +355,23 @@ ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_
{
auto& vm = global_object.vm();
// 1. Assert: y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, and ns2 are integers.
// 2. If options is not present, set options to ! OrdinaryObjectCreate(null).
// 1. If options is not present, set options to ! OrdinaryObjectCreate(null).
if (!options)
options = Object::create(global_object, nullptr);
// 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
// 2. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2);
// 4. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
// 3. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds);
// 5. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
// 4. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1);
// 6. Let balanceResult be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]).
// 5. Let balanceResult be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]).
auto balance_result = balance_iso_date(year1, month1, day1 + time_difference.days);
// 7. If timeSign is -dateSign, then
// 6. If timeSign is -dateSign, then
if (time_sign == -date_sign) {
// a. Set balanceResult to ! BalanceISODate(balanceResult.[[Year]], balanceResult.[[Month]], balanceResult.[[Day]] - timeSign).
balance_result = balance_iso_date(balance_result.year, balance_result.month, balance_result.day - time_sign);
@ -384,25 +380,25 @@ ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_
time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, *js_bigint(vm, { (i32)time_difference.nanoseconds }), largest_unit));
}
// 8. Let date1 be ? CreateTemporalDate(balanceResult.[[Year]], balanceResult.[[Month]], balanceResult.[[Day]], calendar).
// 7. Let date1 be ? CreateTemporalDate(balanceResult.[[Year]], balanceResult.[[Month]], balanceResult.[[Day]], calendar).
auto* date1 = TRY(create_temporal_date(global_object, balance_result.year, balance_result.month, balance_result.day, calendar));
// 9. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar).
// 8. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar).
auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar));
// 10. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
// 9. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
// 11. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
// 10. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit));
// 12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
// 11. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options));
// 13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
// 12. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
auto balance_result_ = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, *js_bigint(vm, { (i32)time_difference.nanoseconds }), largest_unit));
// 14. Return the Record { [[Years]]: dateDifference.[[Years]], [[Months]]: dateDifference.[[Months]], [[Weeks]]: dateDifference.[[Weeks]], [[Days]]: balanceResult.[[Days]], [[Hours]]: balanceResult.[[Hours]], [[Minutes]]: balanceResult.[[Minutes]], [[Seconds]]: balanceResult.[[Seconds]], [[Milliseconds]]: balanceResult.[[Milliseconds]], [[Microseconds]]: balanceResult.[[Microseconds]], [[Nanoseconds]]: balanceResult.[[Nanoseconds]] }.
// 13. Return the Record { [[Years]]: dateDifference.[[Years]], [[Months]]: dateDifference.[[Months]], [[Weeks]]: dateDifference.[[Weeks]], [[Days]]: balanceResult.[[Days]], [[Hours]]: balanceResult.[[Hours]], [[Minutes]]: balanceResult.[[Minutes]], [[Seconds]]: balanceResult.[[Seconds]], [[Milliseconds]]: balanceResult.[[Milliseconds]], [[Microseconds]]: balanceResult.[[Microseconds]], [[Nanoseconds]]: balanceResult.[[Nanoseconds]] }.
return DurationRecord { .years = date_difference->years(), .months = date_difference->months(), .weeks = date_difference->weeks(), .days = balance_result_.days, .hours = balance_result_.hours, .minutes = balance_result_.minutes, .seconds = balance_result_.seconds, .milliseconds = balance_result_.milliseconds, .microseconds = balance_result_.microseconds, .nanoseconds = balance_result_.nanoseconds };
}

View file

@ -42,33 +42,31 @@ void PlainTime::visit_edges(Visitor& visitor)
// 4.5.1 DifferenceTime ( h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2 ), https://tc39.es/proposal-temporal/#sec-temporal-differencetime
TimeDurationRecord difference_time(u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2)
{
// Assert: h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, and ns2 are integers.
// 2. Let hours be h2 h1.
// 1. Let hours be h2 h1.
auto hours = hour2 - hour1;
// 3. Let minutes be min2 min1.
// 2. Let minutes be min2 min1.
auto minutes = minute2 - minute1;
// 4. Let seconds be s2 s1.
// 3. Let seconds be s2 s1.
auto seconds = second2 - second1;
// 5. Let milliseconds be ms2 ms1.
// 4. Let milliseconds be ms2 ms1.
auto milliseconds = millisecond2 - millisecond1;
// 6. Let microseconds be mus2 mus1.
// 5. Let microseconds be mus2 mus1.
auto microseconds = microsecond2 - microsecond1;
// 7. Let nanoseconds be ns2 ns1.
// 6. Let nanoseconds be ns2 ns1.
auto nanoseconds = nanosecond2 - nanosecond1;
// 8. Let sign be ! DurationSign(0, 0, 0, 0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
// 7. Let sign be ! DurationSign(0, 0, 0, 0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
auto sign = duration_sign(0, 0, 0, 0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds);
// 9. Let bt be ! BalanceTime(hours × sign, minutes × sign, seconds × sign, milliseconds × sign, microseconds × sign, nanoseconds × sign).
// 8. Let bt be ! BalanceTime(hours × sign, minutes × sign, seconds × sign, milliseconds × sign, microseconds × sign, nanoseconds × sign).
auto bt = balance_time(hours * sign, minutes * sign, seconds * sign, milliseconds * sign, microseconds * sign, nanoseconds * sign);
// 10. Return the Record { [[Days]]: bt.[[Days]] × sign, [[Hours]]: bt.[[Hour]] × sign, [[Minutes]]: bt.[[Minute]] × sign, [[Seconds]]: bt.[[Second]] × sign, [[Milliseconds]]: bt.[[Millisecond]] × sign, [[Microseconds]]: bt.[[Microsecond]] × sign, [[Nanoseconds]]: bt.[[Nanosecond]] × sign }.
// 9. Return the Record { [[Days]]: bt.[[Days]] × sign, [[Hours]]: bt.[[Hour]] × sign, [[Minutes]]: bt.[[Minute]] × sign, [[Seconds]]: bt.[[Second]] × sign, [[Milliseconds]]: bt.[[Millisecond]] × sign, [[Microseconds]]: bt.[[Microsecond]] × sign, [[Nanoseconds]]: bt.[[Nanosecond]] × sign }.
return TimeDurationRecord { .days = static_cast<double>(bt.days * sign), .hours = static_cast<double>(bt.hour * sign), .minutes = static_cast<double>(bt.minute * sign), .seconds = static_cast<double>(bt.second * sign), .milliseconds = static_cast<double>(bt.millisecond * sign), .microseconds = static_cast<double>(bt.microsecond * sign), .nanoseconds = static_cast<double>(bt.nanosecond * sign) };
}