langsmith:166
From: Shiro Kawai <shiro lava.net>
Date: Sat, 8 Jan 2005 07:45:56 +0900
Subject: [langsmith:166] Re: continuationの実装について
説明をはしょりすぎたかもしれません。「なんでも継続」を
完成させるのが一番良いんでしょうが、なかなか…
ところでSCM方式のスタックコピーによる継続は、ちょっと使い勝手に
癖があります。知っている人は知っている話だと思いますが、あまり
明文化されていないような気もするので、書いておきます。
(Guileのドキュメントにはちゃんと書いてあるかもしれない)。
Cで実装した組み込み関数 (Lisp風に言えばsubr) から、処理系の
評価機へ再入するとします。そして、その関数中で、何かのリソース
(ファイルハンドルでも、GCの対象にならないシステムメモリでも)を
獲得して使う必要があるとします。Cでのイディオムだとこんな感じです。
obj_t foo(obj_t expr, env_t env)
{
handle_t h;
obj_t result;
h = allocate_resource();
result = eval(expr, env); /* 評価機再入 */
do_something(h);
destroy_resource(h);
return result;
}
これは、SCM方式の継続を使っている場合、失敗します。evalから
2回以上リターンしてくる可能性があり、2回目に戻って来た時には
hが既に開放されているからです。C++が間にはさまった場合は
上記のリソースアロケーション/デアロケーションがauto変数の
コンストラクタ/デストラクタで暗黙的に実行される可能性があるので
さらに注意が必要です。
回避法は、
- アロケートしたリソースはGCを使って回収する
- それが出来ない場合はフラグを持っておいて、2回以上復帰
してきたらエラーを投げる(フラグはローカル変数に持つと
継続で巻き戻されてしまうのでヒープに持つ)
evalみたいな明示的な再入でなくても、何らかのパスで評価機に
再入する可能性がある箇所全て(シグナルハンドラとか、例外ハンドラ
が呼ばれる可能性がある箇所とか)でこの配慮が必要です。
--shiro
--
ML: langsmith quickml.atdot.net
使い方: http://www.atdot.net/~ko1/quickml
161 2004-12-29 23:25 [mogami brain.riken.g] continuationの実装について 162 2004-12-29 23:59 ┣[mogami brain.riken.g] 163 2004-12-30 00:18 ┃┗[matz ruby-lang.org ] 164 2004-12-30 08:36 ┗[shiro lava.net ] 165 2005-01-06 18:55 ┗[mogami brain.riken.g] -> 166 2005-01-08 07:45 ┗[shiro lava.net ]