KLICでは、基本的に、先(
ページ、第3.1章参照)に述べた動作モデルのように、
KL1で書かれたコードを実行しつづける。しかしながら、
以下に記述するような理由により、「例外的な処理」を行う必要が生じるときがある。
これらの「例外的処理」は必要に応じて、「述語実行の切れ目」で 行う。つまり、1つの述語が終了し、次の述語を実行する間に 例外的処理を行う必要があるかどうかを判断し、もし必要であれば、 必要な処理(例えば、GC)を行う。
KLICでは、1つのゴールのリダクション途中では、
様々な変数(一時変数, 引数変数、ヒープ割付点などなど)
が更新された状態にあり、GC等を含み得るような処理をするために
必要なこうした変数の退避は難しく、効率も悪いため、
述語の実行中は「他の処理」(
ページ、第3.2章参照)
を行わず、述語実行に専念するようにしている。
よって、述語実行中に 「例外的処理」が必要になった場合には(例えば、割り込みハンドラで) 「次の述語実行の切れ目でわかるように」覚えておくだけで、すぐに通常の 述語実行を継続する。そして述語実行の切れ目では、「例外的処理」を行う必要が あるかどうか検出し、必要あれば、他の処理を行う。
この「例外的処理」要求の検出が、allocpとheaplimitの比較である。 allocpはヒープ割付点であり、heaplimitは、ヒープの上限である。 つまり、通常のヒープ溢れはこの比較で検出され、GCが起動される。 他の「割り込み」については、人為的(一時的)にこのheaplimitを0にすることにより 割込まれたことを記憶しておく、という方式をとっている。 したがって、この大小比較のみで、「例外的処理」要求有無の検出ができる。
この例外処理は、モジュール関数の末尾で呼び出される実行時ライブラリ、
interrupt_goal で行われる。この内部ではreasonpの値により、
どのような例外が起きたのか判定され、適切な処理が行われる。
これらの処理をひきおこすコード箇所については、第3.2章 (
ページ)を
参照のこと。
この場合には、「中断原因の候補」は中断スタックに積まれているので、 それを調べ、候補が全て真に未定義変数(含む中断構造)であれば中断処理を行う。 候補のいずれかが具体値であることが判明すれば、resume_same_prio()関数 により、当該ゴールを「再開」する(つまり、エンキューしてしまう)。