理解が深まれば、適宜更新します。
G-machine
- グラフ簡約のためのスタックマシン
- 関数適用が連なる spine (背骨)を持ち、愚直にカリー化を実現する
- 簡約のたびに、それぞれの項を更新
- ローカル関数はラムダリフティングしてグローバル関数に直す必要がある
- ラムダリフティングされた関数はスーパーコンビネータと呼ばれる
- Gコード
- push/enter 方式
Spineless G-machine
- Spineless: 引数が充足している関数は、一気に呼び出す
- このころまでに標準の G-machine も spineless だったらしい
- サンクは共有されているときだけ更新 (これが重要)
- G コードに対して 5 つの新しいコードを追加
- push/enter 方式
Spineless Tagless G-machine
- Tagless: 統一された書式になって、先頭の tag がなくなった。先頭は info へのポインタ
- T コード
- case 文での分岐は、評価する式が vectorized returns を返すので、直接分岐へ飛べる
- push/enter 方式
STG(Shared Term Graph) language and STG(Spineless Tagless G) machine
- 現在のSTG
- push/enter 方式から eval/apply 方式に変わった
- コンパイル時に不明な関数へは、generic apply する。stg_ap_p_fast とかが generic apply
- eval/applyだからスタックは使わないと思いきや、実際の関数呼び出しでレジスタが足りなければスタックは使う
- pointer taggingを採用した
- ヒープを指すポインタの下位2ビット(32ビットの場合)をタグとして使う
- これにより vectorized returns は廃止された
- 即値(unboxed value)も使える
- 即値(boxed)かポインタ(unboxed)かは、info の layout を見れば分かる (GC に重要)
- Spineless とか Tagless とか、もう意味がないので、STG 言語は Shared Term Graphの略称になった
疑問
- update しなくていいサンクって、どうやって値を保持するんだろう?