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 <[email protected]>
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+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
NaN
2+
NaN
3+
NaN
4+
NaN
5+
1
6+
NaN
7+
NaN
8+
NaN
9+
1
10+
NaN
11+
Infinity
12+
Infinity
13+
Infinity
14+
1
15+
Infinity
16+
0
17+
0
18+
1
19+
NaN
20+
Infinity
21+
4
22+
2
23+
1
24+
1.4142135623730951
25+
0
26+
0.5
27+
1
28+
NaN
29+
NaN
30+
1
31+
1
32+
1
33+
1
34+
NaN
35+
1
36+
1
37+
NaN
38+
0
39+
0.25
40+
0.5
41+
1
42+
0.7071067811865476
43+
Infinity
44+
2
45+
1
46+
NaN
47+
0
48+
0
49+
0
50+
1
51+
0
52+
Infinity
53+
Infinity
54+
1
55+
NaN
56+
Infinity
57+
Infinity
58+
-Infinity
59+
1
60+
Infinity
61+
0
62+
-0
63+
1
64+
NaN
65+
NaN
66+
1
67+
-1
68+
1
69+
NaN
70+
NaN
71+
-1
72+
1
73+
NaN
74+
0
75+
0
76+
-0
77+
1
78+
0
79+
Infinity
80+
-Infinity
81+
1
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
console.log(Math.pow(NaN, NaN));
2+
console.log(Math.pow(NaN, Infinity));
3+
console.log(Math.pow(NaN, 2));
4+
console.log(Math.pow(NaN, 1));
5+
console.log(Math.pow(NaN, 0));
6+
console.log(Math.pow(NaN, 0.5));
7+
console.log(Math.pow(NaN, -Infinity));
8+
console.log(Math.pow(NaN, -1));
9+
console.log(Math.pow(NaN, -0));
10+
console.log(Math.pow(Infinity, NaN));
11+
console.log(Math.pow(Infinity, Infinity));
12+
console.log(Math.pow(Infinity, 2));
13+
console.log(Math.pow(Infinity, 1));
14+
console.log(Math.pow(Infinity, 0));
15+
console.log(Math.pow(Infinity, 0.5));
16+
console.log(Math.pow(Infinity, -Infinity));
17+
console.log(Math.pow(Infinity, -1));
18+
console.log(Math.pow(Infinity, -0));
19+
console.log(Math.pow(2, NaN));
20+
console.log(Math.pow(2, Infinity));
21+
console.log(Math.pow(2, 2));
22+
console.log(Math.pow(2, 1));
23+
console.log(Math.pow(2, 0));
24+
console.log(Math.pow(2, 0.5));
25+
console.log(Math.pow(2, -Infinity));
26+
console.log(Math.pow(2, -1));
27+
console.log(Math.pow(2, -0));
28+
console.log(Math.pow(1, NaN));
29+
console.log(Math.pow(1, Infinity));
30+
console.log(Math.pow(1, 2));
31+
console.log(Math.pow(1, 1));
32+
console.log(Math.pow(1, 0));
33+
console.log(Math.pow(1, 0.5));
34+
console.log(Math.pow(1, -Infinity));
35+
console.log(Math.pow(1, -1));
36+
console.log(Math.pow(1, -0));
37+
console.log(Math.pow(0.5, NaN));
38+
console.log(Math.pow(0.5, Infinity));
39+
console.log(Math.pow(0.5, 2));
40+
console.log(Math.pow(0.5, 1));
41+
console.log(Math.pow(0.5, 0));
42+
console.log(Math.pow(0.5, 0.5));
43+
console.log(Math.pow(0.5, -Infinity));
44+
console.log(Math.pow(0.5, -1));
45+
console.log(Math.pow(0.5, -0));
46+
console.log(Math.pow(0, NaN));
47+
console.log(Math.pow(0, Infinity));
48+
console.log(Math.pow(0, 2));
49+
console.log(Math.pow(0, 1));
50+
console.log(Math.pow(0, 0));
51+
console.log(Math.pow(0, 0.5));
52+
console.log(Math.pow(0, -Infinity));
53+
console.log(Math.pow(0, -1));
54+
console.log(Math.pow(0, -0));
55+
console.log(Math.pow(-Infinity, NaN));
56+
console.log(Math.pow(-Infinity, Infinity));
57+
console.log(Math.pow(-Infinity, 2));
58+
console.log(Math.pow(-Infinity, 1));
59+
console.log(Math.pow(-Infinity, 0));
60+
console.log(Math.pow(-Infinity, 0.5));
61+
console.log(Math.pow(-Infinity, -Infinity));
62+
console.log(Math.pow(-Infinity, -1));
63+
console.log(Math.pow(-Infinity, -0));
64+
console.log(Math.pow(-1, NaN));
65+
console.log(Math.pow(-1, Infinity));
66+
console.log(Math.pow(-1, 2));
67+
console.log(Math.pow(-1, 1));
68+
console.log(Math.pow(-1, 0));
69+
console.log(Math.pow(-1, 0.5));
70+
console.log(Math.pow(-1, -Infinity));
71+
console.log(Math.pow(-1, -1));
72+
console.log(Math.pow(-1, -0));
73+
console.log(Math.pow(-0, NaN));
74+
console.log(Math.pow(-0, Infinity));
75+
console.log(Math.pow(-0, 2));
76+
console.log(Math.pow(-0, 1));
77+
console.log(Math.pow(-0, 0));
78+
console.log(Math.pow(-0, 0.5));
79+
console.log(Math.pow(-0, -Infinity));
80+
console.log(Math.pow(-0, -1));
81+
console.log(Math.pow(-0, -0));
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
console.log(NaN);
2+
console.log(Math.pow(NaN, 1 / 0));
3+
console.log(NaN);
4+
console.log(NaN);
5+
console.log(1);
6+
console.log(NaN);
7+
console.log(Math.pow(NaN, -1 / 0));
8+
console.log(NaN);
9+
console.log(1);
10+
console.log(Math.pow(1 / 0, NaN));
11+
console.log(Math.pow(1 / 0, 1 / 0));
12+
console.log(Math.pow(1 / 0, 2));
13+
console.log(Math.pow(1 / 0, 1));
14+
console.log(Math.pow(1 / 0, 0));
15+
console.log(Math.pow(1 / 0, 0.5));
16+
console.log(Math.pow(1 / 0, -1 / 0));
17+
console.log(Math.pow(1 / 0, -1));
18+
console.log(Math.pow(1 / 0, -0));
19+
console.log(NaN);
20+
console.log(Math.pow(2, 1 / 0));
21+
console.log(4);
22+
console.log(2);
23+
console.log(1);
24+
console.log(1.4142135623730951);
25+
console.log(Math.pow(2, -1 / 0));
26+
console.log(0.5);
27+
console.log(1);
28+
console.log(NaN);
29+
console.log(Math.pow(1, 1 / 0));
30+
console.log(1);
31+
console.log(1);
32+
console.log(1);
33+
console.log(1);
34+
console.log(Math.pow(1, -1 / 0));
35+
console.log(1);
36+
console.log(1);
37+
console.log(NaN);
38+
console.log(Math.pow(0.5, 1 / 0));
39+
console.log(0.25);
40+
console.log(0.5);
41+
console.log(1);
42+
console.log(0.7071067811865476);
43+
console.log(Math.pow(0.5, -1 / 0));
44+
console.log(2);
45+
console.log(1);
46+
console.log(NaN);
47+
console.log(Math.pow(0, 1 / 0));
48+
console.log(0);
49+
console.log(0);
50+
console.log(1);
51+
console.log(0);
52+
console.log(Math.pow(0, -1 / 0));
53+
console.log(Infinity);
54+
console.log(1);
55+
console.log(Math.pow(-1 / 0, NaN));
56+
console.log(Math.pow(-1 / 0, 1 / 0));
57+
console.log(Math.pow(-1 / 0, 2));
58+
console.log(Math.pow(-1 / 0, 1));
59+
console.log(Math.pow(-1 / 0, 0));
60+
console.log(Math.pow(-1 / 0, 0.5));
61+
console.log(Math.pow(-1 / 0, -1 / 0));
62+
console.log(Math.pow(-1 / 0, -1));
63+
console.log(Math.pow(-1 / 0, -0));
64+
console.log(NaN);
65+
console.log(Math.pow(-1, 1 / 0));
66+
console.log(1);
67+
console.log(-1);
68+
console.log(1);
69+
console.log(NaN);
70+
console.log(Math.pow(-1, -1 / 0));
71+
console.log(-1);
72+
console.log(1);
73+
console.log(NaN);
74+
console.log(Math.pow(-0, 1 / 0));
75+
console.log(0);
76+
console.log(-0);
77+
console.log(1);
78+
console.log(0);
79+
console.log(Math.pow(-0, -1 / 0));
80+
console.log(-Infinity);
81+
console.log(1);

0 commit comments

Comments
 (0)