From 396b34b9b9caf865be9bd68353e84a8eac3591bb Mon Sep 17 00:00:00 2001 From: "kerui.lian" Date: Thu, 11 Jul 2024 23:31:13 +0800 Subject: [PATCH 01/10] fix(es/minifier): Fix compress pow NaN --- crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs | 5 +++++ crates/swc_ecma_minifier/src/compress/util/mod.rs | 4 ++++ crates/swc_ecma_minifier/tests/passing.txt | 1 + .../tests/terser/compress/evaluate/pow_nan/config.json | 3 +++ .../tests/terser/compress/evaluate/pow_nan/input.js | 1 + .../tests/terser/compress/evaluate/pow_nan/output.js | 1 + .../terser/compress/evaluate/pow_nan/output.mangleOnly.js | 1 + .../tests/terser/compress/evaluate/pow_nan/output.terser.js | 1 + 8 files changed, 17 insertions(+) create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/config.json create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/input.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.terser.js diff --git a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs index c10dcf89d754..89e1b5b25ae9 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs @@ -335,6 +335,11 @@ impl Optimizer<'_> { self.changed = true; report_change!("evaluate: Evaluated an expression as `{}`", value); + if value.is_nan() { + *e = Expr::Ident(Ident::new("NaN".into(), e.span())); + return; + } + *e = Expr::Lit(Lit::Num(Number { span: e.span(), value, diff --git a/crates/swc_ecma_minifier/src/compress/util/mod.rs b/crates/swc_ecma_minifier/src/compress/util/mod.rs index 1c5810af032f..e4ef606e4999 100644 --- a/crates/swc_ecma_minifier/src/compress/util/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/util/mod.rs @@ -514,6 +514,10 @@ pub(crate) fn eval_as_number(expr_ctx: &ExprCtx, e: &Expr) -> Option { let first = eval_as_number(expr_ctx, &args[0].expr)?; let second = eval_as_number(expr_ctx, &args[1].expr)?; + if first.is_nan() || second.is_nan() { + return Some(f64::NAN); + } + return Some(first.powf(second)); } diff --git a/crates/swc_ecma_minifier/tests/passing.txt b/crates/swc_ecma_minifier/tests/passing.txt index f454e7c65725..8c8545538bf9 100644 --- a/crates/swc_ecma_minifier/tests/passing.txt +++ b/crates/swc_ecma_minifier/tests/passing.txt @@ -535,6 +535,7 @@ 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 diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/config.json b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/config.json new file mode 100644 index 000000000000..3205e065ae01 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/config.json @@ -0,0 +1,3 @@ +{ + "evaluate": true +} diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/input.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/input.js new file mode 100644 index 000000000000..3aaaee6dea32 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/input.js @@ -0,0 +1 @@ +console.log(Math.pow(1, NaN)); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js new file mode 100644 index 000000000000..e389ab1d5e2f --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js @@ -0,0 +1 @@ +console.log(NaN); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js new file mode 100644 index 000000000000..e389ab1d5e2f --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js @@ -0,0 +1 @@ +console.log(NaN); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.terser.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.terser.js new file mode 100644 index 000000000000..e389ab1d5e2f --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.terser.js @@ -0,0 +1 @@ +console.log(NaN); \ No newline at end of file From dc0012650c39c698d1f24ab3b27f8887822050e1 Mon Sep 17 00:00:00 2001 From: "kerui.lian" Date: Fri, 12 Jul 2024 11:56:24 +0800 Subject: [PATCH 02/10] fix: add test for nan to the pow of 0 --- crates/swc_ecma_minifier/src/compress/util/mod.rs | 4 ++++ .../tests/terser/compress/evaluate/pow_nan_of_0/config.json | 3 +++ .../tests/terser/compress/evaluate/pow_nan_of_0/input.js | 1 + .../tests/terser/compress/evaluate/pow_nan_of_0/output.js | 1 + .../compress/evaluate/pow_nan_of_0/output.mangleOnly.js | 1 + .../terser/compress/evaluate/pow_nan_of_0/output.terser.js | 1 + 6 files changed, 11 insertions(+) create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js diff --git a/crates/swc_ecma_minifier/src/compress/util/mod.rs b/crates/swc_ecma_minifier/src/compress/util/mod.rs index 5738d3549b7e..787da45332d2 100644 --- a/crates/swc_ecma_minifier/src/compress/util/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/util/mod.rs @@ -514,6 +514,10 @@ pub(crate) fn eval_as_number(expr_ctx: &ExprCtx, e: &Expr) -> Option { let first = eval_as_number(expr_ctx, &args[0].expr)?; let second = eval_as_number(expr_ctx, &args[1].expr)?; + if second == 0.0 { + return Some(1.0); + } + if first.is_nan() || second.is_nan() { return Some(f64::NAN); } diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json new file mode 100644 index 000000000000..3205e065ae01 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json @@ -0,0 +1,3 @@ +{ + "evaluate": true +} diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js new file mode 100644 index 000000000000..77b51729c3ea --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js @@ -0,0 +1 @@ +console.log(Math.pow(NaN, 0)); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js new file mode 100644 index 000000000000..4e2e0f511572 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js @@ -0,0 +1 @@ +console.log(1); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js new file mode 100644 index 000000000000..296d5492b003 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js @@ -0,0 +1 @@ +console.log(1); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js new file mode 100644 index 000000000000..296d5492b003 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js @@ -0,0 +1 @@ +console.log(1); From 7aeed846f0ecb021d563e3e2e57a1e96d40d39d4 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 14:55:39 +0800 Subject: [PATCH 03/10] chore: rename --- .../compress/evaluate/{pow_nan_of_0 => pow_spec}/config.json | 0 .../terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/input.js | 0 .../terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/output.js | 0 .../evaluate/{pow_nan_of_0 => pow_spec}/output.mangleOnly.js | 0 .../compress/evaluate/{pow_nan_of_0 => pow_spec}/output.terser.js | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename crates/swc_ecma_minifier/tests/terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/config.json (100%) rename crates/swc_ecma_minifier/tests/terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/input.js (100%) rename crates/swc_ecma_minifier/tests/terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/output.js (100%) rename crates/swc_ecma_minifier/tests/terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/output.mangleOnly.js (100%) rename crates/swc_ecma_minifier/tests/terser/compress/evaluate/{pow_nan_of_0 => pow_spec}/output.terser.js (100%) diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/config.json similarity index 100% rename from crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/config.json rename to crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/config.json diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js similarity index 100% rename from crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/input.js rename to crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js similarity index 100% rename from crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.js rename to crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js similarity index 100% rename from crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.mangleOnly.js rename to crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js similarity index 100% rename from crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan_of_0/output.terser.js rename to crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js From 147d72a4a070db074139cd4d95a7576985e0212b Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 14:59:30 +0800 Subject: [PATCH 04/10] chore: update test case --- .../evaluate/pow_spec/expected.stdout | 81 ++++++++++++++++++ .../compress/evaluate/pow_spec/input.js | 80 ++++++++++++++++++ .../compress/evaluate/pow_spec/output.js | 82 ++++++++++++++++++- .../evaluate/pow_spec/output.mangleOnly.js | 82 ++++++++++++++++++- 4 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/expected.stdout diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/expected.stdout b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/expected.stdout new file mode 100644 index 000000000000..e50f2f14c9f3 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/expected.stdout @@ -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 diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js index 77b51729c3ea..562d5f9d153c 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/input.js @@ -1 +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)); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js index 4e2e0f511572..3d1bf52a0c95 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.js @@ -1 +1,81 @@ -console.log(1); \ No newline at end of file +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); diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js index 296d5492b003..562d5f9d153c 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.mangleOnly.js @@ -1 +1,81 @@ -console.log(1); +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)); From 16393b3f624c6507bddab0dc1168b2114d6fd431 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 15:04:32 +0800 Subject: [PATCH 05/10] chore: clean code --- crates/swc_ecma_minifier/src/compress/util/mod.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/swc_ecma_minifier/src/compress/util/mod.rs b/crates/swc_ecma_minifier/src/compress/util/mod.rs index 787da45332d2..eb4c8a007fd3 100644 --- a/crates/swc_ecma_minifier/src/compress/util/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/util/mod.rs @@ -511,18 +511,16 @@ pub(crate) fn eval_as_number(expr_ctx: &ExprCtx, e: &Expr) -> Option { 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)?; - if second == 0.0 { - return Some(1.0); - } - - if first.is_nan() || second.is_nan() { + // 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(first.powf(second)); + return Some(base.powf(exponent)); } _ => {} From 744d6fb49cb991c582309e5ac570e6299fe79386 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 15:08:37 +0800 Subject: [PATCH 06/10] chore: update test result --- crates/swc_ecma_minifier/tests/passing.txt | 2 ++ crates/swc_ecma_minifier/tests/postponed.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/tests/passing.txt b/crates/swc_ecma_minifier/tests/passing.txt index 8c8545538bf9..d55b19c0e816 100644 --- a/crates/swc_ecma_minifier/tests/passing.txt +++ b/crates/swc_ecma_minifier/tests/passing.txt @@ -541,6 +541,7 @@ 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 @@ -1246,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 diff --git a/crates/swc_ecma_minifier/tests/postponed.txt b/crates/swc_ecma_minifier/tests/postponed.txt index 84af33795ad7..e30420344eab 100644 --- a/crates/swc_ecma_minifier/tests/postponed.txt +++ b/crates/swc_ecma_minifier/tests/postponed.txt @@ -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 From 8ea754b8644b6c0e2a268633e4cb2354fcc7148f Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 15:36:22 +0800 Subject: [PATCH 07/10] fix: NaN context issue --- crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs index 89e1b5b25ae9..538ce9afca18 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs @@ -336,7 +336,12 @@ impl Optimizer<'_> { report_change!("evaluate: Evaluated an expression as `{}`", value); if value.is_nan() { - *e = Expr::Ident(Ident::new("NaN".into(), e.span())); + *e = Expr::Ident(Ident::new( + "NaN".into(), + e.span().with_ctxt( + SyntaxContext::empty().apply_mark(self.marks.unresolved_mark), + ), + )); return; } From 7a7199905e89e412f2fe4d2039f3cffceb27d163 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 16:02:10 +0800 Subject: [PATCH 08/10] chore: clean code --- .../tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js index e389ab1d5e2f..3aaaee6dea32 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.mangleOnly.js @@ -1 +1 @@ -console.log(NaN); \ No newline at end of file +console.log(Math.pow(1, NaN)); From d6ecb420e730eaec089c82a005158fc4ed2337c0 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 16:13:59 +0800 Subject: [PATCH 09/10] chore: update test cases --- .../tests/terser/compress/evaluate/pow_nan/output.js | 2 +- .../tests/terser/compress/evaluate/pow_spec/output.terser.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js index e389ab1d5e2f..e45215575f1b 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js @@ -1 +1 @@ -console.log(NaN); \ No newline at end of file +console.log(Math.pow(1,NaN)); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js index 296d5492b003..aed56a32b8ff 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_spec/output.terser.js @@ -1 +1 @@ -console.log(1); +console.log(Math.pow(NaN,NaN)),console.log(Math.pow(NaN,1/0)),console.log(Math.pow(NaN,2)),console.log(Math.pow(NaN,1)),console.log(Math.pow(NaN,0)),console.log(Math.pow(NaN,.5)),console.log(Math.pow(NaN,-1/0)),console.log(Math.pow(NaN,-1)),console.log(Math.pow(NaN,-0)),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,.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(Math.pow(2,NaN)),console.log(Math.pow(2,1/0)),console.log(Math.pow(2,2)),console.log(Math.pow(2,1)),console.log(Math.pow(2,0)),console.log(Math.pow(2,.5)),console.log(Math.pow(2,-1/0)),console.log(Math.pow(2,-1)),console.log(Math.pow(2,-0)),console.log(Math.pow(1,NaN)),console.log(Math.pow(1,1/0)),console.log(Math.pow(1,2)),console.log(Math.pow(1,1)),console.log(Math.pow(1,0)),console.log(Math.pow(1,.5)),console.log(Math.pow(1,-1/0)),console.log(Math.pow(1,-1)),console.log(Math.pow(1,-0)),console.log(Math.pow(.5,NaN)),console.log(Math.pow(.5,1/0)),console.log(Math.pow(.5,2)),console.log(Math.pow(.5,1)),console.log(Math.pow(.5,0)),console.log(Math.pow(.5,.5)),console.log(Math.pow(.5,-1/0)),console.log(Math.pow(.5,-1)),console.log(Math.pow(.5,-0)),console.log(Math.pow(0,NaN)),console.log(Math.pow(0,1/0)),console.log(Math.pow(0,2)),console.log(Math.pow(0,1)),console.log(Math.pow(0,0)),console.log(Math.pow(0,.5)),console.log(Math.pow(0,-1/0)),console.log(Math.pow(0,-1)),console.log(Math.pow(0,-0)),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,.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(Math.pow(-1,NaN)),console.log(Math.pow(-1,1/0)),console.log(Math.pow(-1,2)),console.log(Math.pow(-1,1)),console.log(Math.pow(-1,0)),console.log(Math.pow(-1,.5)),console.log(Math.pow(-1,-1/0)),console.log(Math.pow(-1,-1)),console.log(Math.pow(-1,-0)),console.log(Math.pow(-0,NaN)),console.log(Math.pow(-0,1/0)),console.log(Math.pow(-0,2)),console.log(Math.pow(-0,1)),console.log(Math.pow(-0,0)),console.log(Math.pow(-0,.5)),console.log(Math.pow(-0,-1/0)),console.log(Math.pow(-0,-1)),console.log(Math.pow(-0,-0)); \ No newline at end of file From 80d51819be58f531621e474982c751195a99bbb6 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 12 Jul 2024 17:24:38 +0800 Subject: [PATCH 10/10] chore: update test case --- .../tests/terser/compress/evaluate/pow_nan/output.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js index e45215575f1b..89e3dd4ea485 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/evaluate/pow_nan/output.js @@ -1 +1 @@ -console.log(Math.pow(1,NaN)); \ No newline at end of file +console.log(NaN);