Repository: swc-project/swc (rust)

Issue:
wrongly transform function Infinity to 1/0
### Describe the bug
Infinity is wrongly transformed to 1/0
### Input code

```typescript
function Infinity(){
    console.log('xxx');
}
export default Infinity;
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": false
    },
    "target": "es5",
    "loose": false,
    "minify": {
      "compress": {
        "arguments": false,
        "arrows": true,
        "booleans": true,
        "booleans_as_integers": false,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": false,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true
      },
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.3.100&code=H4sIAAAAAAAAA0srzUsuyczPU%2FDMS8vMyyyp1NCs5lIAguT8vOL8nFS9nPx0DfWKigp1TWuuWq7UioL8ohKFlNS0xNKcErgmawCsssEKRwAAAA%3D%3D&config=H4sIAAAAAAAAA32US5LjIAyG932KlNe9nVnMAXo3Z6AICIc0Ri4k0nF15e4jY%2BcxHTk7W59%2BCSSh77fdrjuS6%2F7svuVTfkZbCMrtXyw0ZbZnsXTgBkuuxJG79ys90oyCTQTNdFlIx7b0wE1Fv1b3LiESXN1X2xBzDNNjQofDWIDowSZWiVcHyEz%2F61dW8GsGXOqjfY%2BYwOYXxFgyMTP0ULTADlOyI4E52aJEmU9qSyTUUsywMngzFhxVnn3kiFlyPlMP1huHHhQUCziOJ9BkkktkmeR6yn0a9rCvfd%2Ba%2FEMNJ5uqZSUnnFtL5LRK1ANGYhNq1kq4wI0aLHAt7k9lDKYA15KfdUeMeaMnnwBSgWSJsh1Ai9s8gszTljq8VMYcZGR5UrjMt3bLDL0U1cQYlMrOlYHCUetmAV8dzJV12nFWvFE%2Bih4MhCCzooSmr8juoCXlaQQMCpD%2B2qBN1QLM7RVu8PlBvMAfckvWB2z1GCwftilNwx7TiwQD8AH9CwdpBeM2LrIlzuM2r9mDjAZ41aVSA89LQB4Ao0ltWT7NhjwPiWj6hPv7mlgdLrclPNjc39%2F7soffVoduQF8bXDf83N9lL%2F%2Fu7k7XLXw7eBfp71XZkl7%2BAVPL6HotBgAA

### SWC Info output

1.3.100

### Expected behavior

don't turn to 1/0 like terser 
```js
function o(){console.log("xxx")}export default o;
```

### Actual behavior
```js
export default 1 / 0;
```

### Version

1.3.100

### Additional context

_No response_

Pull request:
fix(es/resolver): Resolve top-level `undefined`, `NaN`, and `Infinity` correctly
…aration correctly in es module

<!-- Note: CI script will automatically rebase your PR so please do not rebase unless required -->

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**Description:**

For following code
```js
var NaN = 1
console.log(NaN)
```
Result would be

|Envirnoment|Result|
|-|-|
|Non strict script(browser, nodejs repl)|NaN|
|Non strict script(nodejs script)|1|
|Strict script(browser, nodejs repl)|runtime error|
|Strict script(nodejs script)|1|
|ESM|1|

So SWC choose to behave like browser in script mode and confirm to esm standard.

**BREAKING CHANGE:**

<!--
If this PR introduces a breaking change, it must contain a notice for it to be included in the CHANGELOG. Add description or remove entirely if not breaking.

You may need to update `MIGRATION.md` for the breaking changes.
-->

**Related issue (if exists):**
Closes #8465 

Patch:
diff --git a/crates/swc_ecma_transforms_base/src/resolver/mod.rs b/crates/swc_ecma_transforms_base/src/resolver/mod.rs
index 928cee64d4..99cc82944b 100644
--- a/crates/swc_ecma_transforms_base/src/resolver/mod.rs
+++ b/crates/swc_ecma_transforms_base/src/resolver/mod.rs
@@ -148,6 +148,7 @@ pub fn resolver(
         current: Scope::new(ScopeKind::Fn, top_level_mark, None),
         ident_type: IdentType::Ref,
         in_type: false,
+        is_module: false,
         in_ts_module: false,
         decl_kind: DeclKind::Lexical,
         strict_mode: false,
@@ -204,6 +205,7 @@ struct Resolver<'a> {
     current: Scope<'a>,
     ident_type: IdentType,
     in_type: bool,
+    is_module: bool,
     in_ts_module: bool,
     decl_kind: DeclKind,
     strict_mode: bool,
@@ -225,6 +227,7 @@ impl<'a> Resolver<'a> {
             current,
             ident_type: IdentType::Ref,
             in_type: false,
+            is_module: false,
             in_ts_module: false,
             config,
             decl_kind: DeclKind::Lexical,
@@ -245,6 +248,7 @@ impl<'a> Resolver<'a> {
             ident_type: IdentType::Ref,
             config: self.config,
             in_type: self.in_type,
+            is_module: self.is_module,
             in_ts_module: self.in_ts_module,
             decl_kind: self.decl_kind,
             strict_mode: self.strict_mode,
@@ -306,7 +310,9 @@ impl<'a> Resolver<'a> {
                 return match &**sym {
                     // https://tc39.es/ecma262/multipage/global-object.html#sec-value-properties-of-the-global-object-infinity
                     // non configurable global value
-                    "undefined" | "NaN" | "Infinity" if mark == self.config.top_level_mark => {
+                    "undefined" | "NaN" | "Infinity"
+                        if mark == self.config.top_level_mark && !self.is_module =>
+                    {
                         Some(self.config.unresolved_mark)
                     }
                     _ => Some(mark),
@@ -1032,6 +1038,7 @@ impl<'a> VisitMut for Resolver<'a> {
 
     fn visit_mut_module(&mut self, module: &mut Module) {
         self.strict_mode = true;
+        self.is_module = true;
         module.visit_mut_children_with(self)
     }
 


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8465/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/8465/input.js
new file mode 100644
index 0000000000..4f5f1b5e99
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8465/input.js
@@ -0,0 +1,4 @@
+function Infinity() {
+    console.log("xxx");
+}
+export default Infinity;
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8465/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/8465/output.js
new file mode 100644
index 0000000000..fbca6caed6
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8465/output.js
@@ -0,0 +1,3 @@
+export default function() {
+    console.log("xxx");
+}
diff --git a/crates/swc_ecma_minifier/tests/terser_exec.rs b/crates/swc_ecma_minifier/tests/terser_exec.rs
index 1d4b4046ea..1fa1b1be0f 100644
--- a/crates/swc_ecma_minifier/tests/terser_exec.rs
+++ b/crates/swc_ecma_minifier/tests/terser_exec.rs
@@ -112,12 +112,12 @@ fn terser_exec(input: PathBuf) {
         eprintln!("Optimizing");
 
         let output = run(cm.clone(), &handler, &input, &config);
-        let output_module = match output {
+        let output_program = match output {
             Some(v) => v,
             None => return Err(()),
         };
 
-        let actual = print(cm, &[output_module], false, false);
+        let actual = print(cm, &[output_program], false, false);
         let actual_stdout = stdout_of(&actual, Duration::from_secs(5)).unwrap();
 
         if let Some(expected_src) = expected_src {
diff --git a/crates/swc_ecma_transforms_base/tests/resolver/issues/7685/output.js b/crates/swc_ecma_transforms_base/tests/resolver/issues/7685/output.js
index a31e62c38b..fcfeaf2b43 100644
--- a/crates/swc_ecma_transforms_base/tests/resolver/issues/7685/output.js
+++ b/crates/swc_ecma_transforms_base/tests/resolver/issues/7685/output.js
@@ -2,4 +2,4 @@ var NaN__2 = 1;
 {
     let NaN__3 = 1;
     console.log(NaN__3);
-}console.log(NaN);
+}console.log(NaN__2);
diff --git a/crates/swc_ecma_transforms_base/tests/resolver/minifier/10/output.js b/crates/swc_ecma_transforms_base/tests/resolver/minifier/10/output.js
index ef647e6cd5..1c7a9c4c44 100644
--- a/crates/swc_ecma_transforms_base/tests/resolver/minifier/10/output.js
+++ b/crates/swc_ecma_transforms_base/tests/resolver/minifier/10/output.js
@@ -1,2 +1,2 @@
 var NaN__2;
-console.log(NaN.toString());
+console.log(NaN__2.toString());
diff --git a/crates/swc_ecma_transforms_base/tests/resolver/minifier/11/output.js b/crates/swc_ecma_transforms_base/tests/resolver/minifier/11/output.js
index 3c827c9dce..9e66877fa2 100644
--- a/crates/swc_ecma_transforms_base/tests/resolver/minifier/11/output.js
+++ b/crates/swc_ecma_transforms_base/tests/resolver/minifier/11/output.js
@@ -1,2 +1,2 @@
 var NaN__2 = 5;
-console.log(NaN.toString());
+console.log(NaN__2.toString());
diff --git a/crates/swc_node_bundler/tests/pass/resolve-name-fix/output/entry.js b/crates/swc_node_bundler/tests/pass/resolve-name-fix/output/entry.js
index 7c9ee3755d..8809b109be 100644
--- a/crates/swc_node_bundler/tests/pass/resolve-name-fix/output/entry.js
+++ b/crates/swc_node_bundler/tests/pass/resolve-name-fix/output/entry.js
@@ -4570,7 +4570,7 @@ var load228 = __swcpack_require__.bind(void 0, function(module, exports) {
     var Math1 = global.Math;
     var RangeError1 = global.RangeError;
     // eslint-disable-next-line no-shadow-restricted-names
-    global.Infinity;
+    var Infinity1 = global.Infinity;
     var BaseBuffer = $ArrayBuffer;
     var abs = Math1.abs;
     var pow = Math1.pow;
@@ -4595,7 +4595,7 @@ var load228 = __swcpack_require__.bind(void 0, function(module, exports) {
         var e, m, c;
         value = abs(value);
         // eslint-disable-next-line no-self-compare
-        if (value != value || value === Infinity) {
+        if (value != value || value === Infinity1) {
             // eslint-disable-next-line no-self-compare
             m = value != value ? 1 : 0;
             e = eMax;
@@ -4645,7 +4645,7 @@ var load228 = __swcpack_require__.bind(void 0, function(module, exports) {
         nBits += mLen;
         for(; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
         if (e === 0) e = 1 - eBias;
-        else if (e === eMax) return m ? NaN : s ? -Infinity : Infinity;
+        else if (e === eMax) return m ? NaN : s ? -Infinity1 : Infinity1;
         else {
             m = m + pow(2, mLen);
             e = e - eBias;