🦍

Vimをwasm runtime化する

2022/12/02に公開

はじめに

最近Dockerがwasm対応を発表していて、wasmがこれからますます盛り上がりそうな予感がしています。

https://www.docker.com/blog/docker-wasm-technical-preview/

一Vimmerとして、なんとかこのビッグウェーブに乗りたいため、Vimをwasm runtimeにすればいいのでは?と思ったので実際に簡単なものを実装してみました。
足し算、引き算、フィボナッチ関数、分岐を動かせる程度で実用的ではありません。

Vimをwasm runtime化する

https://github.com/skanehira/wasm_runtime.vim

上記のプラグインをインストールすれば、こんな感じで使えます。

:WasmRuntimeRun {wasm} {function} {args...}

あと、↓のフィボナッチ関数は動かせます。
ただ、再帰が深すぎてエラーが出た場合は:set maxfuncdepth=1000とかして調整する必要があります。

(module
  (func $fib (param $N i32) (result i32)
    (if
      (i32.eq (local.get $N) (i32.const 1))
      (then (return (i32.const 1)))
    )
    (if
      (i32.eq (local.get $N) (i32.const 2))
      (then (return (i32.const 1)))
    )
    (i32.add
      (call $fib (i32.sub (local.get $N) (i32.const 1)))
      (call $fib (i32.sub (local.get $N) (i32.const 2)))
    )
  )
  (export "fib" (func $fib))
)

wasm runtime自体はシンプルなスタックマシンなので、そこまで複雑ではないです。
やっていることもシンプルで、バイナリをデコードして命令を処理していくだけです(ただ命令が多いので実装が面倒)

命令を処理する部分はこんな感じで、命令を1つ取り出してプログラムカウンタを進めて命令を処理して、結果をスタックに積んで…を繰り返しています。

https://github.com/skanehira/wasm_runtime.vim/blob/02c8355304d8fade682fd9e51018992e95ac06df/autoload/wasm_runtime.vim#L100-L179

さいごに

Dockerではwasmedgeを使ってwasmを実行しているので、 Vimをwasmedgeに置き換えることができれば、実質VimはOCIランタイムといえます。
「いつからVimはエディタと勘違いしていた?」っていえる日が来るかも知れません。


https://www.publickey1.jp/blog/22/docker_desktopwebassemblywebassembly.html より

Discussion