X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fmop.impure.lisp;h=6015c6652f7b23b2773ec20d761fe0952f693805;hb=f77e81ba7736fc7df9ca7d37b93f662f36dae39f;hp=35118d0cabd825ec633f47883b51cb479a0abaa9;hpb=8f2883a6a64e8116ecddba619de2250e0e236efd;p=sbcl.git diff --git a/tests/mop.impure.lisp b/tests/mop.impure.lisp index 35118d0..6015c66 100644 --- a/tests/mop.impure.lisp +++ b/tests/mop.impure.lisp @@ -554,5 +554,128 @@ (with-test (:name :slow-method-is-fboundp) (assert (fboundp '(sb-pcl::slow-method wrapped (cons)))) (assert (eq :default (funcall #'(sb-pcl::slow-method wrapped (cons)) (list (cons t t)) nil)))) + +;;; Check that SLOT-BOUNDP-USING-CLASS doesn't confuse MAKE-INSTANCE +;;; optimizations. +(defclass sbuc-mio-test-class (standard-class) + ()) +(defmethod validate-superclass ((class sbuc-mio-test-class) + (superclass standard-class)) + t) +(defvar *sbuc-counter* 0) +(defmethod slot-boundp-using-class ((class sbuc-mio-test-class) + (object t) + (slot standard-effective-slot-definition)) + (incf *sbuc-counter*) + (call-next-method)) +(defclass sbuc-mio-test-object () + ((slot :initform 5 :accessor a-slot)) + (:metaclass sbuc-mio-test-class)) +(with-test (:name :sbuc-mio-test) + (assert (= 5 (funcall + (compile + nil + `(lambda () + (let ((object (make-instance 'sbuc-mio-test-object))) + (slot-value object 'slot))))))) + (assert (= 1 *sbuc-counter*))) + +;;; Redefining classes so that slot definition class changes. +(defclass func-slot-class (standard-class) + ()) + +(defmethod sb-mop:validate-superclass ((class func-slot-class) (super standard-class)) + t) + +(defclass func-slot-definition () + ((function :initform nil :initarg :function :reader slotd-function))) + +(defclass effective-func-slot-definition (sb-mop:standard-effective-slot-definition + func-slot-definition) + ()) + +(defclass direct-func-slot-definition (sb-mop:standard-direct-slot-definition + func-slot-definition) + ()) + +(defmethod sb-mop:slot-value-using-class ((class func-slot-class) + instance + (slotd effective-func-slot-definition)) + (funcall (slotd-function slotd) (call-next-method))) + +(defvar *func-slot*) + +(defmethod sb-mop:effective-slot-definition-class ((class func-slot-class) &key) + (if *func-slot* + (find-class 'effective-func-slot-definition) + (call-next-method))) + +(defmethod sb-mop:direct-slot-definition-class ((class func-slot-class) &key) + (find-class 'direct-func-slot-definition)) + +(defmethod sb-mop:compute-effective-slot-definition ((class func-slot-class) name dslotds) + (let* ((*func-slot* (some #'slotd-function dslotds)) + (slotd (call-next-method))) + (when *func-slot* + (setf (slot-value slotd 'function) (fdefinition *func-slot*))) + slotd)) + +(with-test (:name :class-redefinition-changes-custom-slot-type) + (eval `(defclass func-slot-object () + ((foo :initarg :foo :reader foofoo)) + (:metaclass func-slot-class))) + (let ((x (cons t t))) + (assert (eq x (foofoo (make-instance 'func-slot-object :foo x))))) + (eval `(defclass func-slot-object () + ((foo :initarg :foo :reader foofoo :function car)) + (:metaclass func-slot-class))) + (let* ((x (cons t t)) + (y (list x))) + (assert (eq x (foofoo (make-instance 'func-slot-object :foo y)))))) + +(with-test (:name :class-redefinition-changes-custom-slot-type-mio) + (eval `(defclass func-slot-object2 () + ((foo :initarg :foo :reader foofoo)) + (:metaclass func-slot-class))) + (let* ((x (cons t t)) + (y (cons x x)) + (o (make-instance 'func-slot-object2 :foo y))) + (assert (eq y (foofoo o))) + (eval `(defclass func-slot-object2 () + ((foo :initarg :foo :reader foofoo :function car)) + (:metaclass func-slot-class))) + (assert (eq x (foofoo o))))) + +(defclass class-slot-removal-test () + ((instance :initform 1) + (class :allocation :class :initform :ok))) + +(defmethod update-instance-for-redefined-class ((x class-slot-removal-test) added removed plist &rest inits) + (throw 'update-instance + (list added removed plist inits))) + +(with-test (:name :class-redefinition-removes-class-slot) + (let ((o (make-instance 'class-slot-removal-test))) + (assert (equal '(nil nil nil nil) + (catch 'update-instance + (eval `(defclass class-slot-removal-test () + ((instance :initform 2)))) + (slot-value o 'instance)))))) + +(defclass class-slot-add-test () + ((instance :initform 1))) + +(defmethod update-instance-for-redefined-class ((x class-slot-add-test) added removed plist &rest inits) + (throw 'update-instance + (list added removed plist inits))) + +(with-test (:name :class-redefinition-adds-class-slot) + (let ((o (make-instance 'class-slot-add-test))) + (assert (equal '(nil nil nil nil) + (catch 'update-instance + (eval `(defclass class-slot-add-test () + ((instance :initform 2) + (class :allocation :class :initform :ok)))) + (slot-value o 'instance)))))) ;;;; success