Tweak MERGE of 2 vectors into a vector.
[sbcl.git] / src / code / fdefinition.lisp
blob4f471b401caad764ff9439ef8da624986236c415
1 ;;;; This file contains functions that hack on the global function
2 ;;;; namespace (primarily concerned with SETF functions here). Also,
3 ;;;; function encapsulation and routines that set and return
4 ;;;; definitions disregarding whether they might be encapsulated.
6 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; more information.
8 ;;;;
9 ;;;; This software is derived from the CMU CL system, which was
10 ;;;; written at Carnegie Mellon University and released into the
11 ;;;; public domain. The software is in the public domain and is
12 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
13 ;;;; files for more information.
15 (in-package "SB!IMPL")
17 (sb!int::/show0 "fdefinition.lisp 22")
19 ;;;; fdefinition (fdefn) objects
21 (defun make-fdefn (name)
22 (make-fdefn name))
24 (defun fdefn-name (fdefn)
25 (declare (type fdefn fdefn))
26 (fdefn-name fdefn))
28 (defun fdefn-fun (fdefn)
29 (declare (type fdefn fdefn)
30 (values (or function null)))
31 (fdefn-fun fdefn))
33 (defun (setf fdefn-fun) (fun fdefn)
34 (declare (type function fun)
35 (type fdefn fdefn)
36 (values function))
37 (setf (fdefn-fun fdefn) fun))
39 (defun fdefn-makunbound (fdefn)
40 (declare (type fdefn fdefn))
41 (fdefn-makunbound fdefn))
43 #!-sb-fluid (declaim (inline symbol-fdefn))
44 ;; Return SYMBOL's fdefinition, if any, or NIL. SYMBOL must already
45 ;; have been verified to be a symbol by the caller.
46 (defun symbol-fdefn (symbol)
47 (declare (optimize (safety 0)))
48 (info-vector-fdefn (symbol-info-vector (uncross symbol))))
50 ;; Return the fdefn object for NAME, or NIL if there is no fdefn.
51 ;; Signal an error if name isn't valid.
52 ;; Assume that exists-p implies LEGAL-FUN-NAME-P.
54 (declaim (ftype (sfunction ((or symbol list)) (or fdefn null)) find-fdefn))
55 (defun find-fdefn (name0)
56 ;; Since this emulates GET-INFO-VALUE, we have to uncross the name.
57 (let ((name (uncross name0)))
58 (declare (optimize (safety 0)))
59 (when (symbolp name) ; Don't need LEGAL-FUN-NAME-P check
60 (return-from find-fdefn (symbol-fdefn name)))
61 ;; Technically the ALLOW-ATOM argument of NIL isn't needed, but
62 ;; the compiler isn't figuring out not to test SYMBOLP twice in a row.
63 (with-globaldb-name (key1 key2 nil) name
64 :hairy
65 ;; INFO-GETHASH returns NIL or a vector. INFO-VECTOR-FDEFN accepts
66 ;; either. If fdefn isn't found, fall through to the legality test.
67 (awhen (info-vector-fdefn (info-gethash name *info-environment*))
68 (return-from find-fdefn it))
69 :simple
70 (progn
71 (awhen (symbol-info-vector key1)
72 (multiple-value-bind (data-idx descriptor-idx field-idx)
73 (info-find-aux-key/packed it key2)
74 (declare (type index descriptor-idx)
75 (type (integer 0 #.+infos-per-word+) field-idx))
76 ;; Secondary names must have at least one info, so if a descriptor
77 ;; exists, there's no need to extract the n-infos field.
78 (when data-idx
79 (when (eql (incf field-idx) +infos-per-word+)
80 (setq field-idx 0 descriptor-idx (1+ descriptor-idx)))
81 (when (eql (packed-info-field it descriptor-idx field-idx)
82 +fdefn-info-num+)
83 (return-from find-fdefn
84 (aref it (1- (the index data-idx))))))))
85 (when (eq key1 'setf) ; bypass the legality test
86 (return-from find-fdefn nil))))
87 (legal-fun-name-or-type-error name)))
89 (declaim (ftype (sfunction (t) fdefn) find-or-create-fdefn))
90 (defun find-or-create-fdefn (name)
91 (or (find-fdefn name)
92 ;; We won't reach here if the name was not legal
93 (let ((name (uncross name)))
94 (get-info-value-initializing :function :definition name
95 (make-fdefn name)))))
97 (defun maybe-clobber-ftype (name)
98 (unless (eq :declared (info :function :where-from name))
99 (clear-info :function :type name)))
101 ;;; Return the fdefn-fun of NAME's fdefinition including any encapsulations.
102 ;;; LOOKUP-FN, defaulting to FIND-FDEFN, specifies how to lookup the fdefn.
103 ;;; As a special case it can be given as SYMBOL-FDEFN which is slightly quicker.
104 ;;; This is the core of the implementation of the standard FDEFINITION function,
105 ;;; but as we've defined FDEFINITION, that strips encapsulations.
106 (defmacro %coerce-name-to-fun (name &optional (lookup-fn 'find-fdefn))
107 `(let* ((name ,name) (fdefn (,lookup-fn name)))
108 (if fdefn
109 (sb!c:safe-fdefn-fun fdefn)
110 (error 'undefined-function :name name))))
112 ;; Coerce CALLABLE (a function-designator) to a FUNCTION.
113 ;; The compiler emits this when someone tries to FUNCALL something.
114 ;; Extended-function-designators are not accepted,
115 ;; This function is defknowned with 'explicit-check', and we avoid calling
116 ;; SYMBOL-FUNCTION because that would do another check.
117 ;; It would be great if this could change its error message
118 ;; depending on the input to either:
119 ;; "foo is not a function designator" if not a CALLABLE
120 ;; "foo does not designate a currently defined function"
121 ;; if a symbol does not satisfy FBOUNDP.
122 (defun %coerce-callable-to-fun (callable)
123 (etypecase callable
124 (function callable)
125 (symbol (%coerce-name-to-fun callable symbol-fdefn))))
128 ;;;; definition encapsulation
130 (defstruct (encapsulation-info (:constructor make-encapsulation-info
131 (type definition))
132 (:copier nil))
133 ;; This is definition's encapsulation type. The encapsulated
134 ;; definition is in the previous ENCAPSULATION-INFO element or
135 ;; installed as the global definition of some function name.
136 type
137 ;; the previous, encapsulated definition. This used to be installed
138 ;; as a global definition for some function name, but it was
139 ;; replaced by an encapsulation of type TYPE.
140 (definition nil :type function))
142 ;;; Replace the definition of NAME with a function that calls FUNCTION
143 ;;; with the original function and its arguments.
144 ;;; TYPE is whatever you would like to associate with this
145 ;;; encapsulation for identification in case you need multiple
146 ;;; encapsulations of the same name.
147 (defun encapsulate (name type function)
148 (let* ((fdefn (find-fdefn name))
149 (underlying-fun (sb!c:safe-fdefn-fun fdefn)))
150 (when (typep underlying-fun 'generic-function)
151 (return-from encapsulate
152 (encapsulate-generic-function underlying-fun type function)))
153 ;; We must bind and close over INFO. Consider the case where we
154 ;; encapsulate (the second) an encapsulated (the first)
155 ;; definition, and later someone unencapsulates the encapsulated
156 ;; (first) definition. We don't want our encapsulation (second) to
157 ;; bind basic-definition to the encapsulated (first) definition
158 ;; when it no longer exists. When unencapsulating, we make sure to
159 ;; clobber the appropriate INFO structure to allow
160 ;; basic-definition to be bound to the next definition instead of
161 ;; an encapsulation that no longer exists.
162 (let ((info (make-encapsulation-info type underlying-fun)))
163 (setf (fdefn-fun fdefn)
164 (named-lambda encapsulation (&rest args)
165 (apply function (encapsulation-info-definition info)
166 args))))))
168 ;;; This is like FIND-IF, except that we do it on a compiled closure's
169 ;;; environment.
170 (defun find-if-in-closure (test closure)
171 (declare (closure closure))
172 (do-closure-values (value closure)
173 (when (funcall test value)
174 (return value))))
176 ;;; Find the encapsulation info that has been closed over.
177 (defun encapsulation-info (fun)
178 (when (closurep fun)
179 (find-if-in-closure #'encapsulation-info-p fun)))
181 ;;; When removing an encapsulation, we must remember that
182 ;;; encapsulating definitions close over a reference to the
183 ;;; ENCAPSULATION-INFO that describes the encapsulating definition.
184 ;;; When you find an info with the target type, the previous info in
185 ;;; the chain has the ensulating definition of that type. We take the
186 ;;; encapsulated definition from the info with the target type, and we
187 ;;; store it in the previous info structure whose encapsulating
188 ;;; definition it describes looks to this previous info structure for
189 ;;; a definition to bind (see ENCAPSULATE). When removing the first
190 ;;; info structure, we do something conceptually equal, but
191 ;;; mechanically it is different.
192 (defun unencapsulate (name type)
193 #!+sb-doc
194 "Removes NAME's most recent encapsulation of the specified TYPE."
195 (let* ((fdefn (find-fdefn name))
196 (encap-info (encapsulation-info (fdefn-fun fdefn))))
197 (declare (type (or encapsulation-info null) encap-info))
198 (when (and fdefn (typep (fdefn-fun fdefn) 'generic-function))
199 (return-from unencapsulate
200 (unencapsulate-generic-function (fdefn-fun fdefn) type)))
201 (cond ((not encap-info)
202 ;; It disappeared on us, so don't worry about it.
204 ((eq (encapsulation-info-type encap-info) type)
205 ;; It's the first one, so change the fdefn object.
206 (setf (fdefn-fun fdefn)
207 (encapsulation-info-definition encap-info)))
209 ;; It must be an interior one, so find it.
210 (loop
211 (let ((next-info (encapsulation-info
212 (encapsulation-info-definition encap-info))))
213 (unless next-info
214 ;; Not there, so don't worry about it.
215 (return))
216 (when (eq (encapsulation-info-type next-info) type)
217 ;; This is it, so unlink us.
218 (setf (encapsulation-info-definition encap-info)
219 (encapsulation-info-definition next-info))
220 (return))
221 (setf encap-info next-info))))))
224 ;;; Does NAME have an encapsulation of the given TYPE?
225 (defun encapsulated-p (name type)
226 (let ((fdefn (find-fdefn name)))
227 (when (and fdefn (typep (fdefn-fun fdefn) 'generic-function))
228 (return-from encapsulated-p
229 (encapsulated-generic-function-p (fdefn-fun fdefn) type)))
230 (do ((encap-info (encapsulation-info (fdefn-fun fdefn))
231 (encapsulation-info
232 (encapsulation-info-definition encap-info))))
233 ((null encap-info) nil)
234 (declare (type (or encapsulation-info null) encap-info))
235 (when (eq (encapsulation-info-type encap-info) type)
236 (return t)))))
238 ;;;; FDEFINITION
240 ;;; KLUDGE: Er, it looks as though this means that
241 ;;; (FUNCALL (FDEFINITION 'FOO))
242 ;;; doesn't do the same thing as
243 ;;; (FUNCALL 'FOO),
244 ;;; and (SYMBOL-FUNCTION 'FOO) isn't in general the same thing
245 ;;; as (FDEFINITION 'FOO). That doesn't look like ANSI behavior to me.
246 ;;; Look e.g. at the ANSI definition of TRACE: "Whenever a traced
247 ;;; function is invoked, information about the call, ..". Try this:
248 ;;; (DEFUN FOO () (PRINT "foo"))
249 ;;; (TRACE FOO)
250 ;;; (FUNCALL 'FOO)
251 ;;; (FUNCALL (FDEFINITION 'FOO))
252 ;;; What to do? ANSI says TRACE "Might change the definitions of the
253 ;;; functions named by function-names." Might it be OK to just get
254 ;;; punt all this encapsulation stuff and go back to a simple but
255 ;;; correct implementation of TRACE? We'd lose the ability to redefine
256 ;;; a TRACEd function and keep the trace in place, but that seems
257 ;;; tolerable to me. (Is the wrapper stuff needed for anything else
258 ;;; besides TRACE?)
260 ;;; The only problem I can see with not having a wrapper: If tracing
261 ;;; EQ, EQL, EQUAL, or EQUALP causes its function address to change,
262 ;;; it will mess up the MAKE-HASH-TABLE logic which uses EQ tests
263 ;;; on those function values. But given the ANSI statement about
264 ;;; TRACE causing things to change, that doesn't seem too unreasonable;
265 ;;; and we might even be able to forbid tracing these functions.
266 ;;; -- WHN 2001-11-02
267 (defun fdefinition (name)
268 #!+sb-doc
269 "Return name's global function definition taking care to respect any
270 encapsulations and to return the innermost encapsulated definition.
271 This is SETF'able."
272 (let ((fun (%coerce-name-to-fun name)))
273 (loop
274 (let ((encap-info (encapsulation-info fun)))
275 (if encap-info
276 (setf fun (encapsulation-info-definition encap-info))
277 (return fun))))))
279 (defvar *setf-fdefinition-hook* nil
280 #!+sb-doc
281 "A list of functions that (SETF FDEFINITION) invokes before storing the
282 new value. The functions take the function name and the new value.")
284 ;; Return :MACRO or :SPECIAL if FUNCTION is the error-signaling trampoline
285 ;; for a macro or a special operator respectively. Test for this by seeing
286 ;; whether FUNCTION is the same closure as for a known macro.
287 ;; For cold-init to work, this must pick any macro defined before
288 ;; this function is. A safe choice is a macro from this same file.
289 (defun macro/special-guard-fun-p (function)
290 (and (closurep function)
291 ;; Prior to cold-init fixing up the load-time-value, this compares
292 ;; %closure-fun to 0, which is ok - it returns NIL.
293 (eq (load-time-value
294 (%closure-fun (symbol-function '%coerce-name-to-fun)) t)
295 (%closure-fun function))
296 ;; This is not super-efficient, but every code path that gets
297 ;; here does so with the intent of signaling an error.
298 (car (%fun-name function))))
300 ;; Reject any "object of implementation-dependent nature" that
301 ;; so happens to be a function in SBCL, but which must not be
302 ;; bound to a function-name by way of (SETF FEDFINITION).
303 (defun err-if-unacceptable-function (object setter)
304 (when (macro/special-guard-fun-p object)
305 (error 'simple-reference-error
306 :references (list '(:ansi-cl :function fdefinition))
307 :format-control "~S is not acceptable to ~S."
308 :format-arguments (list object setter))))
310 (defun %set-fdefinition (name new-value)
311 #!+sb-doc
312 "Set NAME's global function definition."
313 (declare (type function new-value) (optimize (safety 1)))
314 (err-if-unacceptable-function new-value '(setf fdefinition))
315 (with-single-package-locked-error (:symbol name "setting fdefinition of ~A")
316 (maybe-clobber-ftype name)
318 ;; Check for hash-table stuff. Woe onto him that mixes encapsulation
319 ;; with this.
320 (when (and (symbolp name) (fboundp name)
321 (boundp '*user-hash-table-tests*))
322 (let ((old (symbol-function name)))
323 (declare (special *user-hash-table-tests*))
324 (dolist (spec *user-hash-table-tests*)
325 (cond ((eq old (second spec))
326 ;; test-function
327 (setf (second spec) new-value))
328 ((eq old (third spec))
329 ;; hash-function
330 (setf (third spec) new-value))))))
332 ;; FIXME: This is a good hook to have, but we should probably
333 ;; reserve it for users.
334 (let ((fdefn (find-or-create-fdefn name)))
335 ;; *SETF-FDEFINITION-HOOK* won't be bound when initially running
336 ;; top level forms in the kernel core startup.
337 (when (boundp '*setf-fdefinition-hook*)
338 (dolist (f *setf-fdefinition-hook*)
339 (declare (type function f))
340 (funcall f name new-value)))
342 (let ((encap-info (encapsulation-info (fdefn-fun fdefn))))
343 (cond (encap-info
344 (loop
345 (let ((more-info
346 (encapsulation-info
347 (encapsulation-info-definition encap-info))))
348 (if more-info
349 (setf encap-info more-info)
350 (return
351 (setf (encapsulation-info-definition encap-info)
352 new-value))))))
354 (setf (fdefn-fun fdefn) new-value)))))))
356 ;;;; FBOUNDP and FMAKUNBOUND
358 (defun fboundp (name)
359 #!+sb-doc
360 "Return true if name has a global function definition."
361 (let ((fdefn (find-fdefn name)))
362 (and fdefn (fdefn-fun fdefn) t)))
364 (defun fmakunbound (name)
365 #!+sb-doc
366 "Make NAME have no global function definition."
367 (with-single-package-locked-error
368 (:symbol name "removing the function or macro definition of ~A")
369 (let ((fdefn (find-fdefn name)))
370 (when fdefn
371 (fdefn-makunbound fdefn)))
372 (undefine-fun-name name)
373 name))