LoginSignup
5
2

More than 5 years have passed since last update.

mruby-meta-circularの紹介

Last updated at Posted at 2013-11-30

mruby Advent Calendar 2013はqiitaで書くとよさそうなので、テストを兼ねて投稿します。

mruby Advent Calendar 2013はJITの話をする予定ですが、その時使うmruby-meta-circular の話を書きます。mruby-meta-circularはmrubyからRite VMの各種情報を得たり、書き換えたりするといった、ありがちな操作を行うためのmrubyのgemです。

簡単に使い方を見てみましょう
Irep::get_irep(オブジェクト、 メソッド名)でそのオブジェクトのメソッドのIrepをオブジェクト化したもの(Irepオブジェクト)を取り出すことができます。とりだした結果は、pool, syms, iseqといったメソッドで同名のIrep構造体のメンバーを取り出すことができます。

a = Irep::get_irep([], :each)
これで、Array#[]メソッドのIrepオブジェクトがaに入ります。
p a → #<Irep:0x20013d48>
p a.pool → []  # [1]とあったけど、これはmrubyのJITのメソッドインラインキャッシュがあったため。今はないので[]が返る
p a.syms → [:length, :-, :[], :+, :==, :>=, :call, :<, :<=]

a.iseq.each do |n|
  p Irep::OPTABLE[n & 0x7f]
end

→ 
"ENTER"
"LOADI"
"LOADSELF"
"SEND"
"NOP"
"SUBI"
"NOP"
"MOVE"
"MOVE"
"JMP"
"LOADSELF"
"MOVE"
"ADDI"
"NOP"
"MOVE"
"SEND"
"NOP"
"MOVE"
"MOVE"
"JMPNOT"
"JMP"
"MOVE"
"LOADNIL"
"EQ"
"NOP"
"JMPNOT"
"MOVE"
"LOADSELF"
"SEND"
"NOP"
"GE"
"NOP"
"JMPNOT"
"JMP"
"MOVE"
"MOVE"
"SEND"
"NOP"
"MOVE"
"MOVE"
"LT"
"NOP"
"JMPNOT"
"MOVE"
"LOADSELF"
省略

なお、Irep::OPTABLEは命令コード(整数)をインデックスにアクセスすると命令の名前のシンボルが返ってくる配列です。Irep::OPTABLE_CODEはシンボルからコードに変換することができます。これで、アセンブラ・逆アセンブラがmrubyで実装できますね。なお、mruby-meta-circularにはまだ、アセンブラ・逆アセンブラはないです。まあ、それだけ面倒な作業になりそうということです。

これで、Irepを得るところまで説明しました。実は、Irepを新しく作ることもできるのですが13日までに仕事が入ってこなければその辺も書きたいと思います。

5
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2