下書き

throw_cont_cc 手続きの概要下書き。

とは言え

下書きの前に整理を。

  • throw_cont_cc は throw_cont_body で handlers がペアな間、延々呼び出される。
  • throw_cont_body に渡される handlers は最初に throw_cont_calculate_handlers() 手続きで作られたリスト
  • throw_cont_body に渡されたリストが空リスト以外の場合には handlers の caar 要素を apply して 継続として handlers の cdr を throw_cont_body に渡す形で handlers が空リストになるまでセットされた手続きを呼び出していく
  • handlers が空リストになったら継続を起動してセットされた引数を渡す

うーん、なんか微妙。三番目が長いな。大体これは throw_cont_body 手続きの説明クサい。ええと

  • throw_cont_cc 手続きの引数 data はポインタ配列
  • 最初 1 番目 の要素は ScmObj 型 (struct ScmHeaderRec 構造体のポインタ)
  • 2 番目 の要素は ScmEscapePoint 型のポインタ
  • 最後 3 番目 の要素は ScmObj 型 (struct ScmHeaderRec 構造体のポインタ)
  • 上記を引数に throw_cont_body 手続きを呼び出す

む。最後の微妙。

  • 上記を引数に throw_cont_body を呼び出してその戻り値を戻す

ちなみに handlers がペアじゃないケイスの throw_cont_body 手続きの戻りは Scm_VMApply0() 手続きの戻り。これって引数で渡された手続きオブジェクトを戻すはず。
ええと、継続手続きが呼び出された時は throw_continuation() 手続きが起点になるので、handlers がペアの場合は

  • hendlers 設定
  • throw_cont_body 呼び出し
    • throw_cont_cc が継続フレームに push
    • handler が apply
      • handler を TAIL_CALL
      • 継続を pop
  • throw_cont_cc 呼び出し
    • handlers の cdr が handlers にセッ
    • throw_cont_body 手続き呼び出し
    • 二番目に戻る

これはどーゆー繰り返しなんでしょうか。なんとなく繰り返しに読めちゃうのは scheme 脳に完全に侵されてるからなんでしょうね。あら? でも一旦 run_loop() に戻ってるなぁ。やっぱ繰り返しなのか。

追記

ええと、上記では簡単に_handler が apply_って書いてますが、pc にインストラクションな配列がセットされて handler を戻してるのか。で、戻りがセットされてる val0 に構わず NEXT してる模様。以下なあたりなはず。

                    VAL0 = SCM_SUBR(VAL0)->func(ARGP, argc,
                                                SCM_SUBR(VAL0)->data);
                    /* the subr may substituted pc, so we need to check
                       if we can pop the continuation immediately. */
                    if (TAIL_POS()) RETURN_OP();
                    NEXT;

VM_CALL なインストラクションの SCM_PROC_SUBR な処理のあたり。pc は RET を指してないので NEXT する、と。
とりあえず情報投入してみましょう。