「プログラミング言語を作る」ソースコードバグ情報

このページは、拙著「プログラミング言語を作る」技術評論社 ISBN978-4-7741-3895-4 におけるプログラムソースのバグ情報です。


2013/12/08 crowbarのinterface.cにおける無駄なコード

crowbar_bookの0.2以降のinterface.cには、以下の関数があります。

static void
release_global_strings(CRB_Interpreter *interpreter) {
    while (interpreter->variable) {
        Variable *temp = interpreter->variable;
        interpreter->variable = temp->next;
    }
}

このプログラムは、ループしながらinterpreter->variableを書き換えていますが、 最終的にはinterpreter->>variableはNULLになるだけですので、 単純に「interpreter->variable = NULL;」と書くのと同値です。 そしてその処理は呼び出し側のCRB_dispose_interpreter()でも行っているので、 この関数自体が意味を持ちません。

どうも、こうなってしまった原因は、 crowbarのver.0.1の参照カウンタ使用版における以下の関数にあるようです。

static void
release_global_strings(CRB_Interpreter *interpreter) {
    while (interpreter->variable) {
        Variable *temp = interpreter->variable;
        interpreter->variable = temp->next;
        if (temp->value.type == CRB_STRING_VALUE) {
            crb_release_string(temp->value.u.string_value);
        }
    }
}

この時点では、連結リストで管理しているグローバル変数を順に確認し、 文字列だった場合は文字列の領域を開放する、という処理が必要でした。

ver.0.2以降はmark&sweep式のGCを導入しましたので、 interpreter->variableをNULLにしたうえでcrb_garbage_collect()を 呼び出せばこのような処理は不要です(そして実際にそのようにしています)。

ver.0.1を修正して0.2を作るとき、 コンパイルエラーになるところだけ削って無駄な関数を残してしまったようです。


2013/12/08 realloc()するスタック領域をネイティブ関数に渡している

これは、crowbar, Diksamの両方にある問題です。

ver.0.2以降のcrowbarおよびDiksamでは、 スタックをrealloc()で伸長しています。 そして、ネイティブ関数を呼び出す際、 スタック配列の要素へのポインタをネイティブ関数にそのまま渡してしまっているので、 さらにrealloc()によりスタックが拡張されたときには アドレスが変わってしまう可能性があります。

ネイティブ関数の中でスタックが伸びることがあるのかというと、 crowbar/Diksamともに、ネイティブ関数内からcrowbarまたはDiksamの 関数を呼び出す手段を提供しているので、 (頻度はともかく)問題が起きる可能性があります。

すみませんが、当方ではすぐには直せそうにありません。 具体的な修正方法については こちらの掲示板の議論も参考にしてください。


書籍情報のページに戻る | 著者のWebページトップはこちら

ご意見、ご質問、不具合連絡等は掲示板にお願いいたします。