Roadite: 순수 Ruby로 구현된 WebAssembly 런타임

[EN] Running ruby.wasm on Pure Ruby Wasm Runtime / Uchio KONDO @udzura

3줄 요약

  • Roadite는 순수 Ruby로 작성된 WebAssembly 런타임으로, Ruby 환경에서 WebAssembly 바이너리를 실행할 수 있게 합니다.
  • 높은 이식성과 Ruby 표준 라이브러리에만 의존하는 순수성을 특징으로 하며, WASI를 지원하여 복잡한 애플리케이션 실행을 가능하게 합니다.
  • 성능 최적화를 통해 실행 시간을 크게 단축했으며, 향후 WebAssembly Component Model 지원을 목표로 합니다.

WebAssembly(Wasm)는 브라우저뿐만 아니라 서버, 엣지 디바이스 등 다양한 환경에서 실행되는 바이너리 명령어 형식입니다. 본 발표는 순수 Ruby로 구현된 WebAssembly 런타임 'Roadite'를 소개하며, 개발 과정, 주요 특징, 성능 최적화 및 향후 계획을 다룹니다. Roadite는 Ruby 생태계에서 Wasm의 잠재력을 최대한 활용하고 높은 이식성을 제공하는 것을 목표로 합니다.

Roadite는 순수 Ruby로 작성된 WebAssembly 런타임으로, gem install roadite를 통해 손쉽게 설치 및 사용 가능합니다. Ruby 표준 라이브러리에만 의존하며 외부 C 의존성이 없어 높은 순수성과 이식성을 자랑합니다. 현재 Wasm 코어 사양 및 WASI Common Preview 1을 지원하여 파일 시스템 접근 등 외부 상호작용을 가능케 합니다.

Roadite 개발의 주요 동기는 Ruby와 Wasm 간의 통합 확장, 높은 이식성 확보(네이티브 빌드 회피), Wasm의 강점(언어 독립성, 임베딩, 폴리글랏) 활용 및 개인적인 도전이었습니다. 개발은 Rust 기반 Wasm 구현 학습서인 “Gora Book”의 개념을 Ruby로 옮기는 것에서 시작되어, Wasm 바이너리 파싱, VM 구현, Wasm Core Spec의 기본 명령어 192개 구현이 초기 단계였습니다. 그레이스케일 프로그램 디버깅 과정에서 메모리 할당 및 Rust panic 처리 문제를 해결했고, wasm-spec-test를 통해 숫자 명령어의 정확성을 검증했습니다.

Ruby 자체를 Wasm 위에서 실행하기 위해 37개의 WASI 함수를 구현했으며, 파일 시스템 접근을 위한 pre-opens 메커니즘이 중요했습니다. 이를 통해 Ruby의 기본 명령어와 require 같은 파일 시스템 관련 기능이 정상 작동하게 되었습니다.

성능 최적화는 초기 70초의 Ruby 시작 시간을 단축하는 데 집중했습니다. Wasm의 동적 점프 대상 계산 방식을 캐싱하여 그레이스케일 벤치마크에서 실행 시간을 43% 단축했습니다. 또한, 과도한 객체 인스턴스 생성 문제를 해결하고자 자주 사용되는 정수 인스턴스를 메모이제이션하여 약 1초의 속도 향상을 이루었습니다. 궁극적으로는 즉시 값(immediate values) 사용이 목표입니다. 이러한 최적화를 통해 Wasm은 Ruby 7.1에서 52%, 3.4에서 57%의 실행 시간 단축 효과를 가져왔습니다.

Roadite는 순수 Ruby로 WebAssembly 런타임을 구현하여 Ruby 생태계 내에서 Wasm의 강력한 이점을 활용하는 중요한 발걸음입니다. 언어 독립성, 이식성, 폴리글랏 시스템 구축 가능성 등 Wasm의 핵심 강점을 Ruby에 가져옵니다. 비록 아직 모험적인 측면이 있지만, 지속적인 개발과 커뮤니티 기여를 통해 더욱 발전할 것입니다. 특히 향후 WebAssembly Component Model 지원을 통해 언어 간 상호 운용성을 강화할 계획입니다.