Perlテックブログ

ITエンジニアの成長意欲を刺激する技術考察、モジュール開発の日記。Perlイベントや国内や海外のPerlの記事の紹介。

CレベルAPIにおける関数の安全な呼び出しにはシグニチャが必要になりそうだ

SPVMでは、C言語/C++バインディングする機能をネイティブインターフェースと呼びます。

ネイティブインターフェースでは

  • 配列の作成
  • 配列の要素の取り出し
  • オブジェクトの作成
  • サブルーチンの呼び出し

なんてことができる。

安全にサブルーチンを呼び出すには?

今考えているのは「安全にサブルーチンを呼び出すにはどうしたらいいんだろうか」ということ。

静的型言語での危険性というのは、間違った型のデータが、渡されてしまって、プログラムが壊れてしまうことだ。

たとえば、オブジェクトが要求される引数の位置で、整数型を渡してしまったら、プログラムが壊れてしまう。もしこれに気が付けなければ大変だ。

ネイティブコードにコンパイルされたら、静的に型チェックできない

問題点は、一度ネイティブコードにコンパイルされたら、静的に型チェックできないということだ。

  1. AというパッケージからBというパッケージのfoo($num : int)というサブルーチンを呼び出す。
  2. Aというパッケージがネイティブにコンパイルされた。
  3. Bというパッケージのfooという関数がfoo($obj : Point)に変わった

さぁ、Aというパッケージは、この変更をどうやって知ったらよいのだろうか? 変更が起こった時に、エラーを出すためにはどうしたらいいだろう?

解決策は、動的に型チェックするしかないような気がする

この解決策は、たぶん、Javaにならって実行時に動的に型チェックするしかないような気がする。シグニチャも含めて、指定して、実行時に、本当にそのサブルーチンが存在するかをチェックする。

int32_t sub_id = env->get_sub_id("B", "(int)foo(int)");
if (sub_id < 0) {
  // 例外処理
}
args[0].ival = 5;
env->call_sub(sub_id);