Skip to content

Remove all user-space asUint/toUint in the libraries. #5194

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented Jun 7, 2025

Instead, we use Integer.toUnsignedLong(x).toDouble, which is semantically equivalent. The only remaining use of x >>> 0 is in the JS-only runtime libraries, notably RuntimeLong.

We add some optimizations to generate the best possible code on all targets.

For JS with RuntimeLong, we need to mark RuntimeLong.toDouble as fully inline. That is fine, as its body is actually very short (shorter than most methods of RuntimeLong). Moreover, we need a tailored rewrite in the optimizer to get rid of a Double addition of 0.0 + y when y is provably non-negative.

For JS with bigints, we directly fold (double) <toLongUnsigned>(x) into x >>> 0. Otherwise, we unnecessarily go through a bigint with Number(BigInt(x >>> 0)).

For Wasm, we fold the same shape into a single operation f64.convert_i32_u, which we add in WasmTransients.

@sjrd sjrd force-pushed the no-touint-in-lib branch 2 times, most recently from 7d70ace to 509e955 Compare June 8, 2025 09:08
@sjrd sjrd marked this pull request as ready for review June 8, 2025 09:08
@sjrd sjrd requested a review from gzm0 June 8, 2025 09:08
@sjrd
Copy link
Member Author

sjrd commented Jun 8, 2025

This will need a rebase on top of #5192 once it's merged, in order to also change the calls to toUint introduced there. Otherwise ready for review. Rebased.

sjrd added 2 commits June 8, 2025 22:53
We use these in some low-level routines, notably in `RuntimeLong`.
Introducing casts avoids unnecessary `AsInstanceOf`s around them.
Instead, we use `Integer.toUnsignedLong(x).toDouble`, which is
semantically equivalent. The only remaining use of `x >>> 0` is in
the JS-only runtime libraries, notably `RuntimeLong`.

We add some optimizations to generate the best possible code on all
targets.

For JS with `RuntimeLong`, we need to mark `RuntimeLong.toDouble`
as fully inline. That is fine, as its body is actually very short
(shorter than most methods of `RuntimeLong`). Moreover, we need a
tailored rewrite in the optimizer to get rid of a `Double` addition
of `0.0 + y` when `y` is provably non-negative.

For JS with `bigint`s, we directly fold
`(double) <toLongUnsigned>(x)` into `x >>> 0`. Otherwise, we
unnecessarily go through a `bigint` with `Number(BigInt(x >>> 0))`.

For Wasm, we fold the same shape into a single operation
`f64.convert_i32_u`, which we add in `WasmTransients`.
@sjrd sjrd force-pushed the no-touint-in-lib branch from 509e955 to 4127fd9 Compare June 8, 2025 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant