RHGの逆襲 第7回

新橋ミラクリナックスにて。今週は RHG 12 章で構文木の構築のあたり。いつも会場を使わせていただいているミラクリナックスのよしおかさんに感謝です。

予習は parse.y の膨大なアクション部をひととおりなぞってみよう、という間違ったアプローチをしてしまったため(途中で迷子になって RHG に沿った読み方に復帰)、ローカル変数の解釈のあたりでタイムアップ。そのためか今回は解説をききながら自分でソース読みするのに追われているうちにいつのまにか2時間が過ぎていたという、ある意味非常に充実した勉強会でした。なので今回は発表内容についてのメモがあんまり残ってません。いちおう記憶からさらって箇条書き。

  • Yugui さん、さわださん、星一さんらによる発表
  • struct RNode について
    • RHG の時から flags のビット使用状況が変化していて、行数に使えるビット数が17ビットに増えている
      • なのになぜか 65535 で overflow する(さわださん)(->これは YARV のコードにコンパイルする時に unsigned short に代入されているせいみたいでした。後述)
    • nd_file は使われなくなってる(消してみてもコンパイル通ったらしい)。
      • ファイル名は YARV のコードにコンパイルする時に渡しているようになったみたい(さわださん)。
  • rb_node_newnode はマクロとして node_newnode に定義されているけど、関数としても定義されている(星一さん)
    • (rb_node_newnode)(...) みたいにして明示的に関数の方を呼んでいる……けどこれって何か意味あるんだろうか。名前変えたほうがいいんじゃない?
  • 文字列リテラルでは String#initialize は呼び出されないみたい。
  • NODE_BLOCK のリスト構造や意味解析についてのあたりはだいたい RHG の通り
  • ローカル変数とブロック変数の解析のあたりのコード読み。このあたりは少し変わってる。どっちかというと 1.8 よりすっきりしたかも。
    • struct local_vars のリンクリストがメソッド定義やクラス/モジュール定義などの透過的でないスコープを、その中の struct vtable のリンクリストがローカル変数とブロック変数のスコープのネストを表現している。
    • struct vtable が args と vars に分かれてるのはなぜなのかよくわからない。
  • node.h にて #define NODE_METHOD NODE_METHOD みたいな #define があるのは、デバッガ用に enum のシンボルが残るようにするためらしい。
    • なんだけどこの効果を確認しようと思って実験してもうまく残ってくれない。はて……

ソース行数が 65536 で overflow する件について、わたしのところでも実験してみると同じだったので帰宅してから調べてみました。確かに nd_set_line で flags にセットするところまでは 17bit 使えていました。rb_f_raise のほうから辿ってバックトレース情報を作っているところをみてみたら、元になっているのが struct iseq_insn_info_entry という構造体のなかの line_no というメンバで、これが unsigned short になっていました。

(trunk版 vm_core.h より)
struct iseq_insn_info_entry {
    unsigned short position;
    unsigned short line_no;
    unsigned short sp;
};

compile.c でここに代入する時にオーバフローしてしまっていたみたいです。構文木の Node からコンパイル途中に INSN という構造体に格納されるところまでは int なのですけど……。

次回は VM 部分の読み進め方などについてささださんに訊こうということで、会場は秋葉原になるみたいです。わたしは行ったことがない会場なので行き方がわかるかちょっと心配。