Skip to content

Commit 2b361e6

Browse files
Fnllmagic-akari
andauthored
fix(es/minifier): Fix compress pow NaN (#9210)
**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>
1 parent 181320a commit 2b361e6

File tree

15 files changed

+357
-4
lines changed

15 files changed

+357
-4
lines changed

crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ impl Optimizer<'_> {
345345
self.changed = true;
346346
report_change!("evaluate: Evaluated an expression as `{}`", value);
347347

348+
if value.is_nan() {
349+
*e = Ident::new(
350+
"NaN".into(),
351+
e.span(),
352+
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
353+
)
354+
.into();
355+
return;
356+
}
357+
348358
*e = Lit::Num(Number {
349359
span: e.span(),
350360
value,

crates/swc_ecma_minifier/src/compress/util/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,10 +512,16 @@ pub(crate) fn eval_as_number(expr_ctx: &ExprCtx, e: &Expr) -> Option<f64> {
512512
if args.len() != 2 {
513513
return None;
514514
}
515-
let first = eval_as_number(expr_ctx, &args[0].expr)?;
516-
let second = eval_as_number(expr_ctx, &args[1].expr)?;
515+
let base = eval_as_number(expr_ctx, &args[0].expr)?;
516+
let exponent = eval_as_number(expr_ctx, &args[1].expr)?;
517517

518-
return Some(first.powf(second));
518+
// https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-exponentiate
519+
// https://github.com/rust-lang/rust/issues/60468
520+
if exponent.is_nan() {
521+
return Some(f64::NAN);
522+
}
523+
524+
return Some(base.powf(exponent));
519525
}
520526

521527
_ => {}

crates/swc_ecma_minifier/tests/passing.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,11 +535,13 @@ evaluate/or/input.js
535535
evaluate/positive_zero/input.js
536536
evaluate/pow/input.js
537537
evaluate/pow_mixed/input.js
538+
evaluate/pow_nan/input.js
538539
evaluate/pow_sequence/input.js
539540
evaluate/pow_sequence_with_constants_and_parens/input.js
540541
evaluate/pow_sequence_with_parens/input.js
541542
evaluate/pow_sequence_with_parens_evaluated/input.js
542543
evaluate/pow_sequence_with_parens_exact/input.js
544+
evaluate/pow_spec/input.js
543545
evaluate/pow_with_number_constants/input.js
544546
evaluate/pow_with_right_side_evaluating_to_unary/input.js
545547
evaluate/prop_function/input.js
@@ -1245,6 +1247,7 @@ pure_getters/collapse_vars_2_strict/input.js
12451247
pure_getters/impure_getter_1/input.js
12461248
pure_getters/issue_2110_1/input.js
12471249
pure_getters/issue_2110_2/input.js
1250+
pure_getters/issue_2265_1/input.js
12481251
pure_getters/issue_2265_2/input.js
12491252
pure_getters/issue_2265_4/input.js
12501253
pure_getters/issue_2313_1/input.js

crates/swc_ecma_minifier/tests/postponed.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ pure_funcs/unary/input.js
111111
pure_getters/collapse_vars_1_true/input.js
112112
pure_getters/collapse_vars_2_true/input.js
113113
pure_getters/impure_getter_2/input.js
114-
pure_getters/issue_2265_1/input.js
115114
pure_getters/issue_2265_3/input.js
116115
pure_getters/issue_2313_6/input.js
117116
pure_getters/issue_2838/input.js
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"evaluate": true
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(Math.pow(1, NaN));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(NaN);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(Math.pow(1, NaN));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log(NaN);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"evaluate": true
3+
}

0 commit comments

Comments
 (0)