blog.sorah.jp

Kernel VM

(本記事は カーネル/VM Advent Calendar 2011 に参加している記事です.この記事は 5 日目の記事で,前日は @naota344 でした.)

カーネル/VM 探検隊には参加したことがない sora_h です.こんにちは!

さて,カーネル/VM advent calendar はテーマなんでもいいということですが,やはり前日を見るとカーネル関連じゃないと行けない気がしなくも無いですね……………!!!!

カーネルとVMといえばまあRuby の KernelRubyVMが思い浮かぶわけです.

ネタがないのでこの二つを解説しましょう.ごめんなさい!!!!

Kernel

Kernel とはすべてのクラスから参照できるメソッドが定義されているモジュールであり, Object はこいつを include している.

有名な例では puts とかopen() とかそういうのが Kernel にあります.

しかしこれを解説するのはあまり面白みが無いので RubyVM を解説しようと思います.

RubyVM

今回はそれのサブクラスである RubyVM::InstructionSequence を取り上げます.

これは Ruby 1.9 系列から搭載された VM, YARV (Yet Another Ruby Vm) の insq (instruction sequence, バイトコード(?)) に Ruby レベルからコンパイルしたりなどができるようになって います.

RubyVM::InstructionSequence.compile("puts 'a'")

等することでコンパイルする事が可能です.

コンパイルの結果は,それでかえってきた InstructionSequence のオブジェクトに対して disasm したものを puts などすると良いのではないでしょうか.

require 'pp'
puts RubyVM::InstructionSequence.compile("puts 'a'").disasm

またこの結果は ruby --dump=insns -e 'script' とか ruby --dump=insns foo.rb とかでも 確認することができます.

そして

RubyVM::InstructionSequence.compile("puts 'a'").eval

で実行することも出来ます.

で,これで生成されるバイトコードを見たからなんだ,という話なんですが, たとえば命令をいじってみたりとかして遊ぶことができますね.

YARV の命令群の実態は insns.def ファイルにあって,コンパイル時にそれを一つの C ファイルに変換しています.

なので,insns.def ファイルを編集してビルドすることで命令の動作が変わったりします.楽しいですね.

YARV の instructions を調べたりするには yhara さんが作った YARV Instructions, また YARV 自体の解説にはまだ執筆途中で中途半端なものの開発者である ささださん が書いている YARV Maniacs を読むと良いかもしれません.

参考資料

まとめ

ちゃんとネタは作っておこう

Backfilled at , Published at