スキップしてメイン コンテンツに移動

投稿

8月, 2010の投稿を表示しています

js-ctypes実装に見るlibffiの利用(& Windows-MSVCでのビルド法)

Firefox 3.6から入った、chrome権限のJavaScriptから外部バイナリコンポーネントのネイティブ関数を呼び出す機構である js-ctypes の実装が、 libffi に基づいているということだったので、昔見たときはlibffiはVisual C++はサポートしてなかった記憶があったがFirefoxでビルドできるんだったら単体でもいけるよねーということで js-ctypesのソース を追いつつ試してみた。 結果から先に述べると、若干手間を要するものの問題なくビルドでき、closureも利用できた。ここでいうclosureとは、呼び出された際にユーザー指定コールバック関数(元の呼び出しに使われたlibffiフォーマットの引数データが渡ってくる)を起動してくれる関数コードを、ユーザーが動的に指定したシグニチャで、ランタイムに実行可能メモリ上に構築してくれるlibffiのAPIが用意されているので、それを利用して作成したバイナリコードを指す。 js-ctypes実装の構造は至極直截的で、JSのオブジェクトとネイティブオブジェクトのバインダとしての CTypes クラス と、dll/so/dylibみたいなバイナリコンポーネントのラッパーの Library クラス から成っている。 Library::Declare でシンボルからバイナリ内の関数アドレスを得るときは、 PR_FindFunctionSymbol を呼ぶ。これは NSPR の関数で、Windows上では、なんのことはない GetProcAddress が呼ばれる 。なんでlibffiなんてものが必要かというと、荒っぽく言ってしまえば、Cでは関数ポインタを宣言しておけばコンパイラが良きに計らってくれるところ、動的言語で同じことをランタイムに行うために、その辺の呼び出し規約上のお膳立てをlibffiが整えてくれるというわけだ。 上述のclosureは、js-ctypesでは、ネイティブコード側にJavascriptの関数をコールバックとして渡す時に利用されている。Javascript関数オブジェクトに関連づけたclosureを作成し、それが呼び出された場合には CClosure::ClosureStub が呼び出され、関連づけられていたJavascript関数オブジェクトが実行される