Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
fs: use signed types for
stat
data #43714fs: use signed types for
stat
data #43714Changes from all commits
9920a07
0d1742a
7ab5e87
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may bring back #12607, #13255 and/or the infamous #12115. They are why the cast to
unsigned long
was introduced, IIRC.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a repro for that? I can understand why cast is needed for native JS numbers but not when it's transferred as
Float64
s. If the bug is platform dependent, CI should catch that.I've tried to put numbers from #13255 in
test-fs-stat-date.mjs
on amd64 and got following results:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading those fully:
Date
rounding which is a bit hacky and relied on non-negative numbers. I adjusted that part although it can be refactored into something else.unsigned long
helps.st_ino
collisions which are not affected by this particular cast.Overall it seems that precision loss is inevitable and accepted, and the solution is to simply use
{bigint:true}
whenever we deal with very precise and/or very large dates.I've ran a dumb test to see precision regression between
long
anddouble
and didn't see any difference (however, I'll definitely have to exclude borderline values from proper test 😅).https://ci.nodejs.org/job/node-stress-single-test/352/ -
double
https://ci.nodejs.org/job/node-stress-single-test/353/ -
long
Of course if I'm missing something else, it can be reverted to
long
. The only reason why I preferdouble
is that these values will end up being interptered as 64-bit floats on JS side.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You were right, it did indeed bring back "overflow" from #13255 on win32.
Adjusted the code so it only affects other platforms now.
Any chance for this
long
to become longer? I'd expectint64_t
or at leasttime_t
but not sure how breaking it would be.https://github.com/libuv/libuv/blob/c4d73c306b87e32acba3a77f933da72ac5604659/src/win/fs.c#L100
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking, I'm afraid.
long
was the wrong choice even back in 20131, whenuv_timespec_t
was introduced, but libuv can't change that without breaking ABI. How problematic is this for you?1 Gah, I even pointed it out but this particular instance slipped through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It leaves us with a choice on windows: we either support negative half of int32, or upper half of uint32. Y2038 is pretty close and we have an explicit test that it works:
node/test/parallel/test-fs-utimes-y2K38.js
Lines 45 to 48 in acd2a32
In current state of this PR, it fixes the issue for all platforms except windows, which is IMO the best solution for now.
On a larger scale, if Node.js will be ready to migrate to newer ABI, I'd like to see more appropriate types. In JS part, I think it would be reasonable to drop
Date
quirks in favor ofTemporal
: this will mean switching from ms to ns as "default" units, making bigints more necessary anddouble
/Float64
less accurate.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely forgot but I tried fixing pretty much the exact same issue in pretty much the exact same way in #32408... and looks like I ran into pretty much the exact same issues as you do now. 🤦
You can add a
Fixes: #32369
if/when this gets merged. That issue got closed by accident because I added aFixes:
tag to the libuv commit. Again 🤦There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, I guess searching for previous issues could save quite a time here. 😅