throw_cont_calculate_handlers() 手続き

とりあえずここから。

処理

全体としては ep と vm の handlers を使ってリストを作っているように読める。下準備として ep->handlers をひっくり返している。

    ScmObj target  = Scm_Reverse(ep->handlers);
    ScmObj current = vm->handlers;

で、まず current が指すリストについて以下。

    SCM_FOR_EACH(p, current) {
        SCM_ASSERT(SCM_PAIRP(SCM_CAR(p)));
        if (!SCM_FALSEP(Scm_Memq(SCM_CAR(p), target))) break;
        /* push 'after' handlers to be called */
        SCM_APPEND1(h, t, Scm_Cons(SCM_CDAR(p), SCM_CDR(p)));
    }

えーと current なリストの各要素について、target に car があれば h に append してます。ってか、handlers ってどんなリストなんでしょ。と言いつつ vm.c に dynwind_before_cc() なる手続きを発見。こんなカンジ?

((b3 a3) (b2 a2) (b1 a1))

上記リストの (cons (cdar p) (cdr p)) って以下?

((a3) (b2 a2) (b1 a1))

うーん。。

コメント見たら

以下な記述あり。

Returns a list of (<handler> . <handler-chain>),

なるほど。上記のリストが ep にも vm にもあるとすると戻されるリストは以下なカンジ?

(((a3) (b2 a2) (b1 a1)) ((a2) (b1 a1)) ((a1)) 
 (b1) (b2 (b1 a1)) (b3 (b2 a2) (b1 a1)))

上記なリストが throw_cont_body() 手続きに渡されるんですが、最初の分岐のあたりを以下に引用。

    /*
     * first, check to see if we need to evaluate dynamic handlers.
     */
    if (SCM_PAIRP(handlers)) {

むむ。handlers が空であれば ep な継続フレームを復帰して云々、なんだ。vm->handlers が更新されるタイミングを確認した方が良さげ。