From 9e204464eae5d6041e524750108b2d2ee39ef455 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Wed, 31 Mar 2021 17:36:39 +0200 Subject: [PATCH] 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. --- src/clos/std-slot-value.lsp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/clos/std-slot-value.lsp b/src/clos/std-slot-value.lsp index a0c4e54e1..662f170d6 100644 --- a/src/clos/std-slot-value.lsp +++ b/src/clos/std-slot-value.lsp @@ -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