(legal-fun-name-or-type-error name)
(let ((fdefn (info :function :definition name)))
(if (and (null fdefn) create)
(legal-fun-name-or-type-error name)
(let ((fdefn (info :function :definition name)))
(if (and (null fdefn) create)
;;; something. SETFable.
#!-sb-fluid (declaim (inline %coerce-name-to-fun))
(defun %coerce-name-to-fun (name)
(let ((fdefn (fdefinition-object name nil)))
(or (and fdefn (fdefn-fun fdefn))
;;; something. SETFable.
#!-sb-fluid (declaim (inline %coerce-name-to-fun))
(defun %coerce-name-to-fun (name)
(let ((fdefn (fdefinition-object name nil)))
(or (and fdefn (fdefn-fun fdefn))
(defun (setf %coerce-name-to-fun) (function name)
(let ((fdefn (fdefinition-object name t)))
(setf (fdefn-fun fdefn) function)))
(defun (setf %coerce-name-to-fun) (function name)
(let ((fdefn (fdefinition-object name t)))
(setf (fdefn-fun fdefn) function)))
;; installed as the global definition of some function name.
type
;; the previous, encapsulated definition. This used to be installed
;; installed as the global definition of some function name.
type
;; the previous, encapsulated definition. This used to be installed
;; an encapsulation that no longer exists.
(let ((info (make-encapsulation-info type (fdefn-fun fdefn))))
(setf (fdefn-fun fdefn)
;; an encapsulation that no longer exists.
(let ((info (make-encapsulation-info type (fdefn-fun fdefn))))
(setf (fdefn-fun fdefn)
- (lambda (&rest arg-list)
- (declare (special arg-list))
- (let ((basic-definition (encapsulation-info-definition info)))
- (declare (special basic-definition))
- (eval body)))))))
+ (named-lambda encapsulation (&rest arg-list)
+ (declare (special arg-list))
+ (let ((basic-definition (encapsulation-info-definition info)))
+ (declare (special basic-definition))
+ (eval body)))))))
;;; This is like FIND-IF, except that we do it on a compiled closure's
;;; environment.
(defun find-if-in-closure (test fun)
;;; This is like FIND-IF, except that we do it on a compiled closure's
;;; environment.
(defun find-if-in-closure (test fun)
;;; When removing an encapsulation, we must remember that
;;; encapsulating definitions close over a reference to the
;;; When removing an encapsulation, we must remember that
;;; encapsulating definitions close over a reference to the
;;; When you find an info with the target type, the previous info in
;;; the chain has the ensulating definition of that type. We take the
;;; encapsulated definition from the info with the target type, and we
;;; When you find an info with the target type, the previous info in
;;; the chain has the ensulating definition of that type. We take the
;;; encapsulated definition from the info with the target type, and we
#!+sb-doc
"Removes NAME's most recent encapsulation of the specified TYPE."
(let* ((fdefn (fdefinition-object name nil))
#!+sb-doc
"Removes NAME's most recent encapsulation of the specified TYPE."
(let* ((fdefn (fdefinition-object name nil))
- ;; It disappeared on us, so don't worry about it.
- )
- ((eq (encapsulation-info-type encap-info) type)
- ;; It's the first one, so change the fdefn object.
- (setf (fdefn-fun fdefn)
- (encapsulation-info-definition encap-info)))
- (t
- ;; It must be an interior one, so find it.
- (loop
- (let ((next-info (encapsulation-info
- (encapsulation-info-definition encap-info))))
- (unless next-info
- ;; Not there, so don't worry about it.
- (return))
- (when (eq (encapsulation-info-type next-info) type)
- ;; This is it, so unlink us.
- (setf (encapsulation-info-definition encap-info)
- (encapsulation-info-definition next-info))
- (return))
- (setf encap-info next-info))))))
+ ;; It disappeared on us, so don't worry about it.
+ )
+ ((eq (encapsulation-info-type encap-info) type)
+ ;; It's the first one, so change the fdefn object.
+ (setf (fdefn-fun fdefn)
+ (encapsulation-info-definition encap-info)))
+ (t
+ ;; It must be an interior one, so find it.
+ (loop
+ (let ((next-info (encapsulation-info
+ (encapsulation-info-definition encap-info))))
+ (unless next-info
+ ;; Not there, so don't worry about it.
+ (return))
+ (when (eq (encapsulation-info-type next-info) type)
+ ;; This is it, so unlink us.
+ (setf (encapsulation-info-definition encap-info)
+ (encapsulation-info-definition next-info))
+ (return))
+ (setf encap-info next-info))))))
t)
;;; Does NAME have an encapsulation of the given TYPE?
(defun encapsulated-p (name type)
(let ((fdefn (fdefinition-object name nil)))
(do ((encap-info (encapsulation-info (fdefn-fun fdefn))
t)
;;; Does NAME have an encapsulation of the given TYPE?
(defun encapsulated-p (name type)
(let ((fdefn (fdefinition-object name nil)))
(do ((encap-info (encapsulation-info (fdefn-fun fdefn))
(declare (type (or encapsulation-info null) encap-info))
(when (eq (encapsulation-info-type encap-info) type)
(declare (type (or encapsulation-info null) encap-info))
(when (eq (encapsulation-info-type encap-info) type)
- "This holds functions that (SETF FDEFINITION) invokes before storing the
- new value. These functions take the function name and the new value.")
+ "A list of functions that (SETF FDEFINITION) invokes before storing the
+ new value. The functions take the function name and the new value.")
(defun %set-fdefinition (name new-value)
#!+sb-doc
"Set NAME's global function definition."
(declare (type function new-value) (optimize (safety 1)))
(defun %set-fdefinition (name new-value)
#!+sb-doc
"Set NAME's global function definition."
(declare (type function new-value) (optimize (safety 1)))
- (let ((fdefn (fdefinition-object name t)))
- ;; *SETF-FDEFINITION-HOOK* won't be bound when initially running
- ;; top level forms in the kernel core startup.
- (when (boundp '*setf-fdefinition-hook*)
- (dolist (f *setf-fdefinition-hook*)
- (funcall f name new-value)))
+ (with-single-package-locked-error (:symbol name "setting fdefinition of ~A")
+
+ ;; 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))))))
- (let ((encap-info (encapsulation-info (fdefn-fun fdefn))))
- (cond (encap-info
- (loop
- (let ((more-info
- (encapsulation-info
- (encapsulation-info-definition encap-info))))
- (if more-info
- (setf encap-info more-info)
- (return
- (setf (encapsulation-info-definition encap-info)
- new-value))))))
- (t
- (setf (fdefn-fun fdefn) 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.
+ (when (boundp '*setf-fdefinition-hook*)
+ (dolist (f *setf-fdefinition-hook*)
+ (declare (type function f))
+ (funcall f name new-value)))
+
+ (let ((encap-info (encapsulation-info (fdefn-fun fdefn))))
+ (cond (encap-info
+ (loop
+ (let ((more-info
+ (encapsulation-info
+ (encapsulation-info-definition encap-info))))
+ (if more-info
+ (setf encap-info more-info)
+ (return
+ (setf (encapsulation-info-definition encap-info)
+ new-value))))))
+ (t
+ (setf (fdefn-fun fdefn) new-value)))))))
- (let ((fdefn (fdefinition-object name nil)))
- (when fdefn
- (fdefn-makunbound fdefn)))
- (sb!kernel:undefine-fun-name name)
- name)
+ (with-single-package-locked-error
+ (:symbol name "removing the function or macro definition of ~A")
+ (let ((fdefn (fdefinition-object name nil)))
+ (when fdefn
+ (fdefn-makunbound fdefn)))
+ (sb!kernel:undefine-fun-name name)
+ name))