Latest Results
feat(es/minifier): Evaluate Math.floor, Math.ceil, Math.round and Mat… (#12117)
**Description:**
Extends `eval_as_number` with `Math.floor`, `Math.ceil`, `Math.round`
and `Math.sqrt`, next to the existing `cos` / `sin` / `min` / `max` /
`pow` arms.
Two things from the review of #11220:
**Output size.** A call is only replaced when the resulting literal is
strictly shorter than the call expression, so `Math.sqrt(2)` (12
characters) is left alone rather than becoming `1.4142135623730951` (18
characters).
Ties are rejected as well. `Math.sqrt(Math.PI)` and `1.7724538509055159`
are both 18 characters, but folding it lets a later pass inline the
literal in place of a 2 character binding at two call sites, which grew
`three.js` by 8 bytes. Rejecting ties keeps every size snapshot in the
repository unchanged.
The guard lives at the substitution site in
`compress/optimize/evaluate.rs`, not inside `eval_as_number`.
`eval_as_number` is recursive and returns a bare `f64`, so it cannot see
the original length, and declining there would also block the outer fold
in `Math.ceil(Math.sqrt(2))` Because the visitor is bottom up the inner
call is folded on its own before the outer one is considered, so both
are measured independently.
It applies only to these four methods so `Math.cos` and friends emit
exactly what they emit today.
**`Math.round` semantics.** ECMA-262 rounds ties towards `+Infinity`;
Rust's `f64::round` rounds ties away from zero, so they disagree on
every negative half, `Math.round(-1.5)` is `-1`, `(-1.5f64).round()` is
`-2`. The `(x + 0.5).floor()` shorthand is wrong too:
`0.49999999999999994 + 0.5` rounds up to `1.0` and yields `1` instead of
`0`. `js_round` handles both, and preserves `-0` for inputs in `[-0.5,
0)` since `1 / -0` is observable.
**Tests**
- `exec.rs` two tests that execute the code before and after
minification, covering negative ties, `NaN` / `±Infinity`, nested calls
and `-0` preservation.
- `pass-default/math-constant-folding` asserts the emitted text, so
folded, unfolded and tie cases are all pinned.
Full `cargo test -p swc_ecma_minifier` passes with no snapshot updates.
**Open question:** the existing `cos` / `sin` / `min` / `max` / `pow`
arms have no size guard. I kept the diff focused on the new methods but
happy to extend it to those if you'd prefer.
**Related issue:**
Fixes #11078 Latest Branches
0%
LingyuCoder:seal/fix-react-compiler-sourcemap 0%
0%
ken7253:fix/decorators-private-method-getter-params © 2026 CodSpeed Technology