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 が更新されるタイミングを確認した方が良さげ。