Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@swc/wasm-typescript exits on Windows arm64 when fed with certain syntax #9520

Open
wojtekmaj opened this issue Aug 31, 2024 · 38 comments
Open
Assignees
Labels
Milestone

Comments

@wojtekmaj
Copy link

wojtekmaj commented Aug 31, 2024

Describe the bug

After investigation in nodejs/node#54645 I finally came to conclusion that on Windows arm64 (this particular configuration, not Windows other than arm64, not arm64 other than Windows), swc fails to transform certain syntax and just silently exits instead.

Input code

export function foo() {
	if (false) {
	}
	return 'foo';
};

Config

n/a

Playground link (or link to the minimal reproduction)

https://gist.github.com/wojtekmaj/c37e1eb07676cde83e5201ade8b7f02f

SWC Info output

Operating System:
    Platform: win32
    Arch: arm64
    Machine Type: unknown
    Version: Windows 11 Home
    CPU: (12 cores)
        Models: Snapdragon(R) X 12-core X1E80100 @ 3.40 GHz

Binaries:
    Node: 22.7.0
    npm: N/A
    Yarn: N/A
    pnpm: N/A

Relevant Packages:
    @swc/core: N/A
    @swc/helpers: N/A
    @swc/types: N/A


SWC Config:
    output: N/A
    .swcrc path: N/A

Next.js info:
    output: N/A

Expected behavior

Code should be transformed, types should be stripped, swc should not silently exit.

Actual behavior

swc silently exists, and neither the output, nor "End 2" console.log (see playground link) never appears on the screen.

Version

1.7.22

Additional context

No response

@kdy1 kdy1 added this to the Planned milestone Sep 1, 2024
@wojtekmaj wojtekmaj changed the title @swc/wasm-typescript exists on Windows arm64 when fed with certain syntax @swc/wasm-typescript exits on Windows arm64 when fed with certain syntax Sep 1, 2024
@kdy1 kdy1 self-assigned this Sep 3, 2024
@magic-akari
Copy link
Member

Is this issue only related to the strip-only?
You can check it by adding the option mode: "transform" as shown below:

import { transformSync } from "@swc/wasm-typescript";

const options = {
	mode: "transform",
	transform: {
		verbatimModuleSyntax: true,
		nativeClassProperties: true,
		noEmptyExport: true,
		importNotUsedAsValues: "preserve",
	}
}

console.log("Begin 1");
console.log(
	transformSync(`
export function foo() {
	return 'foo';
};
`, options).code,
);
console.log("End 1");

console.log("Begin 2");
console.log(
	transformSync(`
export function foo() {
	if (false) {
	}
	return 'foo';
};
`, options).code,
);
console.log("End 2");

@wojtekmaj
Copy link
Author

@magic-akari No luck:

PS C:\test> node swc.js 
Begin 1
export function foo() {
    return 'foo';
}

End 1
Begin 2

@magic-akari
Copy link
Member

It's suspected that the issue arises at an earlier stage, possibly in the parser.

@wojtekmaj
Copy link
Author

wojtekmaj commented Sep 6, 2024

It's my first encounter with swc, so apologies if my diagnosis so far aren't the best, but I'll do my best to help out. The hardware is yours to experiment on :D

@magic-akari
Copy link
Member

let's do more experiments to pinpoint this issue.

  1. Test the strip-only mode in your browser by clicking this link:
    https://play.swc.rs/?version=1.7.23&code=H4sIAAAAAAAAA0utKMgvKlFIK81LLsnMz1NIy8%2FX0FSo5uLMTFPQSEvMKU4F82q5OItSS0qL8hTUgSrUrblqrQGZRHv4OgAAAA%3D%3D&config=H4sIAAAAAAAAA6vmUlBQyipOVrJSqAYygZyCxKLi1CI4HyhSXJlXklgBFFFKTc5NLE4uyiwoUQJL1nKBcC0ABwZxP0UAAAA%3D&strip-types=

  2. Check the parser's functionality in your browser using this link:
    https://swc-ast.vercel.app/#code/KYDwDg9gTgLgBAMwK4DsDGMCWEWIhACgEo4BvAKAEhME4CEBDAGwGdgSLKBfKqYGJFFwByBPmEBuclwlA

  3. Run this command to verify the parser's functionality in Node:

npx swc_ast_viewer path/to/your_file.js

@wojtekmaj
Copy link
Author

wojtekmaj commented Sep 11, 2024

@magic-akari

Ad 1 - This worked perfectly fine, on latest Microsoft Edge, arm64 build. input === output.
Ad 2 - This resulted in the following output (no crash):

Output Module( Module { span: 1..59, body: [ ModuleDecl( ExportDecl( ExportDecl { span: 1..58, decl: Fn( FnDecl { ident: Ident { span: 17..20, ctxt: #2, sym: "foo", optional: false, }, declare: false, function: Function { params: [], decorators: [], span: 8..58, ctxt: #3, body: Some( BlockStmt { span: 23..58, ctxt: #3, stmts: [ If( IfStmt { span: 26..41, test: Lit( Bool( Bool { span: 30..35, value: false, }, ), ), cons: Block( BlockStmt { span: 37..41, ctxt: #4, stmts: [], }, ), alt: None, }, ), Return( ReturnStmt { span: 43..56, arg: Some( Lit( Str( Str { span: 50..55, value: "foo", raw: Some( "'foo'", ), }, ), ), ), }, ), ], }, ), is_generator: false, is_async: false, type_params: None, return_type: None, }, }, ), }, ), ), Stmt( Empty( EmptyStmt { span: 58..59, }, ), ), ], shebang: None, }, )
Ad 3 - This just prints the version number, regardless of the file I'm feeding it (!):
PS C:\test> npx swc_ast_viewer ./simple-file.ts
swc@0.103.1

@magic-akari
Copy link
Member

It seems that our WASM version parser isn't working on Windows ARM64 with Node.js.
The lack of error messages from WASM, which just exits quietly, complicates debugging.

Moreover, there are no methods in WASM that trigger process.exit, and I think that exiting silently is an unexpected behavior in Node.js.

What are your thoughts? @kdy1

@marco-ippolito
Copy link
Contributor

My feeling is that there is no crash/error, it simply exits the transpilation early with an empty output.
Github recently released arm64 windows runner, we could use that to reproduce.

@kdy1
Copy link
Member

kdy1 commented Sep 11, 2024

@magic-akari I think we can use the CI of SWC. You can add some node.js tests and run the publish action with only nightly enabled.
I'll do it soon.

@kdy1
Copy link
Member

kdy1 commented Sep 11, 2024

Let's try with @swc/core first.
I made #9547 and triggered https://github.com/swc-project/swc/actions/runs/10810667484

@marco-ippolito
Copy link
Contributor

Let's try with @swc/core first.
I made #9547 and triggered https://github.com/swc-project/swc/actions/runs/10810667484

I see the CI is green, might be related to WASM?

@kdy1
Copy link
Member

kdy1 commented Sep 16, 2024

I got an arm64 windows device. My mother had one 👍
I'll fix this issue after Chuseok holiday(through Wednesday)

@kdy1
Copy link
Member

kdy1 commented Sep 20, 2024

I managed to install VS and rust on it. I'll try later today.

@kdy1
Copy link
Member

kdy1 commented Sep 21, 2024

Running cargo test in swc_fast_ts_strip. If it works I'll try --release and the input specified

@kdy1
Copy link
Member

kdy1 commented Sep 21, 2024

cargo test and cargo test --release works properly for the specified input.
cc @magic-akari What should we do? I think it's a bug of wasm-bindgen

@magic-akari
Copy link
Member

cargo test and cargo test --release works properly for the specified input. cc @magic-akari What should we do? I think it's a bug of wasm-bindgen

However, the same WASM works in the browser but not in node.
You can check the glue code of swc_ast_viewer: https://www.npmjs.com/package/swc_ast_viewer?activeTab=code

@marco-ippolito
Copy link
Contributor

I've tried with newer versions and the problem persists. Just to confirm, is the bug in the javascript wasm glue or in the wasm itself?

@kdy1
Copy link
Member

kdy1 commented Oct 20, 2024

Actually, I don't remember. I'll retry and report back.

@kdy1
Copy link
Member

kdy1 commented Oct 22, 2024

My notebook is somehow broken, so I think I should try using some hosting

@kdy1
Copy link
Member

kdy1 commented Oct 23, 2024

image
Installing...

@kdy1
Copy link
Member

kdy1 commented Oct 23, 2024

I managed to run it and it worked.

image
$ node -v
v20.18.0

$ wasm-pack -V
wasm-pack 0.13.0

$ rustc -vV
rustc 1.83.0-nightly (55a22d2a6 2024-10-06)
binary: rustc
commit-hash: 55a22d2a63334e0faff0202b72a31ce832b56125
commit-date: 2024-10-06
host: aarch64-pc-windows-msvc
release: 1.83.0-nightly
LLVM version: 19.1.1

kdy1@WIN-PQAP3GH9V16 CLANGARM64 ~/Desktop/projects/swc/bindings/binding_typescript_wasm (main)
$ cargo -vV
cargo 1.83.0-nightly (ad074abe3 2024-10-04)
release: 1.83.0-nightly
commit-hash: ad074abe3a18ce8444c06f962ceecfd056acfc73
commit-date: 2024-10-04
host: aarch64-pc-windows-msvc
libgit2: 1.8.1 (sys:0.19.0 vendored)
libcurl: 8.9.0-DEV (sys:0.4.74+curl-8.9.0 vendored ssl:Schannel)
os: Windows 10.0.26100 (Windows 11 Professional) [64-bit]

Can you share the exact node.js version that failed?

@kdy1
Copy link
Member

kdy1 commented Oct 23, 2024

Also, End 2 is printed.
image

@marco-ippolito
Copy link
Contributor

marco-ippolito commented Oct 23, 2024

This is the PR that can reproduce this behavior
nodejs/node#54657
It should be reproducible on node 22.10.0
Can you use transformSync and add the same settings we use on node?
https://github.com/nodejs/amaro/blob/main/src%2Ftransform.ts#L4

@kdy1
Copy link
Member

kdy1 commented Oct 24, 2024

image image

Hmmm... It worked. It may be an OS bug, or a bug of one of the libraries between OS and our runtime. But I'll try the published version first.

@kdy1
Copy link
Member

kdy1 commented Oct 24, 2024

Well... It worked.
image

image
  1. CPU bug
  2. OS bug
  3. Bug in somewhere that is not triggered by windows 11

@wojtekmaj
Copy link
Author

Can my real machine be of any use?

@kdy1
Copy link
Member

kdy1 commented Oct 31, 2024

@wojtekmaj Steps to reproduce:

  1. Install rustup
  2. Install wasm-pack
  3. git clone https://github.com/swc-project/swc.git -b swc-win-arm64
  4. cd ./swc
  5. yarn
  6. cd ./bindings/binding_typescript_wasm
  7. ./scripts/build.sh
  8. node nodejs-patched.mjs

Can you try it?

@wojtekmaj
Copy link
Author

I'm stuck on build phase :/ Getting

= note: rust-lld: error: could not open 'msvcrt.lib': no such file or directory␍

despite installing the dependencies as documented...

@kdy1
Copy link
Member

kdy1 commented Dec 8, 2024

@marco-ippolito I created a separate repository to test it using Github Actions.
Repo: https://github.com/kdy1/swc-win-arm64

I'll monitor this to ensure that it does not fail with unrelated stuffs

@kdy1
Copy link
Member

kdy1 commented Dec 8, 2024

It seems like napi default template does not have arm64 windows.
cc @Brooooooklyn Is there a good way to test napi binding on arm64 windows?

@Brooooooklyn
Copy link
Member

@kdy1 https://github.com/kdy1/swc-win-arm64/actions/runs/12219567059/job/34086308398 The binary was built, but the GitHub Actions doesn't provide Windows on ARM runner, so I think it's hard to setup Windows on ARM test

@kwonoj kwonoj self-assigned this Dec 17, 2024
@kwonoj
Copy link
Member

kwonoj commented Dec 17, 2024

I'll try to see if I can repro this.

@marco-ippolito
Copy link
Contributor

Apparently it now works on Node nodejs/node#54645 I assume it was some weird combination of v8/windows arm64

@wojtekmaj
Copy link
Author

Unfortunately, this is not my experience. I updated @swc/wasm-typescript in my original repro from 1.7.23 to 1.10.1 and this is still very much reproducible, with SWC quietly exiting:

PS C:\test> node swc.js 
Begin 1
export function foo() {
    return 'foo';
}

End 1
Begin 2

@marco-ippolito
Copy link
Contributor

Unfortunately, this is not my experience. I updated @swc/wasm-typescript in my original repro from 1.7.23 to 1.10.1 and this is still very much reproducible, with SWC quietly exiting:

PS C:\test> node swc.js 
Begin 1
export function foo() {
    return 'foo';
}

End 1
Begin 2

Can you try with Node 23?

@marco-ippolito
Copy link
Contributor

marco-ippolito commented Dec 24, 2024

On Node main and v23.5.0 (Windows 11 arm64 VM I got on azure):
(stripTypeScriptTypes) is basically a wrapper around transformSync

// test.swc.js
import { stripTypeScriptTypes } from "node:module";

console.log("Begin 1");
console.log(
	stripTypeScriptTypes(`
export function foo() {
	return 'foo';
};
`),
);
console.log("End 1");

console.log("Begin 2");
console.log(
	stripTypeScriptTypes(`
export function foo() {
	if (false) {
	}
	return 'foo';
};
`),
);
console.log("End 2");

Output:

PS C:\Users\satanacchio\Desktop\projects\node> out\Release\node.exe test.swc.js
Begin 1

export function foo() {
        return 'foo';
};

End 1
Begin 2

export function foo() {
        if (false) {
        }
        return 'foo';
};

End 2

Output on Node 23.5.0:

PS C:\Users\satanacchio\Desktop\projects\node> .\node-23-5-0.exe test.swc.js
Begin 1

export function foo() {
        return 'foo';
};

End 1
Begin 2

export function foo() {
        if (false) {
        }
        return 'foo';
};

End 2

Also the interaction with loaders has been fixed.
I would consider this fixed on Node 23.5.0.
I think it was due to some bug in v8 or some weird interaction.

@Brooooooklyn
Copy link
Member

@marco-ippolito I suggest you verify that the output of process.arch under Node.js in your ARM64 VM is arm64. It is easy to accidentally install the x64 version on a Windows arm64 system.

@marco-ippolito
Copy link
Contributor

marco-ippolito commented Dec 24, 2024

@marco-ippolito I suggest you verify that the output of process.arch under Node.js in your ARM64 VM is arm64. It is easy to accidentally install the x64 version on a Windows arm64 system.

It is arm 100%

image

Screenshot 2024-12-24 at 09 40 19 Screenshot 2024-12-24 at 09 43 41

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

6 participants