[armedbear-devel] Forward referenced classes woes

Stas Boukarev stassats at gmail.com
Sat Aug 11 14:20:35 UTC 2012


Consider the following code:

(defclass whitespace-normalizer (sax-proxy))

(defclass sax-proxy (broadcast-handler)
  ())

(defclass broadcast-handler ()
  ((handlers :initform nil
	     :initarg :handlers
	     :accessor broadcast-handler-handlers)))

Doing the followoing results in errors:

(setf (broadcast-handler-handlers (make-instance 'whitespace-normalizer)) 10)

There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION (SETF BROADCAST-HANDLER-HANDLERS)
{6621477C}> when called with arguments (10 #<WHITESPACE-NORMALIZER
{14BAAEA8}>).

(setf (broadcast-handler-handlers (make-instance 'sax-proxy)) 10) 

The slot HANDLERS is missing from the class #<STANDARD-CLASS SAX-PROXY
{1700FFDB}>.

The problem is that whitespace-normalizer and sax-proxy are
finalized too early.

Finalization happens in std-after-initialization-for-classes
http://trac.common-lisp.net/armedbear/browser/trunk/abcl/src/org/armedbear/lisp/clos.lisp#L857

by calling maybe-finalize-class-subtree, which in its turn finalizes the
class and its subclasses in case the class has all its superclasses
finalized.

When (defclass whitespace-normalizer (sax-proxy)) is executed it creates
a forward-referenced-class for sax-proxy, and when sax-proxy is defined
it calls a method for ensure-class-using-class
http://trac.common-lisp.net/armedbear/browser/trunk/abcl/src/org/armedbear/lisp/clos.lisp#L3121
for forward-referenced-classes. Before calling reinitialize-instance it
does (change-class class metaclass) to change from forward-referenced to
normal class. change-class in its turn calls shared-initialize method,
which calls the aforementioned std-after-initialization-for-classes, but
it doesn't supply any direct-superclass arguments. So, when
maybe-finalize-class-subtree is called it thinks that sax-proxy's sole
superclass is standard-object, so it goes ahead finalizing sax-proxy and
whitespace-normalizer at the wrong time with wrong information. And
ensure-class-using-class later call with the right direct-superclass
information doesn't matter anymore, since the classes were already badly
finalized 

-- 
With best regards, Stas.




More information about the armedbear-devel mailing list