mruby/edge ってブラウザで動くんですか? - ローファイ日記

ローファイ日記

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

mruby/edge ってブラウザで動くんですか?

A: 動きます。

mruby/edge 0.1.4/mec 0.2.3 では、 --no-wasi というオプションをサポートしたので、とりあえずwasiに関わらないコードであれば(fibとか、フィボナッチ数の計算とか)ブラウザでも動かしやすくなりました。

いつものfib置いときます。

def fib(n) # fib.rb
  if n < 2
    return 1
  else
    return fib(n-1)+fib(n-2)
  end
end
# fib.export.rbs
def fib: (Integer) -> Integer

これをコンパイルしますよと。

$ cargo install --version 0.2.3 mec
$ mec --no-wasi fib.rb
$ file fib.wasm
fib.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

$ wasm-objdump -x -j Export ./fib.wasm           

fib.wasm:       file format wasm 0x1
module name: <mywasm.wasm>

Section Details:

Export[5]:
 - memory[0] -> "memory"
 - func[11] <fib> -> "fib"
 - global[1] -> "__data_end"
 - global[2] -> "__heap_base"

fibが無事エクスポートされてます。

ブラウザではこういう感じで動かすらしい。JavaScript、慣れてないのですが...。

<script type="text/javascript">
  window.fire = function(e) {
    WebAssembly.instantiateStreaming(fetch("./fib.wasm"), {})
      .then(function (o) {
        let value = document.getElementById("myValue").value;
        let answer = o.instance.exports.fib(parseInt(value));
        document.getElementById("myAnswer").style.backgroundColor = "#ffff00";
        document.getElementById("myAnswer").value = answer;
      }
    );    
  };
  console.log("done load function");
</script>

ハンズオンWebAssemblyありがとう!

ところで、wasmを盆栽でやってる嬉しさとして、marpで作ったスライドに自分のwasmバイナリを埋め込めることがあるな、って思ったんですが。

上のコードは、

で動いてます。

fib(30) あたりからブラウザがめっちゃ固まるんですが、なんかWorker?的なやつでなんとかなるらしいので今度勉強します。

ということで、mruby/edge は現段階で、ブラウザでも動きます。

現状フィボナッチ数の計算に特化したVMみたいになってるんで、引き続きVMの中身を頑張る...。


rubykaigi.org

現地参加の方、ぜひ部屋に来て応援に来てください...!!!(後でまた宣伝エントリとか、誰向けの発表かとか書くと思いますが)