マイペースなRailsおじさん

Ruby、Ruby on Rails、オブジェクト指向設計を主なテーマとして扱います。だんだん大きくなっていくRuby on Rails製プロダクトのメンテナンス性を損なわない方法を考えたり考えなかったりしている人のブログです。

RubyKaigi 2022 Ruby meets WebAssembly

Ruby meets WebAssembly - RubyKaigi 2022

RubyKaigi 2022 1日目のキーノートが、内容もプレゼンも大変良かったので、少し詳しくレポートします。RubyをWebAssembly (WASM) の対応についてお話頂きました。WebAssemblyの基礎から、WebAssembly対応のテクニカルな難しさまで、非常にわかりやすく丁寧に説明されており、聴きごたえのある素晴らしい発表でした。 特にデモがおもしろく、思わずスゴイ!とうなりたくなるものばかりでした。

主な発表内容は、下記の3つでした。

  • RubyをWASM対応させるメリット
  • WASM対応の仕組み
  • RubyのWASM対応にあたって特に工夫した点

RubyをWASM対応させるメリット

WASMは、主にWebブラウザで利用することを目的として作られた言語です。直接記述するのではなく、他の言語をWASMにコンパイルして使うことを想定して設計されています。

Rubyを動かすためにはまず環境構築が必要ですが、OSや実行環境によってトラブルシュートが必要になることもあります。

RubyがWASMで動くようになれば、WebブラウザさえあればRubyを実行できます。環境構築のハードルぐんと下げてRubyの間口を広げるとともに、より多くの用途でRubyを使えるようになります。

例えば、WASMはWebブラウザだけでなく、エッジコンピューティングなどで利用することもできるようになっきています。RubyをWASM対応させておけば、WASMさえ動く環境であればRuby用の個別の対応をいれずとも自動的にRubyを使えるプラットフォームが増えていきます。乗るしかねえ、このビッグウェーブに、というやつです。

WASM対応の仕組み

RubyをWASMで動かす際は、主に2つのリソースを使います。

ブラウザでWASMで書かれたRubyインタプリタを動かして、そこにRubyソースコードを入力として与えます。

ここで注意したいのが、WASMさえあればRubyが行う全ての操作を実現できてしまうわけではない点です。WASMでは、システムのリソース(時計、ストレージなど)を操作する方法は定義されていません。

Webブラウザで動かす場合は、システムのリソースはJavaScript(JS)を使えば解決します。しかしながら、WASMはいろいろな環境で動かすことを想定するようになってきたので、JSに依存しない仕組みを作ろうということに成りました。そこで開発されたのがWASIです。WASIは、WASMからシステムのリソースへのインターフェースを定義する規定です。このおかげで、WASMとWASIを実装している環境であれば、WASMからシステムのリソースを操作できることになります。

RubyのWASM対応でも、WASIを利用してシステムのリソースを操作します。

RubyのWASM対応にあたって特に工夫した点

Rubyインタプリタは、C言語で書かれていてます。C言語をWASMに変換できるコンパイラは既に存在しています。しかしながらRubyでは、単純には変換できない実装が3つありました。発表者の方は、「3つのドラゴン」と表現していました。

3つのドラゴン

setjmp/longjmpとFiberは、CRuby上でアセンブリを使って実装された特殊な実行フローの制御を行っている点が難しい点だったようでうす。CRubyでは、C言語を普通に書いていては実現できないような制御を、CPUアーキテクチャごとにアセンブリを書いて実装していました。WASMには対応する命令がないので、もとの実装に対応するWASMのコードを実装できない、という難しさがあります。

GCのためのレジスタスキャンは、通常WASMでは扱うことができない領域に対する領域にアクセスしなくてはならない点に難しさがありました。

これらの課題を一挙に解決したのが、Asyncifyという技術です。この技術を使うと、WASM上で通常行えない特殊なフロー制御が行えるようになります。Asincifyをうまく使うことで、3つの課題を解決できたとのことです。

他にも、RubyソースコードRubyインタプリタを同梱できるようにするために、wasi-vfsを開発したそうです。WASIで仮想のファイルシステムを操作できるようにすることで、Rubyソースコードの同梱を実現したそうです。

まとめ

  • RubyをWASM対応させることでRubyの間口を広げた
  • CRubyのアセンブリ実装などに起因する難しい問題があったが、Asincifyをうまく活用することで解決した

より詳しくは、下記の記事で詳しく解説されています。

An Update on WebAssembly/WASI Support in Ruby | by kateinoigakukun | ITNEXT