早起きしたので
メモ。
PUSH_CONT
emacs で vm.c 開いて M-x occur PUSH_CONT したらマクロ定義のソレを除くと以下のソレでマクロを使っている模様。
- TAIL_CALL_INSTRUCTION マクロ
#define TAIL_CALL_INSTRUCTION() \
do { \
if (!TAIL_POS()) { \
CHECK_STACK(CONT_FRAME_SIZE); \
PUSH_CONT(PC); \
PC = PC_TO_RETURN; \
} \
} while (0)
- SCM_VM_PRE_CALL
CASE(SCM_VM_PUSH_PRE_CALL) {
CHECK_STACK_PARANOIA(1);
PUSH_ARG(VAL0);
}
/* FALLTHROUGH */
CASE(SCM_VM_PRE_CALL) {
ScmWord *next;
CHECK_STACK_PARANOIA(CONT_FRAME_SIZE);
FETCH_LOCATION(next);
PUSH_CONT(next);
INCR_PC;
NEXT;
}
- SCM_VM_RECEIVE
(ry
- SCM_VM_RECEIVE_ALL
(ry
- SCM_VM_IS_A
(ry
- いっちゃんケツ
process_queue:
CHECK_STACK(CONT_FRAME_SIZE);
PUSH_CONT(PC);
process_queued_requests(vm);
POP_CONT();
NEXT;
- user_eval_inner() 手続き
TAIL_CALL_INSTRUCTION
これも M-x occur してみた。
- APPLY
- SLOT_REF
- SLOT_SET
- SLOT_REFC
- SLOT_SETC
これは昨晩見た。これ、末尾呼び出しじゃなかったら PUSH_CONT して云々なマクロ。なんなんだ、と言いつつ以下なソレを確認。
gosh> (disasm (lambda (x y) (x 1 2) (y 3 4)))
main_code (name=#f, code=0x80f7ed0, size=11, const=0, stack=11):
args: #f
0 PRE-CALL(2) 6
2 CONSTI-PUSH(1)
3 CONSTI-PUSH(2)
4 LREF1 ; x
5 CALL(2) ; (x 1 2)
6 CONSTI-PUSH(3)
7 CONSTI-PUSH(4)
8 LREF0 ; y
9 TAIL-CALL(2) ; (y 3 4)
10 RET
#<undef>
gosh> こーゆーの以前確認したような気がする。PRE-CALL って確か PUSH_CONT してます。てーか上記のインストラクションの並びを追い掛けると確かにココの_通常の関数呼び出し_ナニに書いてあるコトがそのまんま、に見えますな。
えーと整理しとくと
- 1.の push cont は通常の手続き呼び出しだと PRE-CALL なインストラクションで行なわれる (はず
む。コード読んでみると例の図では_引数フレームのヘッダを積_んで引数 push してますが、逆に引数 push して最後に引数フレームのヘッダをナニしているように読めます。
中断
がきを連れて自転車の練習に行くので中断。