Scm_VMCallCC (10)
次は末尾呼び出し。こんなカンジを例に。
gosh> (disasm (lambda () (fold + 0 '(1 2 3)))) main_code (name=#f, code=0x80f8ec0, size=8, const=3, stack=6): args: #f 0 GREF-PUSH #<identifier user#+>; + 2 CONSTI-PUSH(0) 3 CONST-PUSH (1 2 3) 5 GREF-TAIL-CALL(3) #<identifier user#fold>; (fold + 0 '(1 2 3)) 7 RET #<undef> gosh>
ええと PRE-CALL が略されてるので継続フレームが push されてません。これはVMのスタック操作の_末尾呼び出し_の 1. に解説あり。
ちょっと ARGP とかの値が微妙に気になりますが、とりあえずスルー。
で
4. の調整なんですが、tail_call_entry なラベル以下のナニ。ざっくり的にドキュメントと合致してるな、というアバウトな理解ッス (を
tail_call_entry: argc = SP - ARGP; if (IN_STACK_P((ScmObj*)CONT)) { to = CONT_FRAME_END(CONT); } else { /* continuation has been saved, which means the stack has no longer useful information. */ to = vm->stackBase; } if (argc) { ScmObj *t = to, *a = ARGP; int c; /* The destintation and the source may overlap, but in such case the destination is always lower than the source, so we can safely use incremental copy. */ for (c=0; c<argc; c++) *t++ = *a++; } ARGP = to; SP = to + argc; /* We discarded the current env, so make sure we don't have a dangling env pointer. */ ENV = NULL;
ええと、ざっくりで
- to を設定して
- 底、の設定な詳細はスルー (を
- ARGP が指すナニを順にコピィ
- レジスタ設定
というナニ?
ちょっと
スルー多杉な気がするのでリトライするかもしれません。(何