WebAssembly의 잠재력
WebAssembly는 프로그램 배포 형식으로서 혁신적인 변화를 가져왔습니다. 웹을 위해 설계되었지만, Wasmtime, Wasm Micro Runtime과 같은 다양한 런타임 구현을 통해 웹 외부에서도 활용됩니다. 특히, 리소스가 제한적인 환경(예: IoT, 임베디드 시스템)에서 Wasm의 경량성과 이식성은 큰 이점을 제공합니다. Wasm은 호스트 시스템에 대한 안전한 접근을 허용하며, SaaS 플랫폼이나 플러그인 시스템과 같이 사용자로부터 신뢰할 수 없는 프로그램을 입력받아 안전하게 실행해야 하는 시스템에 유용합니다. 이는 Wasm이 JSON이 데이터 교환의 표준이 된 것처럼 프로그램 공유의 사실상 표준이 될 잠재력을 가지고 있음을 시사합니다.
RubyWasm 프로젝트 소개
RubyWasm은 Ruby를 WebAssembly를 통해 ‘어디서든’ 실행 가능하게 하는 프로젝트입니다. 여기서 ‘어디서든’은 웹 브라우저뿐만 아니라 비 브라우저 환경까지 포함합니다. 이 프로젝트는 세 가지 주요 구성 요소로 이루어집니다:
1. C 인터프리터의 WebAssembly 컴파일: CRuby를 Wasm으로 컴파일하는 과정은 예외 처리, 파이버(fiber), GC(Garbage Collection) 등의 기능 때문에 쉽지 않았습니다. 현재는 as-f-instrumentations
와 같은 후처리 링킹 최적화 기법을 활용하여 이식성을 확보했으나, 성능과 코드 크기 측면에서 개선이 필요하며, 최신 Wasm 기능을 활용하여 이를 개선할 계획입니다.
2. Ruby 파일 및 Gem 패키징 시스템: Wasm 환경에서는 모든 것을 단일 바이너리로 패키징해야 합니다. RubyWasm은 가상 파일 시스템(VFS)을 구현하여 rbwm
명령어를 통해 Gemfile에 명시된 Ruby Gem들을 Wasm 바이너리로 패키징할 수 있도록 합니다.
3. JavaScript 인터프리테이션 라이브러리: JavaScript 함수 호출 및 Promise 처리를 Ruby 코드 내에서 동기적으로 작성할 수 있도록 지원합니다.
RubyWasm 활용 사례
RubyWasm은 다양한 고급 기능을 시연합니다:
* 브라우저 내 IRB 실행: 웹사이트에서 IRB(Interactive Ruby)를 직접 실행할 수 있으며, xterm.js
와의 통합을 통해 자동 완성 및 이스터 에그와 같은 완전한 기능을 갖춘 터미널 에뮬레이션을 제공합니다.
* 브라우저 내 Mastodon 실행: Ruby on Rails 기반의 대규모 오픈소스 애플리케이션인 Mastodon을 브라우저 내에서 구동하는 시연은 RubyWasm의 C 확장 라이브러리 및 Active Record 지원의 견고함을 보여줍니다. Mastodon 앱은 서비스 워커(Service Worker)에서 실행되며, 웹 페이지의 네트워크 요청을 가로채 Rack 인터페이스를 통해 응답합니다. 놀랍게도 PostgreSQL 데이터베이스 또한 브라우저 내에서 실행되어 Active Record와 통신합니다.
* 커뮤니티 제공 사례: Ruby Gem을 웹사이트에서 설치 없이 테스트할 수 있는 Playground와 같은 커뮤니티 프로젝트들이 RubyWasm의 잠재력을 보여줍니다.
기술적 세부 사항: C 확장 동적 링킹
C 확장 라이브러리를 Wasm으로 크로스 컴파일하는 것은 중요한 과제입니다. Ruby 생태계의 핵심인 mkmf
는 C 확장 빌드 시스템의 중심이며, RubyGems는 이를 사용하여 C 확장이 포함된 Gem을 빌드합니다. 발표자는 mkmf
와 RubyGems 자체에 네이티브 크로스 컴파일 지원을 추가하여 Ruby 3.4부터는 크로스 컴파일이 더 용이해질 것이라고 설명했습니다.
컴파일된 라이브러리를 CRuby 인터프리터에 링킹하는 방법에는 정적 링킹과 동적 링킹이 있습니다. 기존에는 내장 확장(예: Json)에 정적 링킹을 사용했지만, Ruby Gem 시스템을 지원하기 위해 동적 링킹을 채택했습니다. 전통적인 동적 링킹 API가 Wasm에 표준으로 존재하지 않아 문제가 있었으나, 최근 WebAssembly 커뮤니티에서 개발 중인 컴포넌트 모델(Component Model)이 해결책을 제시했습니다. 컴포넌트 모델의 핵심 기능인 모듈 링킹(Module Linking)은 여러 Wasm 모듈을 단일 바이너리에 임베드하고, 모듈 간의 링킹 방식을 정의할 수 있게 합니다. 이를 기반으로 ‘선행 동적 링킹(Ahead-of-Time Dynamic Linking)’ 메커니즘을 구축하여, 빌드 시점에 링킹을 완료하고 최종 바이너리는 완전히 자체 포함되도록 합니다. 이는 런타임에 파일 기반 라이브러리 검색 없이 DL open
과 같은 기능을 제한적으로 사용할 수 있게 합니다.