ひとり勉強会

ひとり楽しく勉強会

YARV

poped 引数

なぜ突然スタックマシンの話を始めたかというと、実は、iseq_compile_each の第四引数を理解するのに必要だったからなのです。 iseq_compile_each(..., int poped) ざっと見た感じ、poped=0 で呼び出されている場合の方が多いようでした。そこで、特殊な方の…

スタックマシンとコンパイラ

YARVの仮想マシンは、YARV Maniacs 【第 2 回】 で解説されているように、「スタックマシン」という計算モデルで作られています。スタックマシンというのは、一本のスタック(末尾へのpushとpopだけができる配列)を考えて、そこへデータを入れたり出したり…

YARVソースコード勉強会 (3)

第3回です。今日はいよいよコンパイル処理の本陣に切り込みます。 コンパイルの大元締め関数はただひとつ、iseq_compile_each @ compile.c です。 static int iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) { ... type …

まとめ

というところで、今週のYARVソースコード勉強会はお開きとなります。(^^) また来週!

データ構造・命令列

最終的に生成される命令列は、YARVCore::InstructionSequenceクラスのオブジェクトという形で返されます。このクラスは、C言語レベルではyarv_iseq_structという構造体です。 struct yarv_iseq_struct { /* instruction sequence type */ VALUE type; VALUE …

データ構造・リスト

構文木は、いったんYARV命令の連結リストに変換されます。その状態で最適化をやって、最後にもう一段、命令語の配列への変換処理が入ります。たぶん、最適化で命令の削除・挿入・並べ替えをよくやるので、全部配列でやるよりもリストにした方が効率がよいと…

データ構造・構文木のノード

Rubyプログラムはいったん構文木に変換されます。YARVのコアではRubyプログラムを文字列として扱うのではなく、常にこの構文木になった状態を使います。構文木は、以下のような構造体で表現されます。 typedef struct RNode { unsigned long flags; char *nd…

データ構造

コンパイルは、「構文木」というツリー構造を「YARV命令列」というバイナリ配列に変換するステップです。これに加えて、先ほど調べたときにでてきた連結リストの構造も、変換の途中で使われてるみたいです。この辺りのデータ構造や、それを操作する関数がこ…

コンパイル処理の流れ・まとめ

とりあえず流れはこんなところでした。まとめときます。 th_compile_from_node→yarv_iseq_new→yarv_iseq_new_with_opt YARVCore::InstructionSequenceオブジェクト作成 prepare_iseq_build iseq_compile [compile step 1 (traverse each node)] COMPILE iseq…

コンパイル処理の流れ

iseq = th_compile_from_node(thread, node, file) @ yarvcore.c 解析済みの構文木(node)を受け取って、YARVのマシン語列(iseq)に変換する「コンパイル」処理の関数です。 トップレベルのスクリプトをコンパイルする場合と、evalで文字列をコンパイルする場…

YARVソースコード勉強会 (2)

第2回です。前回は、rubyコマンドの起動から、yarvの評価器の入り口: VALUE iseq = th_compile_from_node(GET_THREAD(), node, file); return yarvcore_eval_iseq(iseq); にたどりつく所までを読みました。今回は、この関数の前半側、th_compile_from_node…

まとめ

というところで、今週のYARVソースコード勉強会はお開きとなります。(^^) 来週は、compile側とeval側のどっちに進んだ方がいいんだろ?データ構造のチェックとかが先かなあ。。。 あとで読む PUSH_TAG, EXEC_TAG 等のタグジャンプの実装 th_init2 : Rubyのス…

ruby_run @ eval.c

最後に、main から ruby_run が呼ばれます。その中では何段にも関数が呼ばれますが、メインの流れは一列です。 main ruby_run ruby_exec ruby_exec_internal yarvcore_eval_parsed @ yarvcore.c yarvcoreにたどり着きました! VALUE yarvcore_eval_parsed(NO…

ruby_option @ eval.c

初期化が終わって、次にmainから呼ばれる処理はコマンドラインのオプションの解析です。 おもしろそうなところは特になかったので、スキップ。

Init_yarvcore @ yarvcore.c

この関数は、基本的には、YARVをRubyスクリプトからさわれるようにするための、Rubyライブラリを提供するものです。 mYarvCore = rb_define_module("YARVCore"); rb_define_const(mYarvCore, "VERSION", rb_str_new2(yarv_version)); ... 略 ... こんなのが…

Init_yarv @ yarvcore.c

一個目の初期化ルーチン Init_yarv はこんなんでした。 void Init_yarv(void) { /* initialize main thread */ yarv_vm_t *vm = ALLOC(yarv_vm_t); yarv_thread_t *th = ALLOC(yarv_thread_t); vm_init2(vm); theYarvVM = vm; th_init2(th); th->vm = vm; ya…

ruby_init @ eval.c

初期化関数、ruby_init のメインな部分を抜き出してみました。 void ruby_init() { ... 略 ... Init_yarv(); Init_stack((void *)&state); Init_heap(); PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { rb_call_inits(); ruby_prog_init(); ALLOW_I…

main @ main.c

今日は、mainから初期化が済んで、スクリプトの実行がいよいよ始まる!その手前までの流れを読んでいきます。まずはmain関数から行ってみましょう。ここからRuby/YARVの実行がはじまります。環境依存の#ifdefを取っ払うと、こんな感じのシンプルなmainです。…

資料

現時点での最新リリース 0.4.1 (revision 522) を読みます。なぜレポジトリの最新版を追いかけないかというと、手元の環境にbisonがなかったのでビルドが手間だったからです。ちょう手抜きです。参考にしようと思ってるサイト: YARV: Yet Another Ruby VM …

YARVソースコード勉強会 (1)

金曜日は YARV: Yet Another Ruby VM のソースコード勉強会をやります。YARVというのは、オブジェクト指向スクリプト言語 Ruby の実装のひとつです。ふつうのRubyと違って、いったんスクリプトを仮想マシンのバイトコードに変換して、高速実行するのが特徴ら…

ここ「ひとり勉強会」は、会と言いつつひとりで勉強した記録を残してます。 金曜日は YARV: Yet Another Ruby VM のソースコード読みの日です。 履歴 (1): main から yarv コアに到達するまで (2): コンパイル処理の流れとデータ構造 (3): if のコンパイル (…