clos: replace macros by functions in with-early-accessors

Accessors are fuctions not macros. While using macros is fine in most
cases, we can't use them for example in higher-order functions. The
only reason this worked in the first place is due to our compiler
allowing expressions such as

`(macrolet ((x (...) ...)) (funcall #'x ...))

even though this is invalid.
This commit is contained in:
Marius Gerbershagen 2021-03-31 17:36:39 +02:00
parent 62d1bb1203
commit 9e204464ea

View file

@ -61,16 +61,19 @@
;;;
(eval-when (:compile-toplevel :execute)
(defmacro with-early-accessors ((&rest slot-definitions) &rest body)
`(macrolet
,(loop for slots in slot-definitions
nconc (loop for (name . slotd) in (if (symbolp slots)
(symbol-value slots)
slots)
for index from 0
for accessor = (getf slotd :accessor)
when accessor
collect `(,accessor (object) `(si::instance-ref ,object ,,index))))
,@body)))
(let (functions)
(loop for slots in slot-definitions
do (loop for (name . slotd) in (if (symbolp slots)
(symbol-value slots)
slots)
for index from 0
for accessor = (getf slotd :accessor)
when (and accessor (not (member accessor functions :key #'first)))
do (push `(,accessor (object) (si::instance-ref object ,index)) functions)
(push `((setf ,accessor) (value object) (si::instance-set object ,index value)) functions)))
`(flet ,functions
(declare (inline ,@(mapcar #'first functions)))
,@body))))
;;;
;;; The following macro is also used at bootstap for instantiating