前提条件
- Windows 11
- .NET 9 がインストール済み
- PowerShellから作業
手順
プロジェクトを作成
dotnet new console -n wasmintro
cd wasmintro
dotnet add package Wasmtime
wasmtime向けruby.wasmバイナリを用意する
# 1. ダウンロード Invoke-WebRequest ` -Uri https://github.com/ruby/ruby.wasm/releases/latest/download/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz ` -OutFile ruby-3.4-wasm32-unknown-wasip1-full.tar.gz # 2. 展開 tar -xvzf ruby-3.4-wasm32-unknown-wasip1-full.tar.gz # 3. ruby.wasm を移動(元の ruby 実行ファイルをリネーム) Move-Item ` -Path "ruby-3.4-wasm32-unknown-wasip1-full/usr/local/bin/ruby" ` -Destination "ruby.wasm"
https://github.com/ruby/ruby.wasm/?tab=readme-ov-file#quick-example-how-to-package-your-ruby-application-as-a-wasi-application に記載されているwasmtimeで動かす手順を参考にしてます。
ruby.wasmでは何種類かのwasmバイナリを作ります。
例えば rake npm:ruby-head-wasm-wasi
で作る packages/npm-packages/ruby-head-wasm-wasi/dist/ruby.wasm
を使うとうまく行きません。
このwasmバイナリにはJavaScriptでホストするための関数が定義されています。
このwasmバイナリをインスタンス化するには、これらの関数にC#側のスタブ関数を紐付ける必要があります。
紐付けないと次のようなエラーメッセージ表示されます。
Unhandled exception. Wasmtime.WasmtimeException: unknown import: `rb-js-abi-host::rb_wasm_throw_prohibit_rewind_exception` has not been defined at Wasmtime.Linker.Instantiate(Store store, Module module) at Program.<Main>$(String[] args) in C:\Users\led_l\wasmintro\Program.cs:line 18
wasmtimeで動かしやすいwasmバイナリを選ぶ必要があります。
ソースコード
using System; using Wasmtime; var engine = new Engine(); var module = Module.FromFile(engine, "ruby.wasm"); using var linker = new Linker(engine); linker.DefineWasi(); using var store = new Store(engine); store.SetWasiConfiguration( new WasiConfiguration() .WithArgs("ruby", "--version") // Rubyのバージョンを表示 .WithInheritedStandardOutput() .WithInheritedStandardError() ); var instance = linker.Instantiate(store, module); instance.GetFunction("_start")?.Invoke();
実行する
dotnet run ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [wasm32-wasi]