ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

wasmで動くmruby(とバイナリ互換のVM)近況報告

RubyKaigi CfP 2024のクローズ期限は本日です。みなさんは準備ですか?

今日は、先日紹介した mruby/edge の近況を報告します。

udzura.hatenablog.jp

VTRをどうぞ

youtu.be

う〜ん地味!

できてること

mec というcli経由でRubyスクリプトを直接wasmファイルにして、ハローワールドする

mec (mruby edge compiler)というフロントエンドとなるコマンドを作りました。と言っても他のコマンドのラッパーなのですが。。crates.io に上げてるので以下でインストールできます。nightlyじゃないとダメなのはいつかなんとかする。

$ rustup default nightly
$ cargo install mec

mec の動作に必要な依存コマンドは、 rustc/cargo(1.77.0-nightly)、mrbc(3.2.0)、あとは git や sed ぐらいです。

特にmrbcをパスの通ったところにインストールするのは至難の業なのですが、 Debian sid のmrubyが今ちょうど 3.2.0 なので、Ubuntu/Debian系のLinuxdebを落としてきてインストールすれば比較的楽に環境が作れます*1

上記が揃ったら、適当なRubyスクリプトを用意して一つメソッドを定義します。

def world
  puts "I love any binaries"
end

これで以下のコマンドを実行したら無事wasmファイルが、同じディレクトリに作られます。

$ mec --fnname world hello.rb
...

この hello.wasm は world というメソッドをそのまま関数としてexportしており、こうやって呼べます。

$ wasmedge --reactor ./hello.wasm world
I love any binaries
Nil

余談

このwasmバイナリのサイズです。 CRuby.wasm の18MB*2に比べると 1/10 くらいでずいぶん小さいですが、そもそも全然機能がないので当たり前ですね...。

$ ls -l hello.wasm 
-rwxrwxr-x 1 ubuntu ubuntu 1812994 Jan 31 21:16 hello.wasm

フィボナッチ数を計算する

mruby/edge はmrubyのトップレベルメソッドを定義し、それを再起で呼び出せるようになりました。

def fib(n)
  if n < 3
    return 1
  else
    return fib(n-1)+fib(n-2)
  end
end

def main
  fib(15)
end
$ mec --fnname main fib.rb
$ wasmedge --reactor ./fib.wasm main
RInteger(610)

まあ fib(20) くらいではっきり遅いとわかっちゃうため、パフォーマンス改善はこれからです...。

これから頑張ること

exportする関数の型に気を遣いたい

上記のようにMVP的なものが動くんですが、普通に使う分でもまだ機能は足りません。

たとえば、fibを上記では別の関数から呼んでますが、こうしたい。つまりこの場合 (int32) -> int32 の関数をexportしたいのでした。

def fib(n)
  if n < 3
    return 1
  else
    return fib(n-1)+fib(n-2)
  end
end
$ wasmedge --reactor ./fib.wasm main 15
610

型推論までできたら凄いんですが、当座はRBS風の文法でこんなオプション用意してもいいかなって気持ちです。う〜ん...。

$ mec --fnname fib --signature "(Integer) -> Integer" fib.rb

もっと命令をサポートする

今mruby/edgeとmecでできることです。

  • 文字の表示
  • トップレベルメソッド定義
  • フィボナッチ数計算に必要な算術演算

はい、ほぼ何もできていない。今後のマイルストーンは、ブロックの扱いとかクラス定義とか例外とかそんなところですね...。mrubyとVMに親しくなりながらやっていく所存です。

ただ、メソッド定義は、ちゃんとmrubyの中のIrepを行ったり来たりしながら実行してくれるように作れました。他の機能もmrubyやmruby/cと言ったファミリーの皆さんの実装を眺めながら随時移植できるかなと思います。きっと。

実は OP_ADDI とかすごく基本的な算術命令すらサボってるんですが、多くのものはやるだけだとは思うので、やっていきます。

やんちゃハウスで集中して実装しようかな...

mruby-asmとかmruby-objdumpが欲しい

普通にないとデバッグに不便なので頑張るぞと。

最後に

所有権は友達、怖くないよ!

ジットハブはここです:

github.com

では、福岡に住んでる人はeBPFイベントで、そうでない人は多分沖縄でお会いしましょう。

*1:パッケージで 3.0.0 が落ちてくる環境もありますが、今の所 3.0 対応してませんすいません...

*2:ruby.wasmでやれることを考えると、とんでもなく小さいと思ってます!