X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fpcl%2Ffixup.lisp;h=d4e0257fa61d7ae5ba7a35a44cebe48a48d305a3;hb=a2fd28fb6d0b3d8d230a7c933db352f80891ac1c;hp=b7b4f21f05cfb6d81f4a64d0b2dbb42c8f37ac79;hpb=0ee1135a83da462e6de2a98bb2eff837b278f926;p=sbcl.git diff --git a/src/pcl/fixup.lisp b/src/pcl/fixup.lisp index b7b4f21..d4e0257 100644 --- a/src/pcl/fixup.lisp +++ b/src/pcl/fixup.lisp @@ -26,24 +26,59 @@ (!fix-early-generic-functions) (!fix-ensure-accessor-specializers) (compute-standard-slot-locations) -(dolist (s '(condition structure-object)) - (dohash (k v (classoid-subclasses (find-classoid s))) +(dolist (s '(condition function structure-object)) + (dohash ((k v) (classoid-subclasses (find-classoid s))) (find-class (classoid-name k)))) -(setq *boot-state* 'complete) +(setq **boot-state** 'complete) (defun print-std-instance (instance stream depth) (declare (ignore depth)) (print-object instance stream)) -;;; Access the slot-vector created by MAKE-SLOT-VECTOR. -(defun find-slot-definition (class slot-name) - (declare (symbol slot-name) (inline getf)) - (let* ((vector (class-slot-vector class)) - (index (rem (sxhash slot-name) (length vector)))) - (declare (simple-vector vector) (index index)) - (do ((plist (svref vector index) (cdr plist))) - ((not plist)) - (let ((key (car plist))) - (setf plist (cdr plist)) - (when (eq key slot-name) - (return (car plist))))))) +(setf (compiler-macro-function 'slot-value) nil) +(setf (compiler-macro-function 'set-slot-value) nil) + +(in-package "SB-C") + +(defknown slot-value (t symbol) t (any)) +(defknown sb-pcl::set-slot-value (t symbol t) t (any)) + +(deftransform slot-value ((object slot-name) (t (constant-arg symbol)) * + :node node) + (let ((c-slot-name (lvar-value slot-name))) + (if (sb-pcl::interned-symbol-p c-slot-name) + (let* ((type (lvar-type object)) + (dd (when (structure-classoid-p type) + (find-defstruct-description + (sb-kernel::structure-classoid-name type)))) + (dsd (when dd + (find c-slot-name (dd-slots dd) :key #'dsd-name)))) + (cond (dsd + `(,(dsd-accessor-name dsd) object)) + (t + (delay-ir1-transform node :constraint) + `(sb-pcl::accessor-slot-value object ',c-slot-name)))) + (give-up-ir1-transform "slot name is not an interned symbol")))) + +(deftransform sb-pcl::set-slot-value ((object slot-name new-value) + (t (constant-arg symbol) t) + * :node node) + (let ((c-slot-name (lvar-value slot-name))) + (if (sb-pcl::interned-symbol-p c-slot-name) + (let* ((type (lvar-type object)) + (dd (when (structure-classoid-p type) + (find-defstruct-description + (sb-kernel::structure-classoid-name type)))) + (dsd (when dd + (find c-slot-name (dd-slots dd) :key #'dsd-name)))) + (cond (dsd + `(setf (,(dsd-accessor-name dsd) object) new-value)) + ((policy node (= safety 3)) + ;; Safe code wants to check the type, and the global + ;; accessor won't do that. Also see the comment in the + ;; compiler-macro. + (give-up-ir1-transform "cannot use optimized accessor in safe code")) + (t + (delay-ir1-transform node :constraint) + `(sb-pcl::accessor-set-slot-value object ',c-slot-name new-value)))) + (give-up-ir1-transform "slot name is not an interned symbol"))))