目指せギリギリ最少Scheme on Scheme の1 - オブジェクト表現とヒープ
これC言語で普通に書くよりも圧倒的に面倒な気がしてきた。。
メモリ表現
GC対象のメモリとして、pointerのvectorを使うことにした。これをcellと呼ぶ。cellは本来的にはより大きいサイズにする必要があるので、cellの大きさ != オブジェクトの大きさにできるようにしておく必要がある。(cellのような割り当て単位はキャッシュラインにalignされる事が望ましい。つまり、16bytesやそれ以上の倍数になる。)
普通、cellは固定長のメモリ領域を指すことが多い気がする。悪い命名。
この部分は、あとでC言語で実装する。I/Oと浮動小数点はまだ実装していない。まぁそのうち。
cellは整数個のpointerで構成される。このため、バイト単位の読み書きは手でpack/unpackしてやる必要が有る。
オブジェクト表現
オブジェクトは2種類に大別される:
- 1ワードに収まるオブジェクト
- nil / true / false / eof-object等の特殊オブジェクト
- char
- 1ワードで収まらないので、ヒープ領域を確保してワードにはポインタを入れる
オブジェクトは、ぼくのScheme実装に有りがちな、zone0/zone1/fixnum/heap-objectの4分類にしている。このため、まず、この4分類実装を先に用意し、
その上にオブジェクトシステムを実装している。
既に、現段階で、consやstring-refのような代表的な操作は揃えている。
"ホスト"Schemeとのやりとり
"ホスト"schemeと"ターゲット"Schemeの区別を導入する。今回、ホストSchemeはnmoshで、ターゲットSchemeは今回実装しているSchemeになる。
このとき、ホストSchemeとターゲットSchemeでオブジェクトをやりとりすることを考えておく必要がある。ターゲットSchemeがコードをloadして実行出来るようになるよりも前に、ホストSchemeを使ってオブジェクトシステムのテストを進めることができる。
ホストSchemeのオブジェクトを再帰的にターゲットSchemeのオブジェクトに変換するimportと、その逆を行うexportを用意する。
こうすることで、
oku@cage ~/repos/r7c $ nmosh nmosh top program nmosh> (import (emul helper export)) nmosh> (export #x1234) #<pointer 0x2468> nmosh>
のようにして、実装したオブジェクトシステムを動作させることが出来る。今回はfixnumで0x1234を表現してみた。今回のオブジェクトシステムでは、fixnumは左に1bitシフトしてゼロを入れるので、pointerの値としては単純に2倍したように見える。
というわけで(flonumとbytevectorを除いて)オブジェクトシステムは揃ったので、これからは普通のScheme on Schemeで手続きを充実させていく。