ビルドシステム

2段階ビルド、別バイナリ方式で検討に入る。スレッドが入るリリースくらいでmergeしたいが。。

phase0 : ライブラリの検査とconfiguration

何らかの形でライブラリのリンクテスト等を行う。見つかったライブラリはすべてリンクする。
また、CPU固有の最適化に関して検査する。skySchemeのコンパイラは(SSEやSPEのintrinsicsを出力する都合上)サポートしているSIMD命令の範囲に影響を受ける。

phase1 : stubコードの生成

一部のコードはCソースコードに静的に変換される。この部分の変換はskySchemeのものを流用する(というかこれからC言語変換を実装する*1。。)。
C言語に静的に変換されるのは、

  • 構造体の処理(本来のskySchemeのユースケース)
    • 構造体のメンバをschemeオブジェクトに変換したりその逆。
    • アクセサのみを提供する場合も有る。
  • C関数の呼び出し
  • OS固有の同期などスレッド関連の処理 / 非同期I/O
    • libspe関連をここに入れる(Scheme側bindingは用意しない)

これらのbindingはmoshではなくskySchemeの語彙で記述する。
Cの構造体からskyScheme記述に変換する奴を作る必要が有りそうだ。
skySchemeのメモリ管理は明示的であり、非GCオブジェクトを主に*2使う。逆にmosh側はGCオブジェクトを使うため、このギャップを埋める必要が有る。
skyScheme側でGCを使うことは出来ない。現在のところmoshGCはBoehm GCであり、GCが発動した場合数十〜百ms程度のworld stopが発生する。これはtimestampの精度を信頼できなくする*3

phase2 : stub libraryの生成とシリアライズ

moshは一旦ビルドすると内蔵変数を追加できないため、skymoshではsymbol-valueによって自身のバイナリ中に含まれる外部シンボルを読み取る。
もちろん、free-vars等を全て再生成する方向性も有り得る。この場合、gauche向けの作業スクリプトmoshに移植する必要が有る。

phase3 : ビルドスクリプトの生成とビルド

moshそのものでビルドすりゃいいという説もあるが、Windows上ではシェル周りの機能があまり信頼できないので、一旦スクリプトを出力する。

*1:LLVMは一旦見送った。SPE対応が絶妙なため。

*2:GCオブジェクトは、"ホストScheme"に依存している。以前は単純なヒープベースの自前Schemeを使用していたが、この部分をmoshに置き換えるように進めている。skySchemeのコードは、コンパイルされて実行される部分とホストSchemeで実行される部分に処理系によって分類される。

*3:もちろん、OSのpreemptionなどの問題もあるから、本来はGCを使わないことで解決するタイプの問題ではない。単に、受け入れ可能な誤差範囲に収まるか否かが重要と言える。parallel markingなどGC側の機能を活用する方向性も考えられるが。。