Posted 2020-12-23 02:46:42 GMT
allocate-instance Advent Calendar 2020 23日目の記事です。
引き続き、allocate-instance
が関係してくるInstance Structure Protocol(ISP)周りを中心に色々なCLOS MOP系の処理系で確認していきたいと思います。
今回は、TELOSのallocate-instance
周りを眺めます。
TELOSは、EuLispのオブジェクトシステムで、EuLispもCommon Lispより簡潔な作りを指向しています。
EuLispとCommon Lispとの目立った違いは、EuLispがLisp1であることで、クラスの表記も他のシンボルと競合しないように、<foo>
のように表記する慣習があります。
ちなみに、ISLISPは、EuLispの影響下にあるので、Lisp2なのに<foo>
と表記します。
allocate
make
initialize
まず、インスタンスの構成ですが、class
、slots
という二つの部分からなるprimitive-class
構造体で表現されています。CLOSの実装でいうとwrapper部は、そのままクラスメタオブジェクトで表現されています。
インスタンスのストレージは標準でベクタ。
スロットストレージへは、primitive-class-slots
、wrapperの取り出しは、primitive-class-of
で行えますが、クラスそのものなので別に必要ないかも?
CLOS MOPと異なる点としては、クラスがスロット数を保持するclass-instance-length
を有します。
slot-value
(setf slot-value)
primitive-slot-value
(setf primitive-slot-value)
slot-value-using-slot
find-slot
slot-reader
slot-writer
compute-slots
primitive-ref
setter-primitive-ref
primitive-find-slot-position
スロットストレージの並び順は、CLと同様compute-slots
で確定するようです。
CLOSのslot-definition
に相当する<slot>
クラスがあり、class-slots
に格納されていますが、スロットの位置を計算するには、primitive-find-slot-position
を使います。
特に最適化はされておらず、class-slots
の中を順に探しているだけです。
(primitive-find-slot-position <simple-class> 'c (class-slots <foo>) 0)
→ 2
CLのstandard-instance-access
に相当するものは、primitive-ref
になります。
slot-value
の中で、標準のメタクラスかどうかを判定するようになっており、標準であれば、slot-value-using-slot
が、スロットのslot-reader
/writer
を呼び出しを値を取り出します。
slot-reader
は最終的にはprimitive-ref
を呼びます。
slot-value
は
(slot-value-using-slot (find-slot (class-of obj) name)
obj)
と展開されるので、何もしなければ、find-slot
が探索してスロット名→スロット位置の変換をするので遅いですが総称関数なので(find-slot obj 'a)
等を特定化して定義してやれば高速化はできそうです。
CLOS系OOPSでスロット名からスロットの位置を割り出す方法にそれぞれ色々と工夫があるようです。
アクセサに比べてslot-value
の方がプリミティブな雰囲気があり、速度もアクセサより速そうな印象がありますが、MOPの仕組みからして、スロットの位置割り出しが計算済みの分アクセサの方が速いですね。
■
HTML generated by 3bmd in LispWorks 7.0.0