CONST_APPLY インストラクション
直前エントリがあまりに悔しく、職場で朝イチ無理矢理現実トウヒ。紙の上で整理してみたら色々分かりました。
とりあえず CONST_APPLY と APPLY の中身を確認。
- CONST_APPLY
- VAL0 に手続きオブジェクトを置いて
- stack に引数 push して
- tail_call_entry に jmp
- APPLY
- 引数と手続き pop して
- Scm_VMApply() に渡して戻りを VAL0 セットして NEXT1
- Scm_VMApply()
- 引数 push
- PC に TAIL_CALL と RET を仕込む
- 引数で受けとった手続き
結局 TAIL_CALL に行くんじゃ何が違うんだろ、と言いつつ CONST_APPLY の中身見てみたら PC が指してるナニ (正確に何と言うのか) からリストへのポインタ取り出して car が手続きで cdr が引数。
FETCH_OPERAND() って何だっけ、と言いつつ M-t してみたら以下。
#define FETCH_OPERAND(var) ((var) = SCM_OBJ(*PC))
ちなみに code を取り出すのが以下なマクロ。
#define FETCH_INSN(var) ((var) = *PC++)
run_loop() の中のループの先頭らへんで ScmWord 型の code に FETCH_INSN マクロで PC の中身を取り出して格納している。という事はそれぞれのインストラクションな分岐の中では code は取り出したインストラクションを指している。
ので以下の命令列は
CASE(SCM_VM_CONST_APPLY) { int nargs = SCM_VM_INSN_ARG(code); ScmObj form, cp; CHECK_STACK(ENV_SIZE(nargs)); FETCH_OPERAND(form); INCR_PC;
引数 (CONST_APPLY の場合は nargs) を code から取り出して現在 PC が指してる領域の値を form にコピーして PC を増分しているのが分かります。
てーコトは
CONST_APPLY nargs
(proc arg1 ...) なリスト
な配列を順に、という事なのか、と得心。そういえば違うインストラクションでも PC から何かを取り出して INCR_PC しているケースがありましたな。
多分真面目に自分のエントリを確認してればこうしたものも確認できたんだろうな、と。
もう少し
説明にある_オペランドに含まれる_という表現については得心したんですが、コンパイル時に云々、という部分ってどうしたものやら。
とりあえず引き続き確認予定ッス。
追記
ええと、compile.scm のコメントに以下な記述がある。
;;; Pass 1 (Parsing): ;;; - Converts Sexpr into an intermediate form (IForm). ;;; - Macros and global inlinable functions are expanded. ;;; - Global constant variables are substituted to its value. ;;; - Variable bindings are resolved. Local variables are marked ;;; according to its usage. ;;; - Constant expressons are folded.
ここで lookup 不要なものは CONST_APPLY な扱いにしていたのでしょうが、現在では obsolete との事にて 0.8.11 な compile.scm からはその痕跡は消えているはず。
とりあえず成程、という事にします。
なんとなく compile.scm にそろそろ手を出せ、というご託宣なのでしょうか。