借り初めのひみつきち

仮ブログです。

Wasm on Wasm

ついに、 WebAssembly の自作エミュレータの上で動く自作 OS の上で自作 WebAssembly ランタイムが動くようになりました 🎉

つまり Wasm on Wasm ですね٩( 'ω' )و

以下に試験的に体験版設置してるので起動してみることができます。

meg-os.org

f:id:neriring16:20210329214942p:plain

もちろん PC98 や FM TOWNS でもなんとなく動きます。

f:id:neriring16:20210329214729p:plain

f:id:neriring16:20210329223029p:plain

基本的には MYOS で実装したものを若干調整して TOE に移植しただけです。最初に移植したときは動くアプリと動かないアプリがあって、調査しようとしたら wasm ランタイムを外部ライブラリに分離して no_std の関係で今まで使えた println! が使えなくなって原因の特定に若干手間取りました。 最終的には、内部で使ってる独自スタッククラスが原因でした。

独自スタックが必要な理由は、 wasm では関数1つ呼び出すたびに複数のスタックが必要になるので個別に確保するのは効率が悪いです。 特に value stack と block stack は事前検証で必要なサイズがわかっています。 *1 そこで、いったん大きめに確保した後で独自クラスの slice として分配してスタックを作っていましたが、環境によってサイズの違う型の計算が間違っていてスタックが重複して破壊されていたようです。 この部分は unsafe な操作を含むので Rust コンパイラくんでも検出できなかったようです

ともあれ、無事に動くようになったのでそろそろ TOE も最初のマイルストーンに到達しそうです。

Wasm on Wasm って一度やってみたかったネタなので、このためだけに3ヶ月くらいがんばりましたヽ(•̀ω•́ )ゝ✧

*1:wasm では分岐命令がネストしたブロックに対して相対的に行われるので、ブロックの構造を事前検証しないと分岐先や value stack の調整ができません