ひとり勉強会

ひとり楽しく勉強会

2006-01-01から1年間の記事一覧

compile_branch_condition @ compile.c

「if文の条件を判定して、trueならthen側、falseならelse側にジャンプ」というマシン語を生成する処理は、関数が別にわかれています。 COMPILE_( nd_cond ) スタックから値をpopして、偽ならelse_labelにジャンプする命令のようにすれば、その場で簡単にコー…

node==nullの場合

elseのないif文も構文解析の段階でif-then-else文にまとめられる、と書きました。実はあんまりちゃんと追ってないのですが、elseがなかった場合はnd_else==0の構文木が作られているようです。 実は、switch文に入るより前にこういうコードがありました。 if …

NODE_IF

次はif-then-else文です。elseのないif文やunless文、三項演算子a?b:cも全部構文解析の段階でこのノードにまとめめられるので、コンパイラは1種類のif文だけ気にすれば済むわけです。コンパイルする処理はこうなっています。 case NODE_IF:{ DECL_ANCHOR(co…

NODE_BLOCK

お次は、NODE_BLOCK。RHG12章 の「幹」の説明を読んでみると、このノードは、文の並びをリストとしてつなぐためのノードです。細かいことは抜きにすると 7; 8; 9 という3つの文は NODE_BLOCK(nd_head: 文"7"を表すノード, nd_next: NODE_BLOCK(nd_head: 文"…

各ノードのコンパイル

この先はしばらく、switch文の各caseを順番に見ていきます。どの順番で読むと良いか特に妙案もありませんし、上からひたすら読んでいくとしましょう。飽きたら途中で考え直します。まず最初の4つのケースは、コンパイルエラーだそうです。 case NODE_METHOD…

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 …

プラス1テーマ

なにかもう一つくらいテーマを増やしたいな。どうしよ。。。前から機会があればやりたいと思ってたのが、OSI承認ライセンス を1個1個しつこいくらいに詳しく読んで整理、比較すること。実用には(L)GPLとBSDとMITとMPLを知ってればよさそうですけど、他にあ…

まとめ

というところで、今週の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…

おしゃべり

なにか間に挟まっていたほうが「最新タイトル」が見やすいかな。毎週の日曜日は[雑談]タグでおしゃべりすることにしました。 と、これを思いついたのは11/3(金)なので、書いているのも11/3(金)です。うーん。ソースコード勉強会、やってみると、なかなか思っ…

まとめ

というところで、今週の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と違って、いったんスクリプトを仮想マシンのバイトコードに変換して、高速実行するのが特徴ら…

はじまり

ここ 「ひとり勉強会」 は、名前のとおり、わたしがひとりで勉強会を開いてひとりで記録を残すブログです。いつもテーマを1,2個持っといて、毎週決まった曜日に定期的に開催していこうと思ってます。月曜日はXX勉強会で、木曜日はYY勉強会、みたいな感じ…

おことわり

勉強会を開こう!と思うくらいですから、ここで扱うテーマについては、わたしは、初心者です。書いてある内容は間違いだらけかもしれません。(そうならないように努力しますが。。。)鵜呑みになさらないよう、よろしくお願いします。また、間違いを見つけ…