ひとり勉強会

ひとり楽しく勉強会

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

NODE_OP_ASGN1

a[x] op= y のパターンは、NODE_OP_ASGN1 という名前になっています。どういうバイトコードにコンパイルされるのか、コメントがついていました。 /* * eval a # a * eval x # a x * dupn 2 # a x a x * send :[] # a x a[x] * eval y # a x a[x] y * send op…

[YARV] 自己代入の注意点

a += 100 自己代入とは、上のように、自分と他の値の演算結果を、また自分に代入し直すような式のことをいいます。これは基本的には、 a = a + 100 と書き直したのと同じ意味です。実際、ほんとうに同じ意味になる場合はRubyの構文解析器が、YARVに渡すより…

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

こんにちは。iseq_compile_each 勉強会です。今日は、自己代入式のコンパイルのあたりから再開です。

サティ

日曜は雑談を書くぞっ!って言っても、特に書くことないですね。街を歩いてると、サティのジムノペティの1番をモチーフにした洋楽が聴こえてきました。こういう、クラシックのメロディを生かした歌って好きなんです。家に帰ってから調べたら YouTube でした。

まとめ

今回こそは10KBにはおさめようと思ったんですけど...ぅー。今日の内容は 代入いろいろ 多重代入いろいろ でした。次回は後ろに自己代入がひかえています。なんかコードが長そげです。 そこが終われば山は抜けられるかな、って雰囲気なので、あと2回でiseq_c…

NODE_MASGN / 多重代入

ここまでのいろいろな代入より、順番的にはこっちのcaseが先に出てきてました。説明の都合で逆順に読んでいます。 a, b, c = 1, 2, 3 みたいな形の代入です。コンパイル処理はほぼ全て、補助関数に丸投げされています。 case NODE_MASGN:{ compile_massign(i…

代入いろいろ

さて代入の話に入りますね。Rubyには、代入(あるいは代入っぽく見えるもの)がたくさんあります。 コード 説明 NODE a = 100 メソッドローカル変数への代入 NODE_LASGN a = 100 ブロックローカル変数への代入 NODE_DASGN,NODE_DASGN_CURR $a = 100 グローバ…

NODE_AND ほか

その前に、3つほど別の構文が間にはさまってました。and (&&), or (||), not (!) です。条件分岐のなかに出てくる場合は前にやりましたが、ここでは普通に式の途中に出てくるケースです。簡単なのでサックリと終わらせちゃいます。コードは省略です。 式1 a…

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

第6回です。今日のテーマは、代入のコンパイルです。

やーまに

るびま わー!!リンクしていただいちゃいました。紹介に恥じないよう頑張ります!Rubyでは定数畳み込みが難しい、というのはなるほどでした。

まとめ

今日は break, redo, next などループ制御構文 for やブロックつきメソッド呼び出し構文 rescue, ensure 例外処理 のコンパイル部分をよみました。これ全部一回でやるつもりはなかったんですが、読んでみると全部深く関係しててこんなことになってしまいまし…

NODE_ENSURE

ensure節のコードは、YARVでは複数箇所に複製される可能性があります。 begin の本体が正常終了する箇所 break などでensureを抜ける箇所 例外で終わる場合の例外ハンドラとして それぞれ、ensure節が終わったあとに実行するコードが違うので、ひとつにまと…

NODE_RESBODY

case NODE_RESBODY:{ NODE *resq = node; NODE *narg; LABEL *label_miss, *label_hit; while (resq) { ... resq = resq->nd_head; } break; 複数のrescue節がありうるので、一個一個順番にコンパイルしていきます。これは上にあるrescue節から順に命令列に…

NODE_RESCUE

rescueやelseがある場合は、メインの命令列は次のようにコンパイルされます。(コンパイルするコードは特別なところはないので省略) start: 本体 end: if(elseがあれば) pop; elseの中身 lcont: if(poped) pop例外ハンドラの登録はこんな感じ。 /* resgiste…

NODE_BEGIN

begin 〜 end 構文です。rescueやensureがつくと、構文解析の段階でいろいろとノードの種類が変わってきます。まとめると以下の通り。 begin AAA end # NODE_BEGIN(AAA) begin AAA ensure EEE end # NODE_ENSURE(AAA,EEE) begin AAA rescue .. BBB rescue ..…

NODE_RETRY

どんどん行きましょう。retry。NODE_ITERのところで読んだように、retryは例外処理になります。常にthrowに変換しておしまい。 case NODE_RETRY:{ if (iseq->type == ISEQ_TYPE_BLOCK || iseq->type == ISEQ_TYPE_RESCUE) { ADD_INSN(ret, nd_line(node), pu…

NODE_REDO, NODE_NEXT

ジャンプ先と飛ばす例外の種類が違うだけで、NODE_BREAKとまったくおんなじです。next!

NODE_BREAK

break文のコンパイルでやるべきことのおさらいです。 ジャンプ脱出コードを生成するか、例外脱出コードを生成するか ジャンプ脱出の場合、ensureの扱い case NODE_BREAK:{ unsigned long level = 0; if (iseq->compile_data->redo_label != 0) { /* while/un…

NODE_ITER, NODE_FOR

ついでだからブロックについてもここで読んじゃいます。NODE_FORはRubyのこの形の式 for 変数s in 式 本体 end を表す構文木ノードで、意味的には 式.each { |変数s| 本体 } と同じです。NODE_ITERは、メソッド名がeachとは限りませんが↑の形のブロックつき…

NODE_WHILE 再び

case NODE_OPT_N: case NODE_WHILE: case NODE_UNTIL:{ LABEL *prev_start_label = iseq->compile_data->start_label; LABEL *prev_end_label = iseq->compile_data->end_label; LABEL *prev_redo_label = iseq->compile_data->redo_label; VALUE prev_loopv…

要注意な点

個々の break 文などのコンパイルは、いつも通り case NODE_BREAK で行われます。でも、その前に NODE_WHILE で while をコンパイルする時点で、あらかじめ準備しておかなくてはいけないことがいくつもあります。注意点を列挙してみました。 break, next, re…

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

第5回です。前回はwhileループのコンパイルを途中まで読んだところで終わりました。普通に何事もなくループが回るケースは、前回読んだ範囲でカバーできています。今回は、ループにからむ制御構造 break, next, redo を扱うためのコンパイル処理について見…

まとめ

case〜when 式は条件が全部リテラルだとテーブルでジャンプするようになってる そこにRubyのArrayやHashオブジェクトが使われてて便利そうでした てな感じでした。うーむ。もっと読むスピードアップしようかな。。。

NODE_WHILE など

続いて、ループ構文です。 while 条件式 本体 end のような形のwhile式をコンパイルします。untilは、whileと終了条件の真偽が逆になったバージョンで、NODE_OPT_Nは、rubyコマンドを-nオプションで起動したときに自動で作られるループ構造 while gets スク…

NODE_WHEN

さきほども述べたように[式0] (head) がないcase文がここで扱われます。「headがwhen式の条件部とマッチしていたら」という判定が、「when式の条件部のどれかがtrueだったら」にすべて変わるだけで、基本的な構造はまったく同じです。むしろだいぶ簡単です。…

NODE_CASE

次は、case文です。 case [式0] when 式1 then 本体1 when 式2 then 本体2 .. else .. end という形の式で、上から順にwhen節を調べていって、式n === 式0 が成り立つところの本体が実行されます。この部分をコンパイルするコードのちょうおおまかな流れは、…

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

こんにちわ。月曜日になってしまいましたが復活です。 今日からリビジョン 581 に更新して読んでいきます。先週に引き続き、 static int iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) { ... type = nd_type(node); swit…

。。。。

風邪であたまが回らないので今日のYARV勉強会はお休み。。。(> 日曜日までに復活できたらそっちでやります。

Tamarin

Project Tamarin - Backnumbers: Steps to Phantasien の Project Tamarin の紹介を読みました。これも面白そうだなあ。あと、コード読みの流れがわかりやすくて。わたしも見習わなくては。

まとめ

今日はこのへんで終わりにします。お疲れ様でした。次回は、飽きるまで延々とノードごとのコンパイル方法を眺めていこうかなと思っています。caseによる分岐や、イテレータを使ったループ、next/redoなどのループ制御が待ちかまえていて、だんだん複雑なゾー…