TinyCCを使う
FFIコールにおける関数アドレス解決方法を調べるメモ
- Parser
Parser>>externalFunctionDeclaration でExternalLibraryFunctionを格納する
ExternalLibraryFunction(ExternalFunction)>>invokeWithArguments: ->
FFIPlugin>>primitiveCalloutWithArgs(primitiveCallout) ->
FFIPlugin>>ffiLoadCalloutAddress
呼び出し関数のExternalLibraryFunctionのハンドルを調べその関数アドレスが正規のものであればこれを関数アドレスとして、以降実行する。なければ外部ライブラリを読み込みを行いアドレス解決を行う。
で上記の動きを確認してみる。
ExternalLibraryFunction allInstances --> #(<cdecl: double 'ffiTestDoubles' ...(いっぱい) ExternalLibraryFunction allInstances at: 56 --> <cdecl: X11Display* 'XOpenDisplay' (char*) module: 'X11'> (ExternalLibraryFunction allInstances at: 56) class --> ExternalLibraryFunction (ExternalLibraryFunction allInstances at: 56) name --> #XOpenDisplay (ExternalLibraryFunction allInstances at: 56) getHandle --> @ 16r00000000 X11Display coloredRectangles "<- do it" (ExternalLibraryFunction allInstances at: 56) getHandle --> @ 16rB7C583F0 (ExternalLibraryFunction allInstances at: 56) getHandle class --> ExternalAddress
FFIの外部ライブラリ呼び出しにおいて関数アドレス解決手順がわかったので、TinyCCを使いJIT的にオンメモリに配置した関数を呼び出すには上記ExternalLibraryFunctionのハンドルをtcc_get_symbol(TinyCC API)で得た関数アドレスを設定(ExternalLibraryFunction>>setHandle:)すればよさそう。
- プリミティブテーブル
Interpreter classPool at: #PrimitiveTable