callback問題

5分くらいで出来るかと思ったらそうでもなかったので。
やること :

トランポリンコードの生成

callbackにschemeクロージャを直接渡すことは出来ないので、一旦、schemeクロージャを呼び出す機械語コードを生成してやる必要がある。

要するに変数に適当にstubを代入(FFI_INIT_TRAMPOLINE)してそれをコードのアドレスとして渡してやれば良い。(適切な実行許可を与える必要がある。普通はmmapとかVirtualAllocの属性として与える。)
標準Cのmallocには当該機能は無いので、libffiは自前のdlmallocを実行可能属性を持ったmmapを使うように改造して使っている。

メッセージへの変換

上でschemeクロージャを呼び出すと書いたけど、Boehm GCは予め登録されたスレッドだけがGC_*を使うことができる。要するに、FFIモジュールが作ったスレッドの実行コンテキスト中にSchemeオブジェクトを作ることは出来ない。
例えばSDLのようなライブラリはcallbackが呼び出し側のスレッドで実行されることは保証していないので、直接closureを呼び出すことはできない。
というわけで、受信側がSchemeオブジェクトを作るようなメッセージ送受信を作らないといけない。

ユースケース

ユースケースは常に検討する必要がある。callbackの用途として :

  • GtkやgstreamerのようなGObjectのsignal
  • SDLのようなバッファのpush要求
  • 非同期I/O
  • 等々

非同期I/Oの類は専用のスレッドやVMを持つのは悪くないアイデアに思えるが、ボタン1つに1VMは流石にどうかという気持ちになる。だから複数のオブジェクトを一つのVMで待ち受ける仕組みが必要になる。仮にそのような仕組みにしたとしても、受信側のVMでディスパッチするようなコードを書くのはあまりスマートには思えない(Win32みたいだ!)。