poor man's rubyの詳細

yarv-devに投稿したものに加筆しています。

fixnumに泣いてもらってfixnumの領域に押し込むようにしました。fixnumは30bitを越えるとbignumになってしまいます。
フォーマットは

   xxxxxxxxxxxxxxxxxxxxxxxxxxxx11   FIXNUM
   xxxxxxxxxxxxxxxxxxxxxxxxxxxx01   FIXFLOAT

となります。FIXFLOATは矛盾に満ちた名前なのですが、個人的にしっくり来るので使っています。何かいい名前があったら教えてください。

後は、ほとんどのFLOATはRFLAOT(var)->valueでアクセスしている様ですが、これをRFLOAT_VALUE(var)で置き換えます。*1
RFLOAT_VALUE(var)は次のような定義です。

 #define RFLOAT_VALUE(obj) ((FIXFLOAT_P(obj)) ? rb_value2float(obj) : (RFLOAT(obj)->value)) 

後は、insns.defなどにFIXFLOATの為の分岐を追加したりしています。

後、問題になるのが、object idです。object idは正式版のものは、すべてのオブジェクトをFIXNUMに変換しますが、*2 poor man's rubyでは、FIXNUM又はFIXFLOATに変換します。
FIXNUMに変換しようとすると、ポインタを8bytesアライメントにする必要があり、poor man's になりません。そこで、poor man's rubyではobject idの変換については、FIXNUMの変換とは異なり、通常のrubyと同じ変換方法(1bit左シフトして最下位ビットを1にする)を使っています。こうすると、object idがFLOATになってしまうという妙なことが起きますが、ちゃんとObjectSpace._id2refは動きますし、object idを操作するようなことは無いので問題ないと思います。

なお、通常のFLOATのフォーマットをFIXFLOATに変換するプログラムは笹田さんの作成したものをそのまま使っています。

*1:その後、正式版もRFLOAT_VALUEでアクセスするように変わっています

*2: 大きなFIXNUMはBIG NUMに変換する場合もある