Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date refactor #3595

Merged
merged 3 commits into from
Jan 23, 2024
Merged

Date refactor #3595

merged 3 commits into from
Jan 23, 2024

Conversation

raskad
Copy link
Member

@raskad raskad commented Jan 18, 2024

This pull request refactors the Date builtin to align it with the spec and enable all tests to pass.

The date operations by chrono are removed. This is necessary, because chrono only allows a limited date range from Jan 1, 262145 BCE to Dec 31, 262143 CE. The spec allows for dates from -271821-04-20T00:00:00.000Z to +275760-09-13T00:00:00.000Z. Instead most datetime specific operations are now performed by the functions that the spec specifies. The only thing that is done by the time create is the calculation of local timzone offsets. All other usages of chrono are also removed so we can remove the dependency.

@raskad raskad added bug Something isn't working builtins PRs and Issues related to builtins/intrinsics waiting-on-review Waiting on reviews from the maintainers labels Jan 18, 2024
@raskad raskad added this to the v0.18.0 milestone Jan 18, 2024
@raskad raskad requested a review from a team January 18, 2024 01:23
Copy link

Test262 conformance changes

Test result main count PR count difference
Total 95,960 95,960 0
Passed 76,572 76,588 +16
Ignored 18,477 18,477 0
Failed 911 895 -16
Panics 0 0 0
Conformance 79.80% 79.81% +0.02%
Fixed tests (16):
test/built-ins/Date/parse/time-value-maximum-range.js [strict mode] (previously Failed)
test/built-ins/Date/parse/time-value-maximum-range.js (previously Failed)
test/built-ins/Date/UTC/fp-evaluation-order.js [strict mode] (previously Failed)
test/built-ins/Date/UTC/fp-evaluation-order.js (previously Failed)
test/built-ins/Date/UTC/time-clip.js [strict mode] (previously Failed)
test/built-ins/Date/UTC/time-clip.js (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-11.js [strict mode] (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-11.js (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-9.js [strict mode] (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-9.js (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-10.js [strict mode] (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-10.js (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-12.js [strict mode] (previously Failed)
test/built-ins/Date/prototype/toISOString/15.9.5.43-0-12.js (previously Failed)
test/annexB/built-ins/Date/prototype/setYear/time-clip.js [strict mode] (previously Failed)
test/annexB/built-ins/Date/prototype/setYear/time-clip.js (previously Failed)

Copy link

codecov bot commented Jan 18, 2024

Codecov Report

Attention: 190 lines in your changes are missing coverage. Please review.

Comparison is base (e1d9a80) 47.35% compared to head (a291e8f) 47.33%.
Report is 8 commits behind head on main.

Files Patch % Lines
core/engine/src/builtins/date/utils.rs 65.83% 96 Missing ⚠️
core/engine/src/builtins/date/mod.rs 75.26% 92 Missing ⚠️
core/engine/src/object/builtins/jsdate.rs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3595      +/-   ##
==========================================
- Coverage   47.35%   47.33%   -0.03%     
==========================================
  Files         475      475              
  Lines       45919    46138     +219     
==========================================
+ Hits        21746    21839      +93     
- Misses      24173    24299     +126     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was taking a look at this. A lot of it looks great! Still have a bit more to review but wanted to run a question by you.

I think some of the utils in this have shared logic in the boa_temporal/utils. Would it be better to share the logic from boa_temporal/utils where possible instead of implementing it twice.

EDIT: Just checked the spec, the idea is actually to unify these but the blocker is 1087, but we seem to be treating the values in most case as the mathematical anyways. So it would probably be best to unify them where possible.

// 7. Let mn be 𝔽(ℝ(m) modulo 12).
let mn = modulo(m, 12.0) as u8;

// 8. Find a finite time value t such that YearFromTime(t) is ym, MonthFromTime(t) is mn,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's an outstanding issue on MakeDay here. Idk if it would be worth tracking it.

For reference

core/engine/src/builtins/date/utils.rs Show resolved Hide resolved
@nekevss nekevss requested a review from a team January 18, 2024 16:30
@raskad
Copy link
Member Author

raskad commented Jan 18, 2024

I think some of the utils in this have shared logic in the boa_temporal/utils. Would it be better to share the logic from boa_temporal/utils where possible instead of implementing it twice.

EDIT: Just checked the spec, the idea is actually to unify these but the blocker is 1087, but we seem to be treating the values in most case as the mathematical anyways. So it would probably be best to unify them where possible.

My first idea was that we may just go with the different implementations for now, until things like 1087 are resolved or the issue of how these are handeled in the spec is resolved. That way the temporal code could potentially evolve if needed and we have no cross cutting effort. But you are way more up to date on how the temporal spec, if you say the spec will probably not change considerably, I'm all for sharing the logic.

One thing to keep in mind is maybe optimizations. My feeling is that there is at least some optimization potential in the Date logic. For example there are places where functions are called multiple times that could be avoided etc. I wanted to take a detailed look later on and I'm not sure how that would change the interoperability as some Date specific optimizations may require specific logic.

@nekevss
Copy link
Member

nekevss commented Jan 18, 2024

We can keep it separate for now. I think some of this logic is fairly stable, so to speak, but there are still spec changes being made. I'd be surprised if the date equations changed much more, but airing on the cautious side doesn't hurt. Especially if there may be some places for optimizations as you said.

Copy link
Member

@nekevss nekevss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me overall. Nice work! There were a couple more things I came across, but nothing blocking.

core/engine/src/builtins/date/utils.rs Outdated Show resolved Hide resolved
}

// 2. Let truncated be ! ToIntegerOrInfinity(year).
let truncated = IntegerOrInfinity::from(year);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: is IntegerOrInfinity needed in this instance if we've already accounted for NaN?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, IntegerOrInfinity also rounds to an integer, so I think it's pretty much needed here.

Copy link
Member

@nekevss nekevss Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it's just truncating.

So I was just wondering whether this step could just be year.trunc() in this particular instance since the truncating here casts and then recasts back to f64.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm that is true... IntegerOrInfinity is mostly used to convert from f64 to an integer, or handle the non-finite edge cases, but here it's only used for the rounding...

Copy link
Member

@nekevss nekevss Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be left as is and merged. It was just something I saw when I was reviewing.

I think this could mostly be expressed as the below.

// Return non-finite cases
if !year.is_finite() {
    return year
}
// truncate
let trunc = year.trunc();

// Check if value is in range.
if (0.0..=99.0).contains(&year) {
    return 1900.0 + year
}

year

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I wanted to leave this for the optimizations later. For example in this case, every result of make_full_year gets passed to make_day afterwards. So there is definitley some potential to optimize this even across spec method boundaries.

@nekevss nekevss requested a review from a team January 19, 2024 04:09
Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like the refactor! It's a shame we cannot fully use integers because of the range of i64, but I think this is solved by Temporal in a much better way.

@raskad raskad added this pull request to the merge queue Jan 23, 2024
Merged via the queue into main with commit 0ed7da5 Jan 23, 2024
14 checks passed
@raskad raskad deleted the date-refactor branch January 23, 2024 21:27
@jedel1043 jedel1043 removed the waiting-on-review Waiting on reviews from the maintainers label Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working builtins PRs and Issues related to builtins/intrinsics
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants