Let's start Scheme

2011-05-03

Call/ccの実装が甘い

R6RSテストを通そうと足掻いているのだが、いまいち上手くいかない。
現在問題になってるのは、Cで実装されたassertion-violationがCのスタックを食いつぶすこと。
単発なら問題になることはないのだが、テストケースでは&assertionが発生してもテストを継続するため、例外 -> ハンドラ -> 例外 -> ハンドラ 以下続くとなりCのスタックを食いつぶす。
なぜこれが発生するかというと、dynamic-windがCで実装されていてかつ、call/ccがSchemeレベルの継続しか捕捉しないため、上記のようなC→Scheme→C→Schemeといった交互にレイヤーが変わるようなものに対して、継続が呼ばれた際にSchemeのスタックは戻すけど、Cのスタックはつぶされたままということになる。(のだと思う)
(Ypsilon、moshはdynamic-windがSchemeレベルで実装されているのでcall/ccで上記の問題は起きないと予測。Gaucheはそれように継続を捕捉した際にCのスタックもjmpbufという形で捕捉している、と思う)

解決方法はおそらく2つあって、dynamic-windをSchemeレベルにする、または継続を捕捉する際にCの継続も捕捉するのどちらかになるのかと。
とりあえず、後者かな。現状回避だけ見れば前者が早いのだけど、もう少し先を見据えると、dynamic-windはCで実装されててほしい気がする。

No comments:

Post a Comment