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