25日間で理解するRubyVMインストラクション - @ledsun blog の1日目が公開されました。
RubyVMはスタックベース仮想マシンです。 スタックに入る値はRubyのオブジェクトがそのまま入る点が特徴的なようです。
例えばduparray
という命令では配列[1, 2, 3]
がそのままスタックに入ります。
ledsun@MSI:/m/c/U/led_l►ruby --dump=insns -e '[1, 2, 3]' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,9)> (catch: false) 0000 duparray [1, 2, 3] ( 1)[Li] 0002 leave
なるほどー。 なんとなくアセンブラみたいに変換されたものとか、ポインタとかが入るのかな?って想像していました。 いやまあ、参照と言う意味でポインタはポインタなのでしょうが、Rubyで扱っているオブジェクトと別の何かなのかなあ?って思っていました。
あと、面白かったのはputstring
のすぶりで次のようにやりました。
ledsun@MSI:/m/c/U/led_l►ruby --dump=insns -e 'abc' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,3)> (catch: false) 0000 putself ( 1)[Li] 0001 opt_send_without_block <calldata!mid:abc, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 leave
pushstring
ではなくてputself
という違うインストラクションが表示されました。
不思議です。
記事のサンプルコードをコピペで実行してみました。
ledsun@MSI:/m/c/U/led_l►ruby --dump=insns -e '"foo"' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,5)> (catch: false) 0000 putstring "foo" ( 1)[Li] 0002 leave
pushstring
がでるんですよー。
不思議ですね。
両者を見比べてみて気がつきました。 そりゃ、そうです。