Skip to content

Commit

Permalink
fix(es/minifier): Fix compress pow NaN (#9210)
Browse files Browse the repository at this point in the history
**Description:**

`f64::powf` for `NaN` returns 1 instead of `NaN`, see
rust-lang/rust#60468. We should handle that.

**Related issue:**

 - Closes #9193

---------

Co-authored-by: magic-akari <akari.ccino@gmail.com>
  • Loading branch information
Fnll and magic-akari committed Jul 12, 2024
1 parent 181320a commit 2b361e6
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 4 deletions.
10 changes: 10 additions & 0 deletions crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,16 @@ impl Optimizer<'_> {
self.changed = true;
report_change!("evaluate: Evaluated an expression as `{}`", value);

if value.is_nan() {
*e = Ident::new(
"NaN".into(),
e.span(),
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
)
.into();
return;
}

*e = Lit::Num(Number {
span: e.span(),
value,
Expand Down
12 changes: 9 additions & 3 deletions crates/swc_ecma_minifier/src/compress/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,16 @@ pub(crate) fn eval_as_number(expr_ctx: &ExprCtx, e: &Expr) -> Option<f64> {
if args.len() != 2 {
return None;
}
let first = eval_as_number(expr_ctx, &args[0].expr)?;
let second = eval_as_number(expr_ctx, &args[1].expr)?;
let base = eval_as_number(expr_ctx, &args[0].expr)?;
let exponent = eval_as_number(expr_ctx, &args[1].expr)?;

return Some(first.powf(second));
// https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-exponentiate
// https://github.com/rust-lang/rust/issues/60468
if exponent.is_nan() {
return Some(f64::NAN);
}

return Some(base.powf(exponent));
}

_ => {}
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_ecma_minifier/tests/passing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,13 @@ evaluate/or/input.js
evaluate/positive_zero/input.js
evaluate/pow/input.js
evaluate/pow_mixed/input.js
evaluate/pow_nan/input.js
evaluate/pow_sequence/input.js
evaluate/pow_sequence_with_constants_and_parens/input.js
evaluate/pow_sequence_with_parens/input.js
evaluate/pow_sequence_with_parens_evaluated/input.js
evaluate/pow_sequence_with_parens_exact/input.js
evaluate/pow_spec/input.js
evaluate/pow_with_number_constants/input.js
evaluate/pow_with_right_side_evaluating_to_unary/input.js
evaluate/prop_function/input.js
Expand Down Expand Up @@ -1245,6 +1247,7 @@ pure_getters/collapse_vars_2_strict/input.js
pure_getters/impure_getter_1/input.js
pure_getters/issue_2110_1/input.js
pure_getters/issue_2110_2/input.js
pure_getters/issue_2265_1/input.js
pure_getters/issue_2265_2/input.js
pure_getters/issue_2265_4/input.js
pure_getters/issue_2313_1/input.js
Expand Down
1 change: 0 additions & 1 deletion crates/swc_ecma_minifier/tests/postponed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ pure_funcs/unary/input.js
pure_getters/collapse_vars_1_true/input.js
pure_getters/collapse_vars_2_true/input.js
pure_getters/impure_getter_2/input.js
pure_getters/issue_2265_1/input.js
pure_getters/issue_2265_3/input.js
pure_getters/issue_2313_6/input.js
pure_getters/issue_2838/input.js
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"evaluate": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(Math.pow(1, NaN));
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(NaN);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(Math.pow(1, NaN));
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(NaN);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"evaluate": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
NaN
NaN
NaN
NaN
1
NaN
NaN
NaN
1
NaN
Infinity
Infinity
Infinity
1
Infinity
0
0
1
NaN
Infinity
4
2
1
1.4142135623730951
0
0.5
1
NaN
NaN
1
1
1
1
NaN
1
1
NaN
0
0.25
0.5
1
0.7071067811865476
Infinity
2
1
NaN
0
0
0
1
0
Infinity
Infinity
1
NaN
Infinity
Infinity
-Infinity
1
Infinity
0
-0
1
NaN
NaN
1
-1
1
NaN
NaN
-1
1
NaN
0
0
-0
1
0
Infinity
-Infinity
1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
console.log(Math.pow(NaN, NaN));
console.log(Math.pow(NaN, Infinity));
console.log(Math.pow(NaN, 2));
console.log(Math.pow(NaN, 1));
console.log(Math.pow(NaN, 0));
console.log(Math.pow(NaN, 0.5));
console.log(Math.pow(NaN, -Infinity));
console.log(Math.pow(NaN, -1));
console.log(Math.pow(NaN, -0));
console.log(Math.pow(Infinity, NaN));
console.log(Math.pow(Infinity, Infinity));
console.log(Math.pow(Infinity, 2));
console.log(Math.pow(Infinity, 1));
console.log(Math.pow(Infinity, 0));
console.log(Math.pow(Infinity, 0.5));
console.log(Math.pow(Infinity, -Infinity));
console.log(Math.pow(Infinity, -1));
console.log(Math.pow(Infinity, -0));
console.log(Math.pow(2, NaN));
console.log(Math.pow(2, Infinity));
console.log(Math.pow(2, 2));
console.log(Math.pow(2, 1));
console.log(Math.pow(2, 0));
console.log(Math.pow(2, 0.5));
console.log(Math.pow(2, -Infinity));
console.log(Math.pow(2, -1));
console.log(Math.pow(2, -0));
console.log(Math.pow(1, NaN));
console.log(Math.pow(1, Infinity));
console.log(Math.pow(1, 2));
console.log(Math.pow(1, 1));
console.log(Math.pow(1, 0));
console.log(Math.pow(1, 0.5));
console.log(Math.pow(1, -Infinity));
console.log(Math.pow(1, -1));
console.log(Math.pow(1, -0));
console.log(Math.pow(0.5, NaN));
console.log(Math.pow(0.5, Infinity));
console.log(Math.pow(0.5, 2));
console.log(Math.pow(0.5, 1));
console.log(Math.pow(0.5, 0));
console.log(Math.pow(0.5, 0.5));
console.log(Math.pow(0.5, -Infinity));
console.log(Math.pow(0.5, -1));
console.log(Math.pow(0.5, -0));
console.log(Math.pow(0, NaN));
console.log(Math.pow(0, Infinity));
console.log(Math.pow(0, 2));
console.log(Math.pow(0, 1));
console.log(Math.pow(0, 0));
console.log(Math.pow(0, 0.5));
console.log(Math.pow(0, -Infinity));
console.log(Math.pow(0, -1));
console.log(Math.pow(0, -0));
console.log(Math.pow(-Infinity, NaN));
console.log(Math.pow(-Infinity, Infinity));
console.log(Math.pow(-Infinity, 2));
console.log(Math.pow(-Infinity, 1));
console.log(Math.pow(-Infinity, 0));
console.log(Math.pow(-Infinity, 0.5));
console.log(Math.pow(-Infinity, -Infinity));
console.log(Math.pow(-Infinity, -1));
console.log(Math.pow(-Infinity, -0));
console.log(Math.pow(-1, NaN));
console.log(Math.pow(-1, Infinity));
console.log(Math.pow(-1, 2));
console.log(Math.pow(-1, 1));
console.log(Math.pow(-1, 0));
console.log(Math.pow(-1, 0.5));
console.log(Math.pow(-1, -Infinity));
console.log(Math.pow(-1, -1));
console.log(Math.pow(-1, -0));
console.log(Math.pow(-0, NaN));
console.log(Math.pow(-0, Infinity));
console.log(Math.pow(-0, 2));
console.log(Math.pow(-0, 1));
console.log(Math.pow(-0, 0));
console.log(Math.pow(-0, 0.5));
console.log(Math.pow(-0, -Infinity));
console.log(Math.pow(-0, -1));
console.log(Math.pow(-0, -0));
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
console.log(NaN);
console.log(Math.pow(NaN, 1 / 0));
console.log(NaN);
console.log(NaN);
console.log(1);
console.log(NaN);
console.log(Math.pow(NaN, -1 / 0));
console.log(NaN);
console.log(1);
console.log(Math.pow(1 / 0, NaN));
console.log(Math.pow(1 / 0, 1 / 0));
console.log(Math.pow(1 / 0, 2));
console.log(Math.pow(1 / 0, 1));
console.log(Math.pow(1 / 0, 0));
console.log(Math.pow(1 / 0, 0.5));
console.log(Math.pow(1 / 0, -1 / 0));
console.log(Math.pow(1 / 0, -1));
console.log(Math.pow(1 / 0, -0));
console.log(NaN);
console.log(Math.pow(2, 1 / 0));
console.log(4);
console.log(2);
console.log(1);
console.log(1.4142135623730951);
console.log(Math.pow(2, -1 / 0));
console.log(0.5);
console.log(1);
console.log(NaN);
console.log(Math.pow(1, 1 / 0));
console.log(1);
console.log(1);
console.log(1);
console.log(1);
console.log(Math.pow(1, -1 / 0));
console.log(1);
console.log(1);
console.log(NaN);
console.log(Math.pow(0.5, 1 / 0));
console.log(0.25);
console.log(0.5);
console.log(1);
console.log(0.7071067811865476);
console.log(Math.pow(0.5, -1 / 0));
console.log(2);
console.log(1);
console.log(NaN);
console.log(Math.pow(0, 1 / 0));
console.log(0);
console.log(0);
console.log(1);
console.log(0);
console.log(Math.pow(0, -1 / 0));
console.log(Infinity);
console.log(1);
console.log(Math.pow(-1 / 0, NaN));
console.log(Math.pow(-1 / 0, 1 / 0));
console.log(Math.pow(-1 / 0, 2));
console.log(Math.pow(-1 / 0, 1));
console.log(Math.pow(-1 / 0, 0));
console.log(Math.pow(-1 / 0, 0.5));
console.log(Math.pow(-1 / 0, -1 / 0));
console.log(Math.pow(-1 / 0, -1));
console.log(Math.pow(-1 / 0, -0));
console.log(NaN);
console.log(Math.pow(-1, 1 / 0));
console.log(1);
console.log(-1);
console.log(1);
console.log(NaN);
console.log(Math.pow(-1, -1 / 0));
console.log(-1);
console.log(1);
console.log(NaN);
console.log(Math.pow(-0, 1 / 0));
console.log(0);
console.log(-0);
console.log(1);
console.log(0);
console.log(Math.pow(-0, -1 / 0));
console.log(-Infinity);
console.log(1);
Loading

0 comments on commit 2b361e6

Please sign in to comment.