ruby.wasmをブラウザで動かすためには次のJavaScriptを使ってruby.wasm
を初期化します。
<script src="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@2.1.0/dist/browser.script.iife.js"></script>
上記のJavaScriptのソースコードは
https://github.com/ruby/ruby.wasm/blob/main/packages/npm-packages/ruby-wasm-wasi/src/browser.script.ts です。
初期化シーケンス
browser.script.ts
で行っている初期化処理をシーケンス図にします。
DefaultRubyVM
はRubyVM
を初期化します。
上記のシーケンス図では複雑な処理を行っていますが、ひとたび初期化が完了すればRubyVM
オブジェクトがあれば十分です。
RubyVM
とWebAssemblyの相互呼び出しはWASI仕様に則っています。
インスタンス化したりお互いの呼び出し関数を登録し合ったりと面倒な手続きがあります。その手続きをDefaultRubyVM
が行っています。
上記シーケンス図の青色の部分です。
初期化完了後
初期化完了後browser.script.ts
はRubyVM
オブジェクトのeval
メソッドを呼び出してRubyスクリプトを実行します。RubyVM
は「WebAssembly化されたCRuby」とJavaScriptの世界を繋ぐためのラッパーとなるJavaScriptのクラスです。
JavaScriptの世界から「WebAssembly化されたCRuby」を呼び出すときはRubyVM
のメソッドを呼び出します。
たとえば、JavaScriptからRubyVM
のeval
メソッドを呼び出すと、任意の文字列をRubyスクリプトとして実行出来ます。
vm.eval('p "Hello, World!"');
反対に「WebAssembly化されたCRuby」からJavaScriptの世界の何かを呼び出すときはRubyVM
のメソッドを呼び出します。
たとえば、「WebAssembly化されたCRuby」からの標準出力への書き込むと、RubyVM
でフックしてconsole.log
の呼び出しに置き換えます。
その結果、上記のJavaScriptの実行結果はコンソールへのHello, World!
の出力になります。
シーケンス図にすると次のようになります。
ここで「WebAssembly化されたCRuby」と呼んでいるのは、CRubyをコンパイルしたWebAssemblyバイナリを、ブラウザ上で実行したWebAssemblyインスタンスのことです。