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 方面に去ります。