タグ

関連タグで絞り込む (3)

タグの絞り込みを解除

ytlに関するnagachikaのブックマーク (6)

  • ytljitの型推論の説明(その6) - miura1729の日記

    なんだかんだで、2か月以上さぼってました。その6です。 今回はsame_typeの実装の話です。 same_typeはdstというノードがdsigというシグネチャでノードが存在するメソッドやブロックを実行している時、srcというノードのssigというシグネチャでの型と同じになると設定します。same_typeの実際のコードを見てみましょう。 def same_type(dst, src, dsig, ssig, context) if dst.is_a?(BaseNode) then src.ti_add_observer(dst, dsig, ssig, context) end ti_update(dst, src, dsig, ssig, context) end ti_add_observer ti_update の2つのメソッドが出てきました。この2つを順に説明します。 ti_a

    ytljitの型推論の説明(その6) - miura1729の日記
  • ytljitの型推論の説明(その5) - miura1729の日記

    今回は、collect_candidate_typeの説明です。candidateとは候補とかそういった意味です。つまり、そのノードの型になる候補(複数かもしれないし0かもしれない)を収集します。前回説明したとおり、この候補から型を選び出すのが、decide_type_onceです。 collect_candidate_typeは引数にcontextを1つとり*1、contextを返します。 collect_candidate_typeの中で別に何をしてもよいのですが、主に行うのは次の3つです。このうち最初の2つの操作については、すべてのノードのスーパークラスのBaseNodeクラスでメソッドが定義されているのでこれを使います。 型候補を加える(add_type) 他のノードと同じ型だよということを設定する(same_type) 他のノードに対して、 collect_candidate_t

    ytljitの型推論の説明(その5) - miura1729の日記
  • ytljitの型推論の説明(その4) - miura1729の日記

    ytljitでao benchが動いたらruby-listにアナウンスするんだ!と決めているのですが、なかなか動かなくて苦労しています。 さて、型推論の説明の続きです。ytljitではYARVの命令列をノードと呼ぶオブジェクトのグラフ(VMと呼んでいる)に変換し、その後そのグラフをトラバースして機械語に変換します。ちょうどノードはYARVと機械語の中間くらいの命令に相当します。YARVや機械語のようにシーケンシャル(ジャンプはあるけど)ではなく、グラフ構造になっているのは型推論のためです。関連のあるノードを素早く(O(1)で)アクセスするためです。 型推論はこんな手順で行います データフロー解析を行ってデータの依存関係を調べる。例えば、ローカル変数の参照を表すノードなら、この変数に値を設定したノード(分岐やジャンプがあるので1つとは限らない)を集める 次のようなことを各ノードについて行う。

    ytljitの型推論の説明(その4) - miura1729の日記
  • ytljitの型推論の説明(その3) - miura1729の日記

    しつこいようですが、シグネチャーはメソッド呼び出しの際の引数を推論した結果の型オブジェクトの配列です。そして、型推論の際には必ずシグネチャが必要になります。 この2つのことから勘のいい人は気づくかも知れませんが(私はプログラムしてバグるまで気づかなかった)、シグネチャーを作るのにシグネチャーがいるのです。普通のメソッドだとそれほど問題ではないのですが、ブロック付きのメソッドの場合、シグネチャの型が一発で決まらないので、この辺の話が重くのしかかります。これが(その1)で書いたバグの根の原因であろう(まだ取れてないので想像)と思うのですが、この辺はよくわかってないので分かったら書きます。 次にメソッドの引数の話をします。ytljitではユーザが指定する普通の引数のほかに隠れ引数を渡します。隠れ引数は現在のところ次の3つです(例外処理とかで増えるかもしれない)。 親のブロックまたはメソッドのフ

    ytljitの型推論の説明(その3) - miura1729の日記
  • ytljitの型推論の説明(その2) - miura1729の日記

    2回目はシグネチャーを作る話です。シグネチャーはメソッドの引数の型オブジェクトを配列でまとめたものです。型オブジェクトという未定義の言葉が出てきたので、これから説明します。 型オブジェクトはRubyのクラスをWrapしたオブジェクトです。型オブジェクトはBOXING/UNBOXINGの2種類があり、Rubyのクラスと独立して設定できます。つまり、BOXINGなFixnumもUNBOXINGなArrayなんてのも表現可能です。それぞれの型オブジェクトは、次のようなメソッドを持っていて、コード生成時にあんまり型による場合分けとかせずに、型推論の結果による最適化が出来るようになっています。 gen_boxing (BOX化するアセンブラコードを生成する) gen_unboxing (UNBOX化するアセンブラコードを生成する) gen_copy (そのクラスのデータをコピーするコードを生成する)

    ytljitの型推論の説明(その2) - miura1729の日記
  • ytljitの型推論の説明(その1) - miura1729の日記

    今、ytljitでうまく推論出来ないプログラムがあっていろいろ直しています。うまくいかないプログラムはこんな感じのものです。 def f yield end f { 1 + 1} f { "abc"} このバグの話の詳細を書くと訳わからなくなるし、詳細はどんどん変わっいるのでそれは書きません。その代り大元の考え方を書いて考えを整理します。つまり、自分のための日記です。 Rubyの型推論ということで余り型を厳しくしてしまうと使いにくくなってしまいます。ytljitのポリシーとして型によるプログラムの検証は一切無視、できるだけオリジナルのRubyのプログラムを受け入れるとします。そうすると例えば、こんな感じのプログラムは推論したいところです。 def id(x) x end id(1.0) id("abc") メソッド単位で型付けをすると考えるとidの戻り値の型は決められない(またはObjec

    ytljitの型推論の説明(その1) - miura1729の日記
  • 1