Gauche:FFIと型表現
Shiro(2021/05/03 08:43:27 UTC): Gauche内でCの型表現に関係する箇所がいくつかあるんだけど、必要に迫られてアドホックにやってるのでバラバラ。FFI導入を機に整理したい。
今あるコンポーネント
Stub type
define-cprocの引数と戻り値で使う ::<int>
など。これはSchemeとCのブリッジの役割も担っている。
gauche.cgen.type
- 各stub typeは
<cgen-type>
のインスタンス - Schemeオブジェクトの型検査、Cへのunboxing、CからのboxingのCコードを生成する
- 具体的なCのデータ表現は知らない (Cコードを生成した後はCコンパイラに丸投げ)
- Schemeの型とCの型は m-to-n。
- Schemeに対応するものしか考えてないので、Cで表現可能な型全てを表現できるわけではない。
CiSE type
CiSEでCの型を表記する表現。::long
とか ::(const char*)
とか。
gauche.cgen.cise
- CiSEはこの型表現の中身はチェックしていない。ただテキストとして扱ってるだけ。なのでユーザ定義型とかトラックする必要もない。
- Cで表現できる型はだいたい書ける。
ftype
バイナリデータを扱うために書きかけになってるもの。
binary.ftype
- データレイアウトを定義して、バイナリデータからフィールドを抽出したりセットしたりするのが目的
ftype
レコードのインスタンス- 各インスタンスはendianやalignment、構造体内でのオフセットなどの情報を保持。
- まだ基本型とstructしかサポートしてない
C parsed type representation
lang.c
でCコードをパーズする際の型情報の表現。
lang.c.type
- S式による表現
- Cで表現可能な型は全部カバー。そのためちょい冗長。
- typedefはトラックしてる (でないとパーズできないので)
- 実行アーキテクチャから中立。
Foreign pointer
実行時に外部オブジェクトへのポインタを扱う仕組みだが、attributeに型情報を載せることは可。
今のところ、外部ライブラリごとにカスタムでインタフェースをCで書いてるので、 汎用的に型情報をメタに扱う仕組みはない。
Native call
ネイティブ関数を呼び出す低レベルAPI
- ABIの対応する型だけトラック。
FFIで必要なもの
- 外部から与えられる情報
- 外部間数ごとのインタフェース宣言 : 型の簡潔な表記。CiSE表記が多分ベスト。
- ヘッダファイルをパーズしたもの:
lang.c
の表現
- 内部で必要なもの
- Native callの型情報へのマッピング。これは実行アーキテクチャ依存。
- aggregate objectについて、uvectorにpack/unpackするためのftype
- pointerについてはforeign pointerとして見せるが、それにくっつけるための型情報
ftypeを軸にするのが良さそう。
- CiSE表記→ftype
lang.c
表現→ftype- ftype→Native call type
- foreign pointerにftypeをアタッチするユーティリティ
ここまでftypeが重要ならコアに組み込むべきか。