作りかけの置換ランタイム

本当は完成させてから偉そうに書きたかったのですが、もうなんといいますか完全に私事で自業自得ですがそれどころではありませんので、書いちゃいます。

https://github.com/ytomino/drake

今までGNATについてあーだこーだ文句を書いたりコンパイラに勝手なパッチを当てて配布してたりしたのですが、そうした成果をひとつにまとめてランタイムに仕立ててしまおうという、私の誰得Ada趣味が極まったプロジェクトです。トータルで考えると何人年かけているのか自分でも怖い……。
D言語Phobosに対するTangoのような存在です。
はいあれだけ期待されていたTangoの末路を見ればこれがどうなるかも予想できますね?

……完全に私が自分で使うためだけに作っているのですが、それでも見ていただけると嬉しいので書き残しておきます。
使い方としては、ご存知のようにgccはデフォルトですと/usr/local/lib/gcc/i686-apple-darwin9みたいなパスにあるランタイムを使うのですが、都合のいいことにgnatmakeには--RTSというランタイムの位置を教えるオプションがあります。使い方はこう。

make -C (drakeのソースパス) RTSDIR=./myruntime
gnatmake --RTS=./myruntime -a hello.adb

本来はZCX例外版とSJLJ例外版みたいな使い分けのためのオプションですが、コンパイラの要求するパッケージや関数を満たしてさえすれば完全に別ランタイムを持ってきても動くという。ま、当然ですね。

gcc 4.5(--enable-langage=c,ada)とheadmaster(拙作。先日の記事参照。ビルドにはO'Caml 3.12.0も必要)の入ったOSXFreeBSD(また限定的な……)で、demoディレクトリで"make"するとサンプルが実際にビルドできる……と思います。たぶん。

いいとこ。

  • 100% pure witten by Adaです。headmaster偉い!(自画自賛です)
  • -bargs -Eでちゃんと例外発生箇所のスタックトレース出します。GNATランタイムと同じフォーマットです。(libaddr2line.aには未対応)
  • ZCX例外のぱーそなりてぃふぁんくしょんというやつは検索と実際のunwindで2回呼ばれるのですが、やることは同じですので1回目の結果を覚えていて2回目はサボってます。例外が少し速いはずです。(gcjのパクリ。未測定)
  • ソートは最近話題のin-placeマージソートです。くっ、実装した時点で記事を書いていれば……っ!(GNATランタイムはヒープソート)
  • 木はAA木です。(GNATランタイムは赤黒木)
  • 乱数はMT19937です。なんか最新版でSFMTとかいうのが公開されてますが見なかった。
  • 全般にわたってStringはUTF-8として扱います。UCDを抱えててTo_Upper等で全角文字も変換できます。(盛大に規格違反)*1
  • Ada.Wide_Text_IO, Ada.Wide_Wide_Text_IOがまともに動きます。LANGがUTF-8以外の環境?知らんな。
  • 入出力はstdio層を完全無視して直接システムコールを使います。termios等を使うときの面倒事が少ないです。CRLF問題は独自に処理してます。(GNATランタイムはstdio使用)
  • Ada.Directoriesがまともに動きます。(GNATランタイムは……)
  • Interfaces.C.wchar_tの定義がまともです。
  • Interfaces.C.PointersとInterfaces.C.Stringsを連携させるため勝手なことをしてます。
  • Adaパッケージの直下にDebug.Putというのを用意してまして、大抵のファイルはwith Ada.〜;しているでしょうから事実上どこからでもデバッグ出力が可能です。pragma Pure;も無視できます!超便利!
  • その他勝手な拡張多数。Delphi風インターフェース移譲もあるよ!
  • セカンダリスタックをmmapでページ単位で取ってきます。(GNATランタイムはmalloc)
  • GNATランタイムは環境変数を見て勝手に動作を変えたりするのですが、そういうことは一切しません!
  • GNATランタイムより2〜3割実行ファイルサイズが減ります!自分でも感動しました!でもよく考えたら未実装が多いので当たり前です!

ダメなとこ。

  • Ada.CalendarはCランタイムに投げてるだけですのでRMで要求されている全範囲(POSIX timeより広い)を扱えません!ダメダメです!
  • Ada.Strings以下はほとんど未実装です。めんどい。
  • task関連は全て未実装です。めんどい。必要な同期も一切していませんのでスレッド使わないでください。
  • その他いろいろ未実装です。めんどい。
  • gccのauto-vectorizationはAdaフロントエンドでは動きませんので(何故だ……)、100% pure written by Adaが仇となって行列関係はGNATランタイムより遅いはずです。(GNATランタイムはFortranのライブラリを呼んでます)
  • Windows(mingw)対応は未実装です。必要なコード片は溜まってるのですが、headmasterがWindows対応していません。なんでかといいますとO'Caml 3.12.0のWindows版が出ないからです。INRIAのせいです。(また刺されそうなことを……)

*1:規格ではStringはLatin-1。