Ruby2.1.0-preview1

今年の12/25リリース予定であるRuby2.1.0のpreview1が出たのでDXRubyをそのままコンパイルして動くかどうかを試してみた。
Ruby2.1ではGCが世代別GCになって、本来であれば拡張ライブラリは修正が必要になるもんなのだが、そこはうまいこと細工してそのままでも動くようになっている。従って、DXRubyもそのままで動くはずだ。だった。

とりあえずRubyをVCでmakeして、DXRubyをコンパイルしようとしたらextconfが動かなかった。win32.hがインストールディレクトリにコピーされていないのが原因で、このへんは何かビルド時にオプション指定が必要だったのかもしれないので手でコピーしてお茶を濁す(面倒なので調べない)。
DXRubyのコンパイルはそれでうまくいったのだが、install.rbを動かしたらシェーダ描画のところでコケた。

install.rb:102: [BUG] rb_id_attrset: ATTRSET ID - 20492

だそうだ。Rubyのrb_id_attrset()は引数で渡したIDをSetterにしてくれる。IDがaというメソッド名を表していた場合、rb_id_attrset()にそれを渡すとa=のIDが返ってくるという感じだと思う。実際には=がついているかどうかはフラグで持っているようだ。Rubyのparse.yにあるので眺めていると、どうも=がつけられないIDはエラーになるような雰囲気である。2.0のソースを見るとこのエラーチェックは無いので2.1で追加されたらしい。
DXRubyではShaderオブジェクトを生成するときに引数のShader::Coreの情報をもとに特異メソッドを作るが、どうもそのSetter側の処理が問題になっている。rb_frame_this_func()の戻り値をrb_id_attrset()に渡しているところでコケているようだ。rb_frame_this_func()はよくわからないのだが現在のメソッドの名前が取得できるようで、Setter内で呼んだら=付きのIDが返ってくるはずなので、これをrb_id_attrset()に渡しちゃってるのが原因なんじゃないかと。処理としてはフラグを立てているだけで、2.0までは立っているフラグをさらに立てるだけだったから問題なく動いていただけで、よろしくない実装になっていたという話だ。
んでrb_id_attrset()を呼ばなくしたら動くようになった。いくつかのスクリプトを動かしてみたが、まあ、とりあえず動いているようなので基本的にはOKである。

今後としては、一通りの機能が動くかどうかの確認をしつつ、うちの環境にFiddleが無いからWSが動かなくて、これをどうにかして確認するのと、あとパフォーマンスの計測と。
んで、大きな問題として現状のDXRuby1.4.0はRuby2.1用にコンパイルできない状態であるわけで、この部分をどうにかする必要がある。1.4.1を出すなら1.5devからのバックポートの選択や品質の確認が必要だし、2.1対応というならRGenGC対応にしておきたいところで、そっち方面はまったくまだ手をつけてないわけで、なんだかんだと手をつける範囲が広くなってしまいそうである。
いまいち感覚的につかめない点としては、RGenGCへの対応はしなくても動くがすれば速くなるという点で、対応しなかった場合に2.0と比較して速いのか遅いのか、である。計測してみるしかない。妄想レベルではDXRubyが扱うオブジェクト数程度ならShadyになっててもたいした影響は無いのではないかと思うのだが、まあ、妄想で決断できるものでもなく。
しばらくそのへん調べつつ考えてみることにする。