X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ffdefinition.lisp;h=a23c0e4886c31617482cc14f363e528f103733a1;hb=cd1b14acf6f548b28b8a14e554d779f0473122ec;hp=f4bd831260a90fb44ead560dcac8e75c53597319;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/fdefinition.lisp b/src/code/fdefinition.lisp index f4bd831..a23c0e4 100644 --- a/src/code/fdefinition.lisp +++ b/src/code/fdefinition.lisp @@ -60,6 +60,10 @@ (setf (info :function :definition name) (make-fdefn name)) fdefn))) +(defun maybe-clobber-ftype (name) + (unless (eq :declared (info :function :where-from name)) + (clear-info :function :type name))) + ;;; Return the fdefinition of NAME, including any encapsulations. ;;; The compiler emits calls to this when someone tries to FUNCALL ;;; something. SETFable. @@ -69,6 +73,7 @@ (or (and fdefn (fdefn-fun fdefn)) (error 'undefined-function :name name)))) (defun (setf %coerce-name-to-fun) (function name) + (maybe-clobber-ftype name) (let ((fdefn (fdefinition-object name t))) (setf (fdefn-fun fdefn) function))) @@ -120,18 +125,16 @@ ;;; This is like FIND-IF, except that we do it on a compiled closure's ;;; environment. -(defun find-if-in-closure (test fun) - (declare (type function test)) - (dotimes (index (1- (get-closure-length fun))) - (let ((elt (%closure-index-ref fun index))) - (when (funcall test elt) - (return elt))))) +(defun find-if-in-closure (test closure) + (declare (closure closure)) + (do-closure-values (value closure) + (when (funcall test value) + (return value)))) ;;; Find the encapsulation info that has been closed over. (defun encapsulation-info (fun) - (and (functionp fun) - (= (widetag-of fun) sb!vm:closure-header-widetag) - (find-if-in-closure #'encapsulation-info-p fun))) + (when (closurep fun) + (find-if-in-closure #'encapsulation-info-p fun))) ;;; When removing an encapsulation, we must remember that ;;; encapsulating definitions close over a reference to the @@ -235,6 +238,24 @@ "Set NAME's global function definition." (declare (type function new-value) (optimize (safety 1))) (with-single-package-locked-error (:symbol name "setting fdefinition of ~A") + (maybe-clobber-ftype name) + + ;; Check for hash-table stuff. Woe onto him that mixes encapsulation + ;; with this. + (when (and (symbolp name) (fboundp name) + (boundp '*user-hash-table-tests*)) + (let ((old (symbol-function name))) + (declare (special *user-hash-table-tests*)) + (dolist (spec *user-hash-table-tests*) + (cond ((eq old (second spec)) + ;; test-function + (setf (second spec) new-value)) + ((eq old (third spec)) + ;; hash-function + (setf (third spec) new-value)))))) + + ;; FIXME: This is a good hook to have, but we should probably + ;; reserve it for users. (let ((fdefn (fdefinition-object name t))) ;; *SETF-FDEFINITION-HOOK* won't be bound when initially running ;; top level forms in the kernel core startup.