vm-m32について
(0)
- osecpu115dより、vm-m32というVMが提供されました。これに関する解説です。
(1)
- もしVMが内部で何をやっているのか知りたい、OSECPU-VMのソースを読みたいと思ったら、vm-m32のソースを読むのがお勧めです。また、自分もOSECPU-VMのVMを作りたいと思ったら、まずは以下のb32形式に準拠するのがお勧めです。
- b32形式というのは、通常のOSECPU-VMのバックエンドコード仕様のサブセットで、以下のような制約があります。
- page0091のフォーマットでバイナリを記述する。
- typで使えるのは、T_SINT32、T_VPTR、T_FLT32のみ。
- bitは32以下。
- この制約を一つでも満たさない場合は、b32形式のヘッダを付けることを認めません。もしこれに違反すれば、それはセキュリティ例外です。
- この制約はかなりきついと思われるかもしれませんが、実はそんなことはありません。任意のプログラムは効率を犠牲にしてよければb32に自動変換できます(ただし32ビットを超える整数演算や、T_FLT64などを使っていない場合に限る)。
- prompt>osecpu -b app.ose app.beb
- prompt>osectols tool:b32 in:app.beb out:app.b32
- これでapp.oseはb32形式に変換できます。
- ちなみにb32形式もbeb(バックエンドバイナリ)形式もどちらもOSECPU-VMのルールに従っているので、そのままosecpuで実行することができます。
- そしてb32形式のみに限って実行できるVMが、vm-m32なのです。
- さらにvm-m32はセキュリティチェックやデバッグ機能などがすべて省略されています。
- その分だけソースは簡潔になり、ソースを読むには最適だと思います。
- もし必要なら、これで読みなれてから、通常版のソースを読むといいと思います(vm-m32 → vm-mini → vm)。
- でもそもそも読む必要はないかも。
- というのは、将来的には、上記の変換処理を全部OSECPU-VMアプリとして書いてしまおうと思っているので、そしたらその変換アプリをb32に変換することで、vm-m32で変換処理ができるようになるので、VMエンジン自身がそれらの機能を直接もつ必要がなくなるわけです。
(2)
- vm-m32のソースの読み方のヒントです。
- 事実上のmain関数は、api.cのOsecpuMain()です。
- 実行は以下のような流れになっています。
- 初期化
- アプリケーションファイルをa32buf[]に読み込む
- a32buf[]をjitcAll()して、内部形式j32buf[]に変換する
- j32buf[]をexecAll()する、これで実際にインタプリタ実行になる
- jitcAll()は1命令ずつjitcStep()を呼び出します。execAll()も1命令ずつexecStep()を呼び出します。
- どの関数がどのソースにあるのかは、osecpu-vm.hをみればすぐに分かります。
- jitcStepはjitcStepInteger()やjitcStepPointer()などを全部呼び出します。それぞれの関数は「自分が担当する命令だったら」対応します。
(3)
- OSECPU-VM(rev2)は多様なフォーマットを許していて、それらをうまく使えば、このようにデコードが簡易になるようにもできるし、逆に効率重視で詰め込むこともできます。このような柔軟性を持つバイトコード体系はかなり珍しいのではないかと思います。
こめんと欄