やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

組込ライブラリ(RubyVM::InstructionSequence)

 コンパイル済みの命令シーケンス。

成果物

情報源

RubyVM::InstructionSequence

Ruby の Virtual Machine のコンパイル済みの命令シーケンスを表すクラスです。

Method、Proc オブジェクトや Rubyソースコードを表す文字列から VM の命令シーケンスを得る事ができます。また、 RubyVM::InstructionSequence オブジェクトを元に命令シーケンスを読みやすい文字列に変換する事もできます。Ruby の命令シーケンスコンパイラの設定を扱う必要がありますが、RubyVM がどのように働くかを知るのに有用です。

VM の命令シーケンスの一覧はRubyソースコード中の insns.def から参照できます。

https://github.com/ruby/ruby/blob/master/insns.def

メンバ抜粋

特異メソッド

compile compile_file compile_option compile_option= disasm disassemble load_from_binary load_from_binary_extra_data new of

インスタンスメソッド

absolute_path base_label disasm disassemble eval first_lineno inspect label path to_a to_binary

new, compile

new(source, file = nil, path = nil, line = 1, options = nil) -> RubyVM::InstructionSequence
compile(source, file = nil, path = nil, line = 1, options = nil) -> RubyVM::InstructionSequence
RubyVM::InstructionSequence.compile("a = 1 + 2")
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>

disasm, disassemble

 人間が読める文字列に変換する。

p = proc { num = 1 + 2 }
puts RubyVM::InstructionSequence.disasm(p)
== disasm: <RubyVM::InstructionSequence:block in <main>@/tmp/proc.rb>===
== catch table
| catch type: redo   st: 0000 ed: 0012 sp: 0000 cont: 0000
| catch type: next   st: 0000 ed: 0012 sp: 0000 cont: 0012
|------------------------------------------------------------------------
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] num
0000 trace            1                                               (   1)
0002 putobject        1
0004 putobject        2
0006 opt_plus         <ic:1>
0008 dup
0009 setlocal         num, 0
0012 leave

所感

 メタい。使わないだろう。

対象環境

$ uname -a
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux