On Tue, Jul 22, 2008 at 12:36 PM, Christophe Rhodes <csr21@...> wrote:
> John Morrison <morrison@...> writes:
>
>> I am trying to build PowerLoom, available at:
>>
>> http://www.isi.edu/isd/LOOM/PowerLoom/download.html
>>
>> with recent SBCL (built from CVS) Linux, and getting an error when
>> loading PowerLoom proper (sbcl --load load-powerloom.lisp). I am
>> having trouble figuring out how to work around it.
>>
>> I have also been told "it looks like a problem with the compiler," and
>> advised to switch to CMUCL, which is one of their supported platforms,
>> but I figured I'd give it the old college try and report the error.
>
> Thank you! It is indeed a problem with the compiler; I would imagine
> that for you the short-term workaround is indeed to use a supported
> platform for PowerLoom.
>
> Otherwise, your report was fine, thanks! I can't fix it now, but I
> have reduced the problem to a stand-alone test case: compiling a file
> with the following contents:
>
> (defvar null-float)
> (defstruct (foo (:constructor %make-foo ()))
> (x null-float :type double-float))
>
> gives the same error in the compiler. (I hope this might help others
> track down the problem.)
This is my fault. The workaround is to make the initialization form
(the double-float null-float)
and real fix is to make the DEFSTRUCT machinery do the equivalent
automatically -- approximately like this:
(in-package :sb-kernel)
(defun create-structure-constructor (dd cons-name arglist vars types values)
;; The difference between the two implementations here is that on all
;; platforms we don't have the appropriate RAW-INSTANCE-INIT VOPS, which
;; must be able to deal with immediate values as well -- unlike
;; RAW-INSTANCE-SET VOPs, which never end up seeing immediate values. With
;; some additional cleverness we might manage without them and just a single
;; implementation here, though -- figure out a way to ensure that on those
;; platforms we always still get a non-immediate TN in every case...
;;
;; Until someone does that, this means that instances with raw slots can be
;; DX allocated only on platforms with those additional VOPs.
#!+raw-instance-init-vops
(let* ((slot-values nil)
(slot-specs
(mapcan (lambda (dsd value)
(unless (eq value '.do-not-initialize-slot.)
(push `(the ,(dsd-type dsd) ,value) slot-values)
(list (list* :slot (dsd-raw-type dsd) (dsd-index dsd)))))
(dd-slots dd)
values)))
`(defun ,cons-name ,arglist
(declare ,@(mapcar (lambda (var type) `(type ,type ,var)) vars types))
(%make-structure-instance-macro ,dd ',slot-specs ,@(reverse
slot-values))))
#!-raw-instance-init-vops
(let ((instance (gensym "INSTANCE")) slot-values slot-specs
raw-slots raw-values)
(mapc (lambda (dsd value)
(unless (eq value '.do-not-initialize-slot.)
(let ((raw-type (dsd-raw-type dsd)))
(cond ((eq t raw-type)
(push `(the ,(dsd-type dsd) value) slot-values)
(push (list* :slot raw-type (dsd-index dsd)) slot-specs))
(t
(push value raw-values)
(push dsd raw-slots))))))
(dd-slots dd)
values)
`(defun ,cons-name ,arglist
(declare ,@(mapcar (lambda (var type) `(type ,type ,var)) vars types))
,(if raw-slots
`(let ((,instance (%make-structure-instance-macro ,dd
',slot-specs ,@slot-values)))
,@(mapcar (lambda (dsd value)
;; (Note that we can't in general use the
;; ordinary named slot setter function here
;; because the slot might be :READ-ONLY, so we
;; whip up new LAMBDA representations of slot
;; setters for the occasion.)
`(,(slot-setter-lambda-form dd dsd) ,value ,instance))
raw-slots
raw-values)
,instance)
`(%make-structure-instance-macro ,dd ',slot-specs ,@slot-values)))))
Cheers,
-- Nikodemus
|