@ledsun blog

無味の味は佳境に入らざればすなわち知れず

RubyVMインストラクション1日目

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がでるんですよー。 不思議ですね。

両者を見比べてみて気がつきました。 そりゃ、そうです。