[armedbear-devel] Forward referenced classes woes
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/l... 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/l... 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.
Hi, Thanks for the nice report and diagnosis! Should be fixed in r14092, which also fixes two ansi-test failures and gets us one component further in compiling McCLIM. Rudi On Aug 11, 2012, at 16:20, Stas Boukarev <stassats@gmail.com> wrote:
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/l...
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/l... 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.
_______________________________________________ armedbear-devel mailing list armedbear-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
Rudolf Schlatte <rudi@constantly.at> writes:
Hi,
Thanks for the nice report and diagnosis! Should be fixed in r14092, which also fixes two ansi-test failures and gets us one component further in compiling McCLIM. Great, CXML now also compiles and works.
-- With best regards, Stas.
participants (2)
-
Rudolf Schlatte
-
Stas Boukarev