週刊mosh - set-current-error-port! / 深いpathのサポート

Darwinでnmoshがビルドできない問題があるらしい( http://d.hatena.ne.jp/higepon/20120109/1326112107 )。
コメントにも書いたけれど、nmoshのビルドはmoshのbootstrapのうちでも非常に負荷の高い処理で、32bitシステム上でのCygwinのようにメモリ要件が厳しいところだと常に失敗する可能性がつきまとっている。実際、0.2.6でnmosh本体のデバッグ情報をnmoshに含まなくなったのはCygwinでビルドできなくなったことも一因。
手元ではまだ再現できていない(絶対に起動しないか、正常にbootstrapできるかの二択で、中間にならない)。

set-current-error-port!の追加

従来は、set-current-input-port!とset-current-output-port!しか無かった。今回、set-current-error-port!を追加することで、root VMのエラーポートを自前のポートに変更できるようになった。
(一応、従来からMulti-VMVMはエラーポートを指定することができたが。。)
この機能はnmoshのGUI REPLで使用される予定。つまり、GUIコンソールにVMの出力をリダイレクトできる。
set-current-error-port!は他のライブラリからはexportされていないので、nmoshでのみ使用できる。

深いpathのサポート

moshやnmoshはVMバイトコードをキャッシュすることで起動の高速化を図っている。これはPythonだとライブラリの*.pycファイルに相当する。
Pythonと違うのは2点で、

  • moshはライブラリだけでなくユーザプログラムもキャッシュする
  • キャッシュはHOMEディレクトリにまとめて行われる (Pythonのキャッシュはライブラリファイルと同じ位置にセーブされる)

という違いがある。
特にnmoshはWin32をサポートしていて、かつ、キャッシュを常にフルパスで管理するため、パス長がMAX_PATHを越える位置にあるファイルを絶対に実行できないという地味な問題があった(従来は--disable-accのようなキャッシュ無効オプションが唯一の回避策だった)。
他の常識的なOSと異なり、Win32のMAX_PATHは260文字しか無いので、かなり簡単にこの制限を超えてしまう。
というわけで2つの対策を導入した。

  • ライブラリパスの解決とキャッシュシステムは常にWin32拡張パス("\\?\"で始まるパス)を使う
  • 長すぎるキャッシュ名は適当に切り詰める

適当に切り詰めたファイル名は当然衝突する可能性があるが、これは真のフルパスをキャッシュデータに格納することで衝突を検出できるようにした。