GN⁺: Jaws – JavaScript를 WASM으로 사전 컴파일하는 컴파일러
(github.com/drogus)- JavaScript를 WebAssembly로 컴파일하는 도구로, 독립 실행형 WASM 바이너리를 생성하는 점에서 porffor와 유사함. Rust로 작성됨
- 실험적인 도구로, 아직 프로덕션에 사용하기에는 준비가 되지 않았으며, 많은 언어 기능과 내장 타입이 부족하거나 불완전함
- 목표는 언어의 100% 지원을 달성하는 것임.
##왜 Jawsm인가?
- Jawsm 프로젝트는 WebAssembly 시나리오를 실행하는 스트레스 테스트 도구인 Crowst 작업 중에 시작됨.
- Rust에서 WASM으로 컴파일된 코드만 지원하나, Rust는 널리 사용되는 언어가 아님.
- 스크립팅 언어를 WASM 위에서 실행하는 것은 현재 이상적이지 않음. 인터프리터를 포함해야 하거나, 타겟 언어의 변형을 사용해야 함.
- 현대 WASM 제안을 통해 컴파일된 인터프리터 없이 JavaScript 기능의 100% 구현이 가능하다고 믿음.
작동하는 것
- 언어의 100% 구현을 목표로 하며, 의미론 구현에 집중하고 있음.
- 구현이 어려운 4가지 항목: 스코프/클로저, try/catch, async/await, 제너레이터.
- 현재 Jawsm은 클로저를 사용한 코드 컴파일, try/catch, 제한된
Promise
API 및async
를 구현함. - 작동하는 기능: 변수 선언 및 할당,
while
, 문자열 리터럴, 숫자 및 기본 연산자, 불리언 및 기본 불리언 연산자, 배열 리터럴, 객체 리터럴,new
키워드.
호스트 요구 사항
- Jawsm은 최근 WASM 제안으로 구축되어, 생성된 바이너리는 런타임 간에 이식성이 떨어짐.
- WASIp2를 염두에 두고 구현 중이며, V8을 사용하여 WASIp2 기능을 위한 JavaScript 폴리필을 사용함.
- Jawsm이 생성한 바이너리를 실행할 수 있는 스크립트
run.js
가 있음.
사용 방법
- 기여하지 않는 한 사용하지 않는 것이 좋음.
- 저장소를 클론한 후
execute.sh
스크립트를 사용하여 WAT 파일을 생성하고 바이너리로 컴파일한 후 Node.js로 실행 가능. - Rust의
cargo
, 최신 버전의wasm-tools
, Node.js v23.0.0 이상이 필요함.
다음 단계
- 구현이 어려운 기능을 먼저 완료할 계획이며, 다음은 제너레이터와
await
키워드 지원임. - 스택 전환 제안을 사용하고 싶지만, 현재는 CPS 변환을 사용하여 지속성을 시뮬레이션 중임.
- 이후 문법 및 내장 타입과 API를 구현할 예정임.
작동 원리
- 프로젝트는 JavaScript 구문을 WASM 명령어로 변환하며, WASM GC, 예외 처리 및 꼬리 호출 최적화 제안을 활용함.
- JavaScript의 스코프와 클로저를 WASM에서 시뮬레이션하기 위해 추가 WASM 코드를 작성함.
Hacker News 의견
-
새로운 WASM GC 제안의 영리한 사용법임. 기존의 JS -> WASM 컴파일러들은 전체 JS 엔진을 포함했지만, 이 프로젝트는 JS 구조를 WASM 기본 요소로 직접 매핑하려고 시도함.
- 과거에 거의 Typescript에 가까운 ARM 임베디드 컴파일러를 만들었음. 몇 가지 기술이 유용할 수 있음.
-
Rust를 작성하는 것을 좋아하지만, 널리 사용되는 언어는 아님. Rust는 요즘 매우 주목받고 있으며, 여러 곳에서 사용되는 것처럼 보임.
-
JavaScript 사양의 100%를 커버할 수 있을 것이라고 확신함. 아이디어, 질문 또는 비판을 환영함.
- test262_runner.rb의 결과가 있는지 궁금함. README에 이 진행 상황을 보여주면 좋겠음. 훌륭한 프로젝트임.
-
프로젝트의 README.md를 읽었지만, 예상되는 사용법이 무엇인지 확신할 수 없음. 생성된 WASM 코드가 런타임과 어떻게 상호작용하는지 궁금함. 브라우저 및 기타 WASM 런타임과 호환되는 도구로 의도된 것인지, 아니면 프로젝트에 연결된 런타임과만 호환되는 것인지 궁금함.
- JavaScript 코드 내의 웹 API나 특정 환경에서만 정의된 글로벌 식별자를 만나면 어떻게 반응하는지 궁금함. 해당 환경을 위한 것이 아니라면, 이를 사용할 때 I/O를 어떻게 해야 하는지 궁금함.
-
"브라우저 런타임 없이 JS 실행"이 다가오고 있음. perforr, jaws 또는 다른 프로젝트가 결국 성공할 것임.
-
문자열 인코딩 불일치 및 관련 유틸리티는 어떻게 처리되는지 궁금함. WASM은 UTF-8을 지원하고 JS는 (잠재적으로 잘못된) UTF-16을 지원함.
-
이 접근 방식을 매우 좋아함. 직접적으로 바이너리를 생성하려고 하기보다는 WASM을 위해 직접 빌드하는 것이 WASM GC와 WASI 0.3의 일부로 예상되는 비동기 지원에 의존할 수 있음을 의미함.
-
일부 사람들은 이를 컴파일러라고 부름. 훌륭한 작업임.
-
이 코드가 JS에서 동일한 코드를 실행하는 것보다 더 빠르게 실행되는지, 아니면 다른 언어와의 상호 운용성을 위한 것인지 궁금함.