1.0.24.2: CONSTANTP aware GET-SETF-EXPANDER
authorNikodemus Siivola <nikodemus@random-state.net>
Fri, 2 Jan 2009 11:14:27 +0000 (11:14 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Fri, 2 Jan 2009 11:14:27 +0000 (11:14 +0000)
 * Or rather GET-SETF-METHOD-INVERSE -- check for constant arguments,
   which don't need to be rebound. This allows compiler macros for
   SETF-functions to see their constant arguments.

 * This exposes a small thinko in ACCESSOR-VALUES-INTERNAL (something
   gets optimized during PCL build which wasn't before): EARLY-P there
   doesn't mean the method is early.

NEWS
src/code/early-setf.lisp
src/pcl/dfun.lisp
tests/setf.impure.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 6b3c2b9..ef00da9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,10 @@ changes in sbcl-1.0.25 relative to 1.0.24:
   * improvement: reading from a TWO-WAY-STREAM does not touch the output
     stream anymore making it thread safe to have a concurrent reader and
     a writer, for instance, in a pipe.
+  * improvement: GET-SETF-EXPANDER avoids adding bindings for constant
+    arguments, making compiler-macros for SETF-functions able to inspect
+    their constant arguments.
+
 changes in sbcl-1.0.24 relative to 1.0.23:
   * new feature: ARRAY-STORAGE-VECTOR provides access to the underlying data
     vector of a multidimensional SIMPLE-ARRAY.
index 1487215..b1d583f 100644 (file)
@@ -41,7 +41,7 @@
                (sb!xc:macroexpand-1 form environment)
              (if expanded
                  (sb!xc:get-setf-expansion expansion environment)
-                 (let ((new-var (gensym)))
+                 (let ((new-var (gensym "NEW")))
                    (values nil nil (list new-var)
                            `(setq ,form ,new-var) form)))))
           ;; Local functions inhibit global SETF methods.
@@ -53,7 +53,7 @@
                       (return t)))))
            (expand-or-get-setf-inverse form environment))
           ((setq temp (info :setf :inverse (car form)))
-           (get-setf-method-inverse form `(,temp) nil))
+           (get-setf-method-inverse form `(,temp) nil environment))
           ((setq temp (info :setf :expander (car form)))
            ;; KLUDGE: It may seem as though this should go through
            ;; *MACROEXPAND-HOOK*, but the ANSI spec seems fairly explicit
@@ -100,21 +100,29 @@ GET-SETF-EXPANSION directly."
         (sb!xc:get-setf-expansion expansion environment)
         (get-setf-method-inverse form
                                  `(funcall #'(setf ,(car form)))
-                                 t))))
+                                 t
+                                 environment))))
 
-(defun get-setf-method-inverse (form inverse setf-fun)
-  (let ((new-var (gensym))
+(defun get-setf-method-inverse (form inverse setf-fun environment)
+  (let ((new-var (gensym "NEW"))
         (vars nil)
-        (vals nil))
-    (dolist (x (cdr form))
-      (push (gensym) vars)
-      (push x vals))
-    (setq vals (nreverse vals))
-    (values vars vals (list new-var)
+        (vals nil)
+        (args nil))
+    (dolist (x (reverse (cdr form)))
+      (cond ((sb!xc:constantp x environment)
+             (push x args))
+            (t
+             (let ((temp (gensym "TMP")))
+               (push temp args)
+               (push temp vars)
+               (push x vals)))))
+    (values vars
+            vals
+            (list new-var)
             (if setf-fun
-                `(,@inverse ,new-var ,@vars)
-                `(,@inverse ,@vars ,new-var))
-            `(,(car form) ,@vars))))
+                `(,@inverse ,new-var ,@args)
+                `(,@inverse ,@args ,new-var))
+            `(,(car form) ,@args))))
 \f
 ;;;; SETF itself
 
index c9bdfc3..37002f9 100644 (file)
@@ -1235,13 +1235,8 @@ Except see also BREAK-VICIOUS-METACIRCLE.  -- CSR, 2003-05-28
                                            (class-precedence-list
                                             accessor-class))
                                        :test #'eq)
-                               (if early-p
-                                   (not (eq *the-class-standard-method*
-                                            (early-method-class meth)))
-                                   (accessor-method-p meth))
-                               (if early-p
-                                   (early-accessor-method-slot-name meth)
-                                   (accessor-method-slot-name meth))))))
+                               (accessor-method-p meth)
+                               (accessor-method-slot-name meth)))))
          (slotd (and accessor-class
                      (if early-p
                          (dolist (slot (early-class-slotds accessor-class) nil)
index 0b8a867..cd13d8d 100644 (file)
                    (declare (ignore env))
                    `(set-foo ,foo ,new)))))
 
+;;; Not required by the spec, but allowes compiler-macros for SETF-functiosn
+;;; to see their constant argument forms.
+(with-test (:name constantp-aware-get-setf-expansion)
+  (multiple-value-bind (temps values stores set get)
+      (get-setf-expansion '(foo 1 2 3))
+    (assert (not temps))
+    (assert (not values))
+    (assert (equal `(funcall #'(setf foo) ,@stores 1 2 3) set))
+    (assert (equal '(foo 1 2 3) get))))
+
 ;;; success
index 61bdc6d..1ee247d 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.24.1"
+"1.0.24.2"