LOCAL_ENV_CLOSURE

ええと、LOCAL_ENV* なインストラクションがどんな状態で出てくるんだか忘れてます。自分ブログを検索しても出てこない。どっかで LOCAL_ENV が出てきたのを見た記憶があるんですが、何だったか全然思い出せん。

試行錯誤している内に以下を発見。

gosh> (disasm (lambda () (+ ((lambda (x y) (* x y)) x y) ((lambda (x y) (/ x y)) x y))))
main_code (name=#f, code=0x814bd80, size=22, const=4, stack=13):
args: #f
     0 GREF-PUSH #<identifier user#x>; x
     2 GREF-PUSH #<identifier user#y>; y
     4 LOCAL-ENV(2)             ; ((lambda (x y) (* x y)) x y)
     5 LREF1-PUSH               ; x
     6 LREF0                    ; y
     7 NUMMUL2                  ; (* x y)
     8 POP-LOCAL-ENV 
     9 PUSH-PRE-CALL(2) 20
    11 GREF-PUSH #<identifier user#x>; x
    13 GREF-PUSH #<identifier user#y>; y
    15 LOCAL-ENV(2)             ; ((lambda (x y) (/ x y)) x y)
    16 LREF1-PUSH               ; x
    17 LREF0                    ; y
    18 NUMDIV2                  ; (/ x y)
    19 RET 
    20 NUMADD2                  ; (+ ((lambda (x y) (* x y)) x y) ((lambda ...
    21 RET 
#<undef>
gosh> 

なんとなく LOCAL_ENV_CLOSURE なナニを見つつ類推してみる事に。
まず、

                int nlocals = SCM_VM_INSN_ARG(code);
                ScmObj *z, cp, clo = SCM_UNDEFINED;
                ScmEnvFrame *e;

にて変数の初期化。先頭にて int な nlocals にインストラクションの引数を取り出して設定しているはず。で

                FETCH_OPERAND(cp);
                INCR_PC;

で PC が指してる領域からデータを取り出して cp にセットして PC を ++ している。取り出したデータは何らかのリストの先頭な模様。
で?

                CHECK_STACK_PARANOIA(ENV_SIZE(nlocals));
                SP += nlocals;
                FINISH_ENV(SCM_FALSE, ENV);

むむ。スタックのチェックして SP 増分させて FINISH_ENV しています。このあたりポイント高そげなんですが、意図としては今から引数積むけど FINISH_ENV はしとくかんね、という事なのでしょうか。
以降にて

                e = get_env(vm);
                z = (ScmObj*)e - nlocals;

みたいな初期設定してます。get_env とか若干微妙、と言いつつ自分ブログを検索かけたら http://d.hatena.ne.jp/yamanetoshi/20090330/p1 なエントリを発見。
明日、現実トウヒがてら確認する方向で EoPL 方面に去ります。