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 が指すナニを順にコピィ
  • レジスタ設定

というナニ?

ちょっと

スルー多杉な気がするのでリトライするかもしれません。(何