うーん
へろへろなので、と信じたいんですがよく分からん。
VMのスタック操作(未完) なるドキュメントをニラミつつナニ。
_通常の関数呼び出し_なマンガ見ながら色々検討した記憶があるような無いような。
とりあえず色々見てたんですが CALL なインストラクションは今の理解では微妙。きっかけが何かは忘れましたが、とりあえず PUSH_CONT マクロ。
/* Push a continuation frame. next_pc is the PC from where execution
will be resumed. */
#define PUSH_CONT(next_pc) \
do { \
ScmContFrame *newcont = (ScmContFrame*)SP; \
newcont->prev = CONT; \
newcont->env = ENV; \
newcont->argp = ARGP; \
newcont->size = SP - ARGP; \
newcont->pc = next_pc; \
newcont->base = BASE; \
CONT = newcont; \
SP += CONT_FRAME_SIZE; \
ARGP = SP; \
} while (0)これは正に_1. push cont_なソレですな。ええと、vm.c で M-x occur PUSH_CONT したら以下なナニが列挙 (ちなみに Gauche-0.8.11)。
TAIL_CALL_INSTRUCTION マクロ
以下。
/* used for the inlined instruction which is supposed to be called at
tail position (e.g. SLOT-REF). This checks whether we're at the tail
position or not, and if not, push a cont frame to make the operation
a tail call. */
#define TAIL_CALL_INSTRUCTION() \
do { \
if (!TAIL_POS()) { \
CHECK_STACK(CONT_FRAME_SIZE); \
PUSH_CONT(PC); \
PC = PC_TO_RETURN; \
} \
} while (0)コメントは後で見るとして、このマクロをナニしてるのが以下のインストラクション。
- APPLY
- SLOT_REF
- SLOT_SET
- SLOT_REFC
- SLOT_SETC
うーん。なんなんだ。SLOT_* は略として APPLY されて末尾呼び出しでなければ、
- スタックに継続フレーム push するナニがあるかチェキ
- 継続フレーム push
- PC に RET をナニ
という事ッスか。末尾呼び出しでなければ apply する時には継続フレームが push される、ってとりあえず参考コンテンツに書いてある通り?
# 問題になってるのは次以降なんですが ...
PRE_CALL インストラクション
CASE(SCM_VM_PRE_CALL) {
ScmWord *next;
CHECK_STACK_PARANOIA(CONT_FRAME_SIZE);
FETCH_LOCATION(next);
PUSH_CONT(next);
INCR_PC;
NEXT;
}むむ。PRE_CALL は CALL した直後にある命令のための継続の処理?
次
色々雑念が入ってワケワカんなくなり始めてるので機械的に。以下、簡単に PUSH_CONT マクロをナニしているインストラクションとか。
- RECEIVE
- IS_A
- run_loop のいっちゃんケツ
いっちゃんケツのソレが微妙。
process_queue:
CHECK_STACK(CONT_FRAME_SIZE);
PUSH_CONT(PC);
process_queued_requests(vm);
POP_CONT();
NEXT;
}
}
/* End of run_loop */正に末端。しかもぱっと見ワケワカ。
を
PUSH_ENV_HDR ぽいナニを見つけた。
/* push environment header to finish the environment frame.
env, sp, argp is updated. */
#define FINISH_ENV(info_, up_) \
do { \
ScmEnvFrame *e__ = (ScmEnvFrame*)SP; \
e__->up = up_; \
e__->info = info_; \
e__->size = SP - ARGP; \
SP += ENV_HDR_SIZE; \
ARGP = SP; \
ENV = e__; \
} while (0)あ、引数とかツむのってこの後になるのか。ちょっと限界気味なんで、明日これを見つつ復習予定ですが、時間が確保できるかどうかは微妙ッス。