リハビリ
体調崩したままですが、微妙に頑張る。
とりあえず 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 する処理は未だに理解が微妙です。