Provide restarts in %coerce-name-to-fun.
[sbcl.git] / src / code / fdefinition.lisp
blobc7f9cbe350f8f9bde300820d0837e1f888227019
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 #!-immobile-space (make-fdefn name)
23 ;; This is %primitive because it needs pseudo-atomic,
24 ;; otherwise it would just be an alien-funcall.
25 #!+immobile-space
26 (let ((fdefn (truly-the (values fdefn)
27 (%primitive sb!vm::alloc-immobile-fdefn name))))
28 (%primitive fdefn-makunbound fdefn)
29 fdefn))
31 (defun fdefn-name (fdefn)
32 (declare (type fdefn fdefn))
33 (fdefn-name fdefn))
35 (defun fdefn-fun (fdefn)
36 (declare (type fdefn fdefn)
37 (values (or function null)))
38 (fdefn-fun fdefn))
40 (defun (setf fdefn-fun) (fun fdefn)
41 (declare (type function fun)
42 (type fdefn fdefn)
43 (values function))
44 (setf (fdefn-fun fdefn) fun))
46 (defun fdefn-makunbound (fdefn)
47 (declare (type fdefn fdefn))
48 (fdefn-makunbound fdefn))
50 #!-sb-fluid (declaim (inline symbol-fdefn))
51 ;; Return SYMBOL's fdefinition, if any, or NIL. SYMBOL must already
52 ;; have been verified to be a symbol by the caller.
53 (defun symbol-fdefn (symbol)
54 (declare (optimize (safety 0)))
55 (info-vector-fdefn (symbol-info-vector symbol)))
57 ;; Return the fdefn object for NAME, or NIL if there is no fdefn.
58 ;; Signal an error if name isn't valid.
59 ;; Assume that exists-p implies LEGAL-FUN-NAME-P.
61 (declaim (ftype (sfunction ((or symbol list)) (or fdefn null)) find-fdefn))
62 (defun find-fdefn (name)
63 (declare (explicit-check))
64 (when (symbolp name) ; Don't need LEGAL-FUN-NAME-P check
65 (return-from find-fdefn (symbol-fdefn name)))
66 ;; Technically the ALLOW-ATOM argument of NIL isn't needed, but
67 ;; the compiler isn't figuring out not to test SYMBOLP twice in a row.
68 (with-globaldb-name (key1 key2 nil) name
69 :hairy
70 ;; INFO-GETHASH returns NIL or a vector. INFO-VECTOR-FDEFN accepts
71 ;; either. If fdefn isn't found, fall through to the legality test.
72 (awhen (info-vector-fdefn (info-gethash name *info-environment*))
73 (return-from find-fdefn it))
74 :simple
75 (progn
76 (awhen (symbol-info-vector key1)
77 (multiple-value-bind (data-idx descriptor-idx field-idx)
78 (info-find-aux-key/packed it key2)
79 (declare (type index descriptor-idx)
80 (type (integer 0 #.+infos-per-word+) field-idx))
81 ;; Secondary names must have at least one info, so if a descriptor
82 ;; exists, there's no need to extract the n-infos field.
83 (when data-idx
84 (when (eql (incf field-idx) +infos-per-word+)
85 (setq field-idx 0 descriptor-idx (1+ descriptor-idx)))
86 (when (eql (packed-info-field it descriptor-idx field-idx)
87 +fdefn-info-num+)
88 (return-from find-fdefn
89 (aref it (1- (the index data-idx))))))))
90 (when (eq key1 'setf) ; bypass the legality test
91 (return-from find-fdefn nil))))
92 (legal-fun-name-or-type-error name))
94 (declaim (ftype (sfunction (t) fdefn) find-or-create-fdefn))
95 (defun find-or-create-fdefn (name)
96 (or (find-fdefn name)
97 ;; We won't reach here if the name was not legal
98 (get-info-value-initializing :function :definition name
99 (make-fdefn name))))
101 ;;; Remove NAME's FTYPE information unless it was explicitly PROCLAIMED.
102 ;;; The NEW-FUNCTION argument is presently unused, but could be used
103 ;;; for checking compatibility of the NEW-FUNCTION against a proclamation.
104 ;;; (We could issue a warning and/or remove the type if incompatible.)
105 (defun maybe-clobber-ftype (name new-function)
106 (declare (ignore new-function))
107 (unless (eq :declared (info :function :where-from name))
108 (clear-info :function :type name)))
110 ;;; Return the fdefn-fun of NAME's fdefinition including any encapsulations.
111 ;;; LOOKUP-FN, defaulting to FIND-FDEFN, specifies how to lookup the fdefn.
112 ;;; As a special case it can be given as SYMBOL-FDEFN which is slightly quicker.
113 ;;; This is the core of the implementation of the standard FDEFINITION function,
114 ;;; but as we've defined FDEFINITION, that strips encapsulations.
115 (defmacro %coerce-name-to-fun (name &optional (lookup-fn 'find-fdefn)
116 strictly-functionp)
117 `(block nil
118 (let ((name ,name))
119 (tagbody retry
120 (let ((fdefn (,lookup-fn name)))
121 (when fdefn
122 (let ((f (fdefn-fun (truly-the fdefn fdefn))))
123 ;; If STRICTLY-FUNCTIONP is true, we make sure not to return an error
124 ;; trampoline. This extra check ensures that full calls such as
125 ;; (MAPCAR 'OR '()) signal an error that OR isn't a function.
126 ;; This accords with the non-requirement that macros store strictly
127 ;; a function in the symbol that names them. In many implementations,
128 ;; (FUNCTIONP (SYMBOL-FUNCTION 'OR)) => NIL. We want to pretend that.
129 (when f
130 (,@(if strictly-functionp
131 '(unless (macro/special-guard-fun-p f))
132 '(progn))
133 (return f)))))
134 (restart-case (error 'undefined-function :name name)
135 (continue ()
136 :report (lambda (stream)
137 (format stream "Retry using ~s." name)))
138 (use-value (value)
139 :report (lambda (stream)
140 (format stream "Use specified function"))
141 :interactive read-evaluated-form
142 (when (functionp value)
143 (return value))
144 (setf name (the ,(if (eq lookup-fn 'symbol-fdefn)
145 'symbol
147 value))))
148 (go retry))))))
150 ;; Return T if FUNCTION is the error-signaling trampoline
151 ;; for a macro or a special operator. Test for this by seeing
152 ;; whether FUNCTION is the same closure as for a known macro.
153 ;; For cold-init to work, this must pick any macro defined before
154 ;; this function is. A safe choice is a macro from this same file.
155 (declaim (inline macro/special-guard-fun-p))
156 (defun macro/special-guard-fun-p (function)
157 ;; When inlined, this is a few instructions shorter than CLOSUREP
158 ;; if we already know that FUNCTION is a function.
159 ;; It will signal a type error if not, which is the right thing to do anyway.
160 ;; (this isn't quite a true predicate)
161 (and (= (fun-subtype function) sb!vm:closure-header-widetag)
162 ;; Prior to cold-init fixing up the load-time-value, this compares
163 ;; %closure-fun to 0, which is ok - it returns NIL.
164 (eq (load-time-value (%closure-fun (symbol-function '%coerce-name-to-fun))
166 (%closure-fun function))))
168 ;; Coerce CALLABLE (a function-designator) to a FUNCTION.
169 ;; The compiler emits this when someone tries to FUNCALL something.
170 ;; Extended-function-designators are not accepted,
171 ;; This function declares EXPLICIT-CHECK, and we avoid calling
172 ;; SYMBOL-FUNCTION because that would do another check.
173 ;; It would be great if this could change its error message
174 ;; depending on the input to either:
175 ;; "foo is not a function designator" if not a CALLABLE
176 ;; "foo does not designate a currently defined function"
177 ;; if a symbol does not satisfy FBOUNDP.
178 (defun %coerce-callable-to-fun (callable)
179 (declare (explicit-check))
180 (etypecase callable
181 (function callable)
182 (symbol (%coerce-name-to-fun callable symbol-fdefn t))))
185 ;;;; definition encapsulation
187 (defstruct (encapsulation-info (:constructor make-encapsulation-info
188 (type definition))
189 (:copier nil))
190 ;; This is definition's encapsulation type. The encapsulated
191 ;; definition is in the previous ENCAPSULATION-INFO element or
192 ;; installed as the global definition of some function name.
193 type
194 ;; the previous, encapsulated definition. This used to be installed
195 ;; as a global definition for some function name, but it was
196 ;; replaced by an encapsulation of type TYPE.
197 (definition nil :type function))
199 ;;; Replace the definition of NAME with a function that calls FUNCTION
200 ;;; with the original function and its arguments.
201 ;;; TYPE is whatever you would like to associate with this
202 ;;; encapsulation for identification in case you need multiple
203 ;;; encapsulations of the same name.
204 (defun encapsulate (name type function)
205 (let* ((fdefn (find-fdefn name))
206 (underlying-fun (sb!c:safe-fdefn-fun fdefn)))
207 (when (typep underlying-fun 'generic-function)
208 (return-from encapsulate
209 (encapsulate-generic-function underlying-fun type function)))
210 ;; We must bind and close over INFO. Consider the case where we
211 ;; encapsulate (the second) an encapsulated (the first)
212 ;; definition, and later someone unencapsulates the encapsulated
213 ;; (first) definition. We don't want our encapsulation (second) to
214 ;; bind basic-definition to the encapsulated (first) definition
215 ;; when it no longer exists. When unencapsulating, we make sure to
216 ;; clobber the appropriate INFO structure to allow
217 ;; basic-definition to be bound to the next definition instead of
218 ;; an encapsulation that no longer exists.
219 (let ((info (make-encapsulation-info type underlying-fun)))
220 (setf (fdefn-fun fdefn)
221 (named-lambda encapsulation (&rest args)
222 (apply function (encapsulation-info-definition info)
223 args))))))
225 ;;; This is like FIND-IF, except that we do it on a compiled closure's
226 ;;; environment.
227 (defun find-if-in-closure (test closure)
228 (declare (closure closure))
229 (do-closure-values (value closure)
230 (when (funcall test value)
231 (return value))))
233 ;;; Find the encapsulation info that has been closed over.
234 (defun encapsulation-info (fun)
235 (when (closurep fun)
236 (find-if-in-closure #'encapsulation-info-p fun)))
238 ;;; When removing an encapsulation, we must remember that
239 ;;; encapsulating definitions close over a reference to the
240 ;;; ENCAPSULATION-INFO that describes the encapsulating definition.
241 ;;; When you find an info with the target type, the previous info in
242 ;;; the chain has the ensulating definition of that type. We take the
243 ;;; encapsulated definition from the info with the target type, and we
244 ;;; store it in the previous info structure whose encapsulating
245 ;;; definition it describes looks to this previous info structure for
246 ;;; a definition to bind (see ENCAPSULATE). When removing the first
247 ;;; info structure, we do something conceptually equal, but
248 ;;; mechanically it is different.
249 (defun unencapsulate (name type)
250 "Removes NAME's most recent encapsulation of the specified TYPE."
251 (let* ((fdefn (find-fdefn name))
252 (encap-info (encapsulation-info (fdefn-fun fdefn))))
253 (declare (type (or encapsulation-info null) encap-info))
254 (when (and fdefn (typep (fdefn-fun fdefn) 'generic-function))
255 (return-from unencapsulate
256 (unencapsulate-generic-function (fdefn-fun fdefn) type)))
257 (cond ((not encap-info)
258 ;; It disappeared on us, so don't worry about it.
260 ((eq (encapsulation-info-type encap-info) type)
261 ;; It's the first one, so change the fdefn object.
262 (setf (fdefn-fun fdefn)
263 (encapsulation-info-definition encap-info)))
265 ;; It must be an interior one, so find it.
266 (loop
267 (let ((next-info (encapsulation-info
268 (encapsulation-info-definition encap-info))))
269 (unless next-info
270 ;; Not there, so don't worry about it.
271 (return))
272 (when (eq (encapsulation-info-type next-info) type)
273 ;; This is it, so unlink us.
274 (setf (encapsulation-info-definition encap-info)
275 (encapsulation-info-definition next-info))
276 (return))
277 (setf encap-info next-info))))))
280 ;;; Does NAME have an encapsulation of the given TYPE?
281 (defun encapsulated-p (name type)
282 (let ((fdefn (find-fdefn name)))
283 (when (and fdefn (typep (fdefn-fun fdefn) 'generic-function))
284 (return-from encapsulated-p
285 (encapsulated-generic-function-p (fdefn-fun fdefn) type)))
286 (do ((encap-info (encapsulation-info (fdefn-fun fdefn))
287 (encapsulation-info
288 (encapsulation-info-definition encap-info))))
289 ((null encap-info) nil)
290 (declare (type (or encapsulation-info null) encap-info))
291 (when (eq (encapsulation-info-type encap-info) type)
292 (return t)))))
294 ;;;; FDEFINITION
296 ;;; KLUDGE: Er, it looks as though this means that
297 ;;; (FUNCALL (FDEFINITION 'FOO))
298 ;;; doesn't do the same thing as
299 ;;; (FUNCALL 'FOO),
300 ;;; and (SYMBOL-FUNCTION 'FOO) isn't in general the same thing
301 ;;; as (FDEFINITION 'FOO). That doesn't look like ANSI behavior to me.
302 ;;; Look e.g. at the ANSI definition of TRACE: "Whenever a traced
303 ;;; function is invoked, information about the call, ..". Try this:
304 ;;; (DEFUN FOO () (PRINT "foo"))
305 ;;; (TRACE FOO)
306 ;;; (FUNCALL 'FOO)
307 ;;; (FUNCALL (FDEFINITION 'FOO))
308 ;;; What to do? ANSI says TRACE "Might change the definitions of the
309 ;;; functions named by function-names." Might it be OK to just get
310 ;;; punt all this encapsulation stuff and go back to a simple but
311 ;;; correct implementation of TRACE? We'd lose the ability to redefine
312 ;;; a TRACEd function and keep the trace in place, but that seems
313 ;;; tolerable to me. (Is the wrapper stuff needed for anything else
314 ;;; besides TRACE?)
316 ;;; The only problem I can see with not having a wrapper: If tracing
317 ;;; EQ, EQL, EQUAL, or EQUALP causes its function address to change,
318 ;;; it will mess up the MAKE-HASH-TABLE logic which uses EQ tests
319 ;;; on those function values. But given the ANSI statement about
320 ;;; TRACE causing things to change, that doesn't seem too unreasonable;
321 ;;; and we might even be able to forbid tracing these functions.
322 ;;; -- WHN 2001-11-02
323 (defun fdefinition (name)
324 "Return name's global function definition taking care to respect any
325 encapsulations and to return the innermost encapsulated definition.
326 This is SETF'able."
327 (declare (explicit-check))
328 (let ((fun (%coerce-name-to-fun name)))
329 (loop
330 (let ((encap-info (encapsulation-info fun)))
331 (if encap-info
332 (setf fun (encapsulation-info-definition encap-info))
333 (return fun))))))
335 (defvar *setf-fdefinition-hook* nil
336 "A list of functions that (SETF FDEFINITION) invokes before storing the
337 new value. The functions take the function name and the new value.")
339 ;; Reject any "object of implementation-dependent nature" that
340 ;; so happens to be a function in SBCL, but which must not be
341 ;; bound to a function-name by way of (SETF FEDFINITION).
342 (defun err-if-unacceptable-function (object setter)
343 (declare (notinline macro/special-guard-fun-p)) ; not performance-critical
344 (when (macro/special-guard-fun-p object)
345 (error 'simple-reference-error
346 :references (list '(:ansi-cl :function fdefinition))
347 :format-control "~S is not acceptable to ~S."
348 :format-arguments (list object setter))))
350 (defun %set-fdefinition (name new-value)
351 "Set NAME's global function definition."
352 (declare (type function new-value) (optimize (safety 1)))
353 (declare (explicit-check))
354 (err-if-unacceptable-function new-value '(setf fdefinition))
355 (with-single-package-locked-error (:symbol name "setting fdefinition of ~A")
356 (maybe-clobber-ftype name new-value)
358 ;; Check for hash-table stuff. Woe onto him that mixes encapsulation
359 ;; with this.
360 (when (and (symbolp name) (fboundp name)
361 (boundp '*user-hash-table-tests*))
362 (let ((old (symbol-function name)))
363 (declare (special *user-hash-table-tests*))
364 (dolist (spec *user-hash-table-tests*)
365 (cond ((eq old (second spec))
366 ;; test-function
367 (setf (second spec) new-value))
368 ((eq old (third spec))
369 ;; hash-function
370 (setf (third spec) new-value))))))
372 ;; FIXME: This is a good hook to have, but we should probably
373 ;; reserve it for users.
374 (let ((fdefn (find-or-create-fdefn name)))
375 ;; *SETF-FDEFINITION-HOOK* won't be bound when initially running
376 ;; top level forms in the kernel core startup.
377 (when (boundp '*setf-fdefinition-hook*)
378 (dolist (f *setf-fdefinition-hook*)
379 (declare (type function f))
380 (funcall f name new-value)))
382 (let ((encap-info (encapsulation-info (fdefn-fun fdefn))))
383 (cond (encap-info
384 (loop
385 (let ((more-info
386 (encapsulation-info
387 (encapsulation-info-definition encap-info))))
388 (if more-info
389 (setf encap-info more-info)
390 (return
391 (setf (encapsulation-info-definition encap-info)
392 new-value))))))
394 (setf (fdefn-fun fdefn) new-value)))))))
396 ;;;; FBOUNDP and FMAKUNBOUND
398 (defun fboundp (name)
399 "Return true if name has a global function definition."
400 (declare (explicit-check))
401 (let ((fdefn (find-fdefn name)))
402 (and fdefn (fdefn-fun fdefn) t)))
404 (defun fmakunbound (name)
405 "Make NAME have no global function definition."
406 (declare (explicit-check))
407 (with-single-package-locked-error
408 (:symbol name "removing the function or macro definition of ~A")
409 (let ((fdefn (find-fdefn name)))
410 (when fdefn
411 (fdefn-makunbound fdefn)))
412 (undefine-fun-name name)
413 name))