Posted 2020-12-21 20:53:44 GMT
allocate-instance Advent Calendar 2020 22日目の記事です。
前回に引き続き、allocate-instance
が関係してくるInstance Structure Protocol(ISP)周りを中心に色々なCLOS MOP系の処理系で確認していきたいと思います。
今回は、MCSのallocate-instance
周りを眺めます。
まず、MCSですが、The Meta Class Systemの略で、ObjVlispの流れをくみつつCLOSとの互換性も高いシステムです。
MOPも大体同じような構成になっていますが、MCSの方がシンプルでありつつ抽象クラスやmixinクラス等も用意されていて色々整理されているようにも見えます。
allocate-instance
make-instance
initialize-instance
change-class
change-class-using-class
さてまず、インスタンスの構成ですが、isit
、slots
という二つの部分からなる構造体で表現されています。isit
というのはCLOSの実装でいうとwrapperですが、クラスメタオブジェクトを一つ含んだリストで表現されていて、wrapperとclassのオブジェクトがほぼ一本化されています。
インスタンスのストレージは標準ではベクタです。
スロットストレージへは、mcs%-slots
、wrapperの取り出しは、mcs%-isit
で行えます。
CLOS MOPと異なる点として、スロット名から、スロットストレージの位置を割り出す関数がクラスの中に格納されている点で、標準では、general-slot-position
関数が、class-slot-accessor
に格納されています。
slot-exists-p
slot-boundp
slot-makunbound
slot-value
mcs%slot-value
(setf slot-value)
mcs%set-slot-value
mcs%set-slot-value-low
compute-slots
mcs%local-slot-indexed
mcs%local-slot-indexed-low
スロットストレージの並び順は、CLと同様compute-slots
で確定するようです。
スロットの位置を計算する関数がクラスに含まれているので、slot-definition-location
は存在せず、%slot-location-of
が位置計算用関数を呼び出して計算します。
CLのstandard-instance-access
に相当するものは、mcs%local-slot-indexed-low
になりますが、slot unboundのサポートありのmcs%local-slot-indexed
も用意されています。
CLと違ってslot-value
はマクロになっており、slot-value-using-
系メソッドはなく、mcs%slot-value
に展開か、メソッド内部での最適化として、mcs%local-slot-indexed-low
を用いたアクセスになるよう展開するようです(なお実装ではそこまで最適化されていない)
mcs%slot-value
は、上述のスロット位置を名前から割り出す関数を呼び出して、インスタンスのストレージを添字でアクセスします。
なお、-low
が掴ないものは、slot unboundをサポートせずslot missingのみサポートします。
MCSではslot-value-using-class
が省略されていますが、その代わりにクラスがスロット名→ストレージの位置の変換関数を保持するというのが面白いと思いました。
この辺りの方式の違いをそのうち比較してみたいところです。
■
HTML generated by 3bmd in LispWorks 7.0.0