リハビリ

体調崩したままですが、微妙に頑張る。
とりあえず cstack の意味合いは微妙な理解ながらも throw_continuation() 関数に書いてある事自体は読むことができる。微妙なのが以下なソレ

    if (vm->cstack != ep->cstack) {
        ScmCStack *cstk;
        for (cstk = vm->cstack; cstk; cstk = cstk->prev) {
            if (ep->cstack == cstk) break;
        }
        if (cstk == NULL) {
            Scm_Error("a continuation is thrown outside of it's extent: %p",
                      ep);
        } else {
            /* Rewind C stack */
            vm->escapeReason = SCM_VM_ESCAPE_CONT;
            vm->escapeData[0] = ep;
            vm->escapeData[1] = args;
            siglongjmp(vm->cstack->jbuf, 1);
        }
    } else {

vm->cstack と ep->cstack が違う、というタイミングが何なのかは不明。ちなみに cstack って ScmCStack 型なソレ (ポインタ) で定義は gauche/vm.h にて以下。

typedef struct ScmCStackRec {
    struct ScmCStackRec *prev;
    ScmContFrame *cont;
    sigjmp_buf jbuf;
} ScmCStack;

ポインタ値が違うってコトは新たなナニが stack に積まれている、という事か。おそらくは stack が積まれる瞬間を確認すれば良いのでしょうが、今日の時点ではスルー。

ポインタ値が異なる場合、スタックを ep が指すソレまで巻き戻して、って巻き戻した cstk は使われてませんな。あれば OK ってコトですか。ちょっと整理してみると

  • vm->cstack と ep->cstack が違う
    • vm->cstack を順に掘る。NULL になったら終了
    • ep->cstack と同じポインタ値があれば終了
    • NULL で終了してたらエラー

てーコトは vm->cstack が始点のスタックなリストに ep->cstack な要素があれば OK なんスか。ただ、rewind する処理は未だに理解が微妙です。