x86-64: leave some registers out of *descriptor-args*.
[sbcl.git] / src / compiler / ir1tran-lambda.lisp
blob729e5d97530f218930568b160a9e44c597f01e36
1 ;;;; This file contains code which does the translation of lambda
2 ;;;; forms from Lisp code to the first intermediate representation
3 ;;;; (IR1).
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
14 (in-package "SB-C")
16 ;;;; LAMBDA hackery
18 ;;;; Note: Take a look at the compiler-overview.tex section on "Hairy
19 ;;;; function representation" before you seriously mess with this
20 ;;;; stuff.
21 (declaim (start-block ir1-convert-lambda ir1-convert-lambda-body
22 ir1-convert-aux-bindings varify-lambda-arg
23 ir1-convert-lambdalike))
25 ;;; Return a VAR structure for NAME, filling in info if it is globally
26 ;;; special. If it is losing, we punt with a COMPILER-ERROR.
27 (defun varify-lambda-arg (name &optional source-form)
28 (declare (type symbol name))
29 (case (info :variable :kind name)
30 (:special
31 (let ((variable (find-free-var name)))
32 (make-lambda-var :%source-name name
33 :type (leaf-type variable)
34 :where-from (leaf-where-from variable)
35 :specvar variable)))
37 (make-lambda-var :%source-name name
38 :source-form source-form))))
40 ;;; Parse a lambda list into a list of VAR structures, stripping off
41 ;;; any &AUX bindings. Each arg name is checked for legality, and
42 ;;; duplicate names are checked for. If an arg is globally special,
43 ;;; the var is marked as :SPECIAL instead of :LEXICAL. &KEY,
44 ;;; &OPTIONAL and &REST args are annotated with an ARG-INFO structure
45 ;;; which contains the extra information. If we hit something losing,
46 ;;; we bug out with COMPILER-ERROR. These values are returned:
47 ;;; 1. a list of the var structures for each top level argument;
48 ;;; 2. a flag indicating whether &KEY was specified;
49 ;;; 3. a flag indicating whether other &KEY args are allowed;
50 ;;; 4. a list of the &AUX variables; and
51 ;;; 5. a list of the &AUX values.
52 (declaim (ftype (sfunction (list) (values list boolean boolean list list))
53 make-lambda-vars))
54 (defun make-lambda-vars (list)
55 (multiple-value-bind (llks required optional rest/more keys aux)
56 (multiple-value-call #'check-lambda-list-names (parse-lambda-list list))
57 (collect ((vars)
58 (aux-vars)
59 (aux-vals))
60 (flet ((add-var (name &optional source-form)
61 (let ((var (varify-lambda-arg name)))
62 (setf (lambda-var-source-form var) source-form)
63 (vars var)
64 var))
65 (add-info (var kind &key (default nil defaultp) suppliedp-var key)
66 (let ((info (make-arg-info :kind kind)))
67 (when defaultp
68 (setf (arg-info-default info) default
69 (arg-info-default-p info) t))
70 (when suppliedp-var
71 (setf (arg-info-supplied-p info)
72 (varify-lambda-arg suppliedp-var)))
73 (when key
74 (setf (arg-info-key info) key))
75 (setf (lambda-var-arg-info var) info))))
76 ;; Required
77 (mapc #'add-var required)
78 ;; Optional
79 (dolist (spec optional)
80 (multiple-value-bind (name default suppliedp-var defaultp)
81 (parse-optional-arg-spec spec)
82 (apply #'add-info (add-var name) :optional
83 :suppliedp-var (first suppliedp-var)
84 (when defaultp (list :default default)))))
85 ;; Rest/more
86 (when rest/more
87 (mapc (lambda (name kind)
88 (add-info (add-var name) kind))
89 rest/more (let ((morep (eq (ll-kwds-restp llks) '&more)))
90 (if morep '(:more-context :more-count) '(:rest)))))
91 ;; Keys
92 (dolist (spec keys)
93 (multiple-value-bind (keyword name default suppliedp-var defaultp)
94 (parse-key-arg-spec spec)
95 (apply #'add-info (add-var name spec) :keyword
96 :suppliedp-var (first suppliedp-var)
97 :key keyword
98 (when defaultp (list :default default)))))
99 ;; Aux
100 (dolist (spec aux)
101 (multiple-value-bind (name val)
102 (if (atom spec) spec (values (car spec) (cadr spec)))
103 (let ((var (varify-lambda-arg name)))
104 (aux-vars var)
105 (aux-vals val))))
107 (values (vars) (ll-kwds-keyp llks) (ll-kwds-allowp llks)
108 (aux-vars) (aux-vals))))))
110 ;;; This is similar to IR1-CONVERT-PROGN-BODY except that we
111 ;;; sequentially bind each AUX-VAR to the corresponding AUX-VAL before
112 ;;; converting the body. If there are no bindings, just convert the
113 ;;; body, otherwise do one binding and recurse on the rest.
115 ;;; FIXME: This could and probably should be converted to use
116 ;;; SOURCE-NAME and DEBUG-NAME. But I (WHN) don't use &AUX bindings,
117 ;;; so I'm not motivated. Patches will be accepted...
118 (defun ir1-convert-aux-bindings (start next result body aux-vars aux-vals
119 post-binding-lexenv &key value-source-forms)
120 (declare (type ctran start next) (type (or lvar null) result)
121 (list body aux-vars aux-vals))
122 (if (null aux-vars)
123 (let ((*lexenv* (make-lexenv :vars post-binding-lexenv)))
124 (ir1-convert-progn-body start next result body))
125 (let ((ctran (make-ctran))
126 (fun-lvar (make-lvar))
127 (fun (ir1-convert-lambda-body body
128 (list (first aux-vars))
129 :aux-vars (rest aux-vars)
130 :aux-vals (rest aux-vals)
131 :post-binding-lexenv post-binding-lexenv
132 :debug-name (debug-name
133 '&aux-bindings
134 (mapcar #'leaf-source-name
135 aux-vars))
136 :value-source-forms (rest value-source-forms))))
137 (reference-leaf start ctran fun-lvar fun)
138 (ir1-convert-combination-args fun-lvar ctran next result
139 (list (first aux-vals))
140 :arg-source-forms (list (first value-source-forms)))))
141 (values))
143 ;;; This is similar to IR1-CONVERT-PROGN-BODY except that code to bind
144 ;;; the SPECVAR for each SVAR to the value of the variable is wrapped
145 ;;; around the body. If there are no special bindings, we just convert
146 ;;; the body, otherwise we do one special binding and recurse on the
147 ;;; rest.
149 ;;; We make a cleanup and introduce it into the lexical
150 ;;; environment. If there are multiple special bindings, the cleanup
151 ;;; for the blocks will end up being the innermost one. We force NEXT
152 ;;; to start a block outside of this cleanup, causing cleanup code to
153 ;;; be emitted when the scope is exited.
154 (defun ir1-convert-special-bindings
155 (start next result body aux-vars aux-vals svars post-binding-lexenv
156 &key value-source-forms)
157 (declare (type ctran start next) (type (or lvar null) result)
158 (list body aux-vars aux-vals svars))
159 (cond
160 ((null svars)
161 (ir1-convert-aux-bindings start next result body aux-vars aux-vals
162 post-binding-lexenv
163 :value-source-forms value-source-forms))
165 (ctran-starts-block next)
166 (let ((cleanup (make-cleanup :kind :special-bind))
167 (var (first svars))
168 (bind-ctran (make-ctran))
169 (cleanup-ctran (make-ctran)))
170 (ir1-convert start bind-ctran nil
171 `(%special-bind ',(lambda-var-specvar var) ,var))
172 (setf (cleanup-mess-up cleanup) (ctran-use bind-ctran))
173 (let ((*lexenv* (make-lexenv :cleanup cleanup)))
174 (ir1-convert bind-ctran cleanup-ctran nil '(%cleanup-point))
175 (ir1-convert-special-bindings cleanup-ctran next result
176 body aux-vars aux-vals
177 (rest svars)
178 post-binding-lexenv
179 :value-source-forms value-source-forms)))))
180 (values))
182 ;;; Create a lambda node out of some code, returning the result. The
183 ;;; bindings are specified by the list of VAR structures VARS. We deal
184 ;;; with adding the names to the LEXENV-VARS for the conversion. The
185 ;;; result is added to the NEW-FUNCTIONALS in the *CURRENT-COMPONENT*
186 ;;; and linked to the component head and tail.
188 ;;; We detect special bindings here, replacing the original VAR in the
189 ;;; lambda list with a temporary variable. We then pass a list of the
190 ;;; special vars to IR1-CONVERT-SPECIAL-BINDINGS, which actually emits
191 ;;; the special binding code.
193 ;;; We ignore any ARG-INFO in the VARS, trusting that someone else is
194 ;;; dealing with &NONSENSE, except for &REST vars with DYNAMIC-EXTENT.
196 ;;; AUX-VARS is a list of VAR structures for variables that are to be
197 ;;; sequentially bound. Each AUX-VAL is a form that is to be evaluated
198 ;;; to get the initial value for the corresponding AUX-VAR.
199 (defun ir1-convert-lambda-body (body
200 vars
201 &key
202 aux-vars
203 aux-vals
204 (source-name '.anonymous.)
205 debug-name
206 (note-lexical-bindings t)
207 post-binding-lexenv
208 local-policy
209 value-source-forms)
210 (declare (list body vars aux-vars aux-vals))
212 ;; We're about to try to put new blocks into *CURRENT-COMPONENT*.
213 (aver-live-component *current-component*)
215 (let* ((bind (make-bind))
216 (lambda (make-clambda :vars vars
217 :bind bind
218 :%source-name source-name
219 :%debug-name debug-name
220 :lexenv (if local-policy
221 (make-lexenv :policy local-policy)
222 *lexenv*)))
223 (result-ctran (make-ctran))
224 (result-lvar (make-lvar)))
225 ;; just to check: This function should fail internal assertions if
226 ;; we didn't set up a valid debug name above.
228 ;; (In SBCL we try to make everything have a debug name, since we
229 ;; lack the omniscient perspective the original implementors used
230 ;; to decide which things didn't need one.)
231 (functional-debug-name lambda)
233 (setf (lambda-home lambda) lambda)
234 (collect ((svars)
235 (new-venv nil cons))
237 (dolist (var vars)
238 ;; As far as I can see, LAMBDA-VAR-HOME should never have
239 ;; been set before. Let's make sure. -- WHN 2001-09-29
240 (aver (not (lambda-var-home var)))
241 (setf (lambda-var-home var) lambda)
242 (let ((specvar (lambda-var-specvar var)))
243 (cond (specvar
244 (svars var)
245 (new-venv (cons (leaf-source-name specvar) specvar)))
247 (when note-lexical-bindings
248 (note-lexical-binding (leaf-source-name var)))
249 (new-venv (cons (leaf-source-name var) var))))))
251 (let ((*lexenv* (make-lexenv :vars (new-venv)
252 :lambda lambda
253 :cleanup nil)))
254 (setf (bind-lambda bind) lambda)
255 (setf (node-lexenv bind) *lexenv*)
257 (let ((block (ctran-starts-block result-ctran)))
258 (let ((return (make-return :result result-lvar :lambda lambda))
259 (tail-set (make-tail-set :funs (list lambda))))
260 (setf (lambda-tail-set lambda) tail-set)
261 (setf (lambda-return lambda) return)
262 (setf (lvar-dest result-lvar) return)
263 (link-node-to-previous-ctran return result-ctran)
264 (setf (block-last block) return))
265 (link-blocks block (component-tail *current-component*)))
267 (with-component-last-block (*current-component*
268 (ctran-block result-ctran))
269 (let ((prebind-ctran (make-ctran))
270 (postbind-ctran (make-ctran)))
271 (ctran-starts-block prebind-ctran)
272 (link-node-to-previous-ctran bind prebind-ctran)
273 (use-ctran bind postbind-ctran)
274 (ir1-convert-special-bindings postbind-ctran result-ctran
275 result-lvar body
276 aux-vars aux-vals (svars)
277 post-binding-lexenv
278 :value-source-forms value-source-forms)))))
280 (link-blocks (component-head *current-component*) (node-block bind))
281 (push lambda (component-new-functionals *current-component*))
283 lambda))
285 ;;; Entry point CLAMBDAs have a special kind
286 (defun register-entry-point (entry dispatcher)
287 (declare (type clambda entry)
288 (type optional-dispatch dispatcher))
289 (setf (functional-kind entry) (functional-kind-attributes optional))
290 (setf (leaf-ever-used entry) t)
291 (setf (lambda-optional-dispatch entry) dispatcher)
292 entry)
294 ;;; Create the actual entry-point function for an optional entry
295 ;;; point. The lambda binds copies of each of the VARS, then calls FUN
296 ;;; with the argument VALS and the DEFAULTS. Presumably the VALS refer
297 ;;; to the VARS by name. The VALS are passed in the reverse order.
299 ;;; If any of the copies of the vars are referenced more than once,
300 ;;; then we mark the corresponding var as EVER-USED to inhibit
301 ;;; "defined but not read" warnings for arguments that are only used
302 ;;; by default forms.
303 (defun convert-optional-entry (fun vars vals defaults name)
304 (declare (type clambda fun) (list vars vals defaults))
305 (let* ((fvars (reverse vars))
306 (arg-vars (mapcar (lambda (var)
307 (make-lambda-var
308 :%source-name (leaf-source-name var)
309 :type (leaf-type var)
310 :where-from (leaf-where-from var)
311 :specvar (lambda-var-specvar var)))
312 fvars))
313 (fun (collect ((default-bindings)
314 (default-vals))
315 (dolist (default defaults)
316 (if (constantp default)
317 (default-vals default)
318 (let ((var (gensym)))
319 (default-bindings `(,var ,default))
320 (default-vals var))))
321 (let ((bindings (default-bindings))
322 (call
323 `(locally
324 ;; See lengthy comment at top of 'seqtran'
325 ;; as to why muffling is not done during xc.
326 #-sb-xc-host
327 (declare (muffle-conditions code-deletion-note))
328 (%funcall ,fun ,@(reverse vals) ,@(default-vals)))))
329 (ir1-convert-lambda-body (if bindings
330 `((let (,@bindings) ,call))
331 `(,call))
332 arg-vars
333 ;; FIXME: Would be nice to
334 ;; share these names instead
335 ;; of consing up several
336 ;; identical ones. Oh well.
337 :debug-name (debug-name
338 '&optional-processor
339 name)
340 :note-lexical-bindings nil)))))
341 (mapc (lambda (var arg-var)
342 (when (cdr (leaf-refs arg-var))
343 (setf (leaf-ever-used var) t)))
344 fvars arg-vars)
345 fun))
347 ;;; This function deals with supplied-p vars in optional arguments. If
348 ;;; there is no supplied-p arg, then we just call
349 ;;; IR1-CONVERT-HAIRY-ARGS on the remaining arguments, and generate a
350 ;;; optional entry that calls the result. If there is a supplied-p
351 ;;; var, then we add it into the default vars and throw a T into the
352 ;;; entry values. The resulting entry point function is returned.
353 (defun generate-optional-default-entry (res default-vars default-vals
354 entry-vars entry-vals
355 vars supplied-p-p body
356 aux-vars aux-vals
357 source-name debug-name
358 force post-binding-lexenv)
359 (declare (type optional-dispatch res)
360 (list default-vars default-vals entry-vars entry-vals vars body
361 aux-vars aux-vals))
362 (let* ((arg (first vars))
363 (arg-name (leaf-source-name arg))
364 (info (lambda-var-arg-info arg))
365 (default (arg-info-default info))
366 (supplied-p (arg-info-supplied-p info))
367 (force (or force
368 (not (constantp (arg-info-default info)))))
369 (ep (if supplied-p
370 (ir1-convert-hairy-args
372 (list* supplied-p arg default-vars)
373 (list* (leaf-source-name supplied-p) arg-name default-vals)
374 (cons arg entry-vars)
375 (list* t arg-name entry-vals)
376 (rest vars) t body aux-vars aux-vals
377 source-name debug-name
378 force post-binding-lexenv)
379 (ir1-convert-hairy-args
381 (cons arg default-vars)
382 (cons arg-name default-vals)
383 (cons arg entry-vars)
384 (cons arg-name entry-vals)
385 (rest vars) supplied-p-p body aux-vars aux-vals
386 source-name debug-name
387 force post-binding-lexenv))))
389 ;; We want to delay converting the entry, but there exist
390 ;; problems: hidden references should not be established to
391 ;; lambdas of kind NIL should not have (otherwise the compiler
392 ;; might let-convert or delete them) and to variables.
393 (let ((name (or debug-name source-name)))
394 (if (or force
395 supplied-p-p ; this entry will be of kind NIL
396 (and (lambda-p ep) (functional-kind-eq ep nil)))
397 (convert-optional-entry ep
398 default-vars default-vals
399 (if supplied-p (list default nil) (list default))
400 name)
401 (let* ((value (constant-form-value default))
402 ;; One-and-only-once-more: MAYBE-EMIT-MAKE-LOAD-FORMS has a similar test.
403 (namedp-not-eql-comparable
404 (and (symbolp default)
405 (not (typep value '(or symbol character number)))))
406 (default (if namedp-not-eql-comparable default `',value))
407 (defaults (if supplied-p (list default nil) (list default))))
408 ;; DEFAULT can contain a reference to a
409 ;; to-be-optimized-away function/block/tag, so better to
410 ;; reduce code now (but we possibly lose syntax checking
411 ;; in an unreachable code).
412 (delay
413 (register-entry-point
414 (convert-optional-entry (force ep)
415 default-vars default-vals
416 defaults
417 name)
418 res)))))))
420 ;;; Create the MORE-ENTRY function for the OPTIONAL-DISPATCH RES.
421 ;;; ENTRY-VARS and ENTRY-VALS describe the fixed arguments. REST is
422 ;;; the var for any &REST arg. KEYS is a list of the &KEY arg vars.
424 ;;; The most interesting thing that we do is parse keywords. We create
425 ;;; a bunch of temporary variables to hold the result of the parse,
426 ;;; and then loop over the supplied arguments, setting the appropriate
427 ;;; temps for the supplied keyword. Note that it is significant that
428 ;;; we iterate over the keywords in reverse order --- this implements
429 ;;; the CL requirement that (when a keyword appears more than once)
430 ;;; the first value is used.
432 ;;; If there is no supplied-p var, then we initialize the temp to the
433 ;;; default and just pass the temp into the main entry. Since
434 ;;; non-constant &KEY args are forcibly given a supplied-p var, we
435 ;;; know that the default is constant, and thus safe to evaluate out
436 ;;; of order.
438 ;;; If there is a supplied-p var, then we create temps for both the
439 ;;; value and the supplied-p, and pass them into the main entry,
440 ;;; letting it worry about defaulting.
442 ;;; We deal with :ALLOW-OTHER-KEYS by delaying unknown keyword errors
443 ;;; until we have scanned all the keywords.
444 (defun convert-more-entry (res entry-vars entry-vals rest morep keys name)
445 (declare (type optional-dispatch res) (list entry-vars entry-vals keys))
446 (collect ((arg-vars)
447 (arg-vals (reverse entry-vals))
448 (temps)
449 (body))
451 (dolist (var (reverse entry-vars))
452 (arg-vars (make-lambda-var :%source-name (leaf-source-name var)
453 :type (leaf-type var)
454 :where-from (leaf-where-from var))))
456 (let* ((*allow-instrumenting* nil)
457 (n-context (gensym "N-CONTEXT-"))
458 (context-temp (make-lambda-var :%source-name n-context
459 :arg-info (make-arg-info :kind :more-context)))
460 (n-count (gensym "N-COUNT-"))
461 (count-temp (make-lambda-var :%source-name n-count
462 :type (specifier-type 'index)
463 :arg-info (make-arg-info :kind :more-count))))
465 (arg-vars context-temp count-temp)
467 (when rest
468 (arg-vals `(%listify-rest-args ,n-context ,n-count)))
469 (when morep
470 (arg-vals n-context)
471 (arg-vals n-count))
473 ;; The reason for all the noise with
474 ;; STACK-GROWS-DOWNWARD-NOT-UPWARD is to enable generation of
475 ;; slightly more efficient code on x86oid processors. (We can
476 ;; hoist the negation of the index outside the main parsing loop
477 ;; and take advantage of the base+index+displacement addressing
478 ;; mode on x86oids.)
479 (when (optional-dispatch-keyp res)
480 (let ((n-index (gensym "N-INDEX-"))
481 (n-key (gensym "N-KEY-"))
482 (n-value-temp (gensym "N-VALUE-TEMP-"))
483 (n-allowp (gensym "N-ALLOWP-"))
484 (n-lose (gensym "N-LOSE-"))
485 (allowp (or (optional-dispatch-allowp res)
486 (policy *lexenv* (zerop safety))))
487 (found-allow-p nil))
489 (temps #-stack-grows-downward-not-upward
490 `(,n-index (+ ,n-count ,(if (vop-existsp :translate %more-kw-arg)
492 -1)))
493 #+stack-grows-downward-not-upward
494 `(,n-index (- (1- ,n-count))))
495 (body `(declare (fixnum ,n-index)))
497 (collect ((tests))
498 (dolist (key keys)
499 (let* ((info (lambda-var-arg-info key))
500 (default (arg-info-default info))
501 (keyword (arg-info-key info))
502 (supplied-p (arg-info-supplied-p info))
503 (supplied-used-p (arg-info-supplied-used-p info))
504 (n-value (gensym "N-VALUE-"))
505 (clause (cond (supplied-p
506 (let ((n-supplied (gensym "N-SUPPLIED-")))
507 (temps (list n-supplied
508 (if supplied-used-p
510 0)))
511 (arg-vals n-value n-supplied)
512 `((,keyword)
513 (setq ,n-supplied ,(if supplied-used-p
516 (setq ,n-value ,n-value-temp))))
518 (arg-vals n-value)
519 `((,keyword)
520 (setq ,n-value ,n-value-temp))))))
521 (when (and (not allowp) (eq keyword :allow-other-keys))
522 (setq found-allow-p t)
523 (setq clause
524 (append clause `((setq ,n-allowp ,n-value-temp)))))
525 (temps `(,n-value ,(if (and default
526 (neq (lambda-var-type key) *universal-type*))
527 `(the* (,(lambda-var-type key)
528 :use-annotations t
529 :source-form ,(lambda-var-source-form key))
530 ,default)
531 default)))
532 (tests clause)))
534 (unless allowp
535 (temps n-allowp
536 (list n-lose '(make-unbound-marker)))
537 (unless found-allow-p
538 (tests `(:allow-other-keys
539 (setq ,n-allowp ,n-value-temp))))
540 (tests `(t
541 (setq ,n-lose ,n-key))))
543 (body
544 `(when (oddp ,(cond #-stack-grows-downward-not-upward
545 ((vop-existsp :translate %more-kw-arg)
546 n-index)
548 n-count)))
549 (%odd-key-args-error)))
551 (body
552 #-stack-grows-downward-not-upward
553 `(locally
554 (declare (optimize (safety 0)))
555 (loop
556 ,@(cond ((vop-existsp :translate %more-kw-arg)
557 `((when (zerop ,n-index) (return))
558 (decf ,n-index 2)
559 (multiple-value-bind (,n-value-temp ,n-key)
560 (%more-kw-arg ,n-context ,n-index)
561 (declare (ignorable ,n-value-temp ,n-key))
562 (case ,n-key ,@(tests)))))
564 `((when (minusp ,n-index) (return))
565 (let ((,n-value-temp (%more-arg ,n-context ,n-index))
566 (,n-key (%more-arg ,n-context (decf ,n-index))))
567 (declare (ignorable ,n-value-temp ,n-key))
568 (decf ,n-index)
569 (case ,n-key ,@(tests))))))))
570 #+stack-grows-downward-not-upward
571 `(locally (declare (optimize (safety 0)))
572 (loop
573 (when (plusp ,n-index) (return))
574 (multiple-value-bind (,n-value-temp ,n-key)
575 (%more-kw-arg ,n-context ,n-index)
576 (declare (ignorable ,n-value-temp ,n-key))
577 (incf ,n-index 2)
578 (case ,n-key ,@(tests))))))
580 (unless allowp
581 (let ((location (make-restart-location)))
582 (body `(if (and (not (unbound-marker-p ,n-lose))
583 (not ,n-allowp))
584 (%unknown-key-arg-error ,n-lose ,location)
585 (restart-point ,location))))))))
587 (let ((ep (ir1-convert-lambda-body
588 `((let ,(temps)
589 ,@(body)
590 (%funcall ,(optional-dispatch-main-entry res)
591 ,@(arg-vals))))
592 (arg-vars)
593 :debug-name (debug-name '&more-processor name)
594 :note-lexical-bindings nil)))
595 (setf (optional-dispatch-more-entry res)
596 (register-entry-point ep res)))))
598 (values))
600 ;;; This is called by IR1-CONVERT-HAIRY-ARGS when we run into a &REST
601 ;;; or &KEY arg. The arguments are similar to that function, but we
602 ;;; split off any &REST arg and pass it in separately. REST is the
603 ;;; &REST arg var, or NIL if there is no &REST arg. KEYS is a list of
604 ;;; the &KEY argument vars.
606 ;;; When there are &KEY arguments, we introduce temporary gensym
607 ;;; variables to hold the values while keyword defaulting is in
608 ;;; progress to get the required sequential binding semantics.
610 ;;; This gets interesting mainly when there are &KEY arguments with
611 ;;; supplied-p vars or non-constant defaults. In either case, pass in
612 ;;; a supplied-p var. If the default is non-constant, we introduce an
613 ;;; IF in the main entry that tests the supplied-p var and decides
614 ;;; whether to evaluate the default or not. In this case, the real
615 ;;; incoming value is NIL, so we must union NULL with the declared
616 ;;; type when computing the type for the main entry's argument.
617 (defun ir1-convert-more (res default-vars default-vals entry-vars entry-vals
618 rest more-context more-count keys supplied-p-p
619 body aux-vars aux-vals source-name debug-name
620 post-binding-lexenv)
621 (declare (type optional-dispatch res)
622 (list default-vars default-vals entry-vars entry-vals keys body
623 aux-vars aux-vals))
624 (collect ((main-vars (reverse default-vars))
625 (main-vals default-vals cons)
626 (bind-vars)
627 (bind-vals))
628 (when rest
629 (main-vars rest)
630 (main-vals '())
631 (unless (lambda-var-ignorep rest)
632 ;; Make up two extra variables, and squirrel them away in
633 ;; ARG-INFO-DEFAULT for transforming (VALUES-LIST REST) into
634 ;; (%MORE-ARG-VALUES CONTEXT 0 COUNT) when possible.
635 (let* ((context-name (gensym "REST-CONTEXT-"))
636 (context (make-lambda-var :%source-name context-name
637 :arg-info (make-arg-info :kind :more-context)))
638 (count-name (gensym "REST-COUNT-"))
639 (count (make-lambda-var :%source-name count-name
640 :arg-info (make-arg-info :kind :more-count)
641 :type (specifier-type 'index))))
642 (setf (arg-info-default (lambda-var-arg-info rest)) (list context count)
643 (lambda-var-ever-used context) t
644 (lambda-var-ever-used count) t)
645 (setf more-context context
646 more-count count))))
647 (when more-context
648 (main-vars more-context)
649 (main-vals nil)
650 (main-vars more-count)
651 (main-vals 0))
653 (dolist (key keys)
654 (let* ((info (lambda-var-arg-info key))
655 (default (arg-info-default info))
656 (hairy-default (not (constantp default)))
657 (supplied-p (arg-info-supplied-p info))
658 ;; was: (format nil "~A-DEFAULTING-TEMP" (leaf-source-name key))
659 (n-val (make-symbol ".DEFAULTING-TEMP."))
660 (val-temp (make-lambda-var :%source-name n-val))
661 (default `(with-source-form ,(lambda-var-source-form key)
662 ,default)))
663 (main-vars val-temp)
664 (bind-vars key)
665 (cond ((or hairy-default supplied-p)
666 (let* ((n-supplied (gensym "N-SUPPLIED-"))
667 (supplied-temp (make-lambda-var
668 :%source-name n-supplied)))
669 (unless supplied-p
670 (setf (arg-info-supplied-p info) supplied-temp))
671 (when hairy-default
672 (setf (arg-info-default info) nil)
673 (unless supplied-p
674 (setf (arg-info-supplied-used-p info) nil)))
675 (main-vars supplied-temp)
676 (cond (hairy-default
677 (main-vals nil
678 (if supplied-p
681 (bind-vals
682 (if supplied-p
683 `(if ,n-supplied ,n-val ,default)
684 `(if (eq ,n-supplied 0) ,default ,n-val))))
686 (main-vals default nil)
687 (bind-vals n-val)))
688 (when supplied-p
689 (bind-vars supplied-p)
690 (bind-vals n-supplied))))
692 (main-vals default)
693 (bind-vals n-val)))))
695 (let* ((main-entry (ir1-convert-lambda-body
696 body (main-vars)
697 :aux-vars (append (bind-vars) aux-vars)
698 :aux-vals (append (bind-vals) aux-vals)
699 :post-binding-lexenv post-binding-lexenv
700 :source-name source-name
701 :debug-name debug-name))
702 (name (or debug-name source-name))
703 (last-entry (convert-optional-entry main-entry default-vars
704 (main-vals) () name)))
705 (setf (optional-dispatch-main-entry res)
706 (register-entry-point main-entry res))
707 (convert-more-entry res entry-vars entry-vals rest more-context keys
708 name)
710 (push (register-entry-point
711 (if supplied-p-p
712 (convert-optional-entry last-entry entry-vars entry-vals
713 () name)
714 last-entry)
715 res)
716 (optional-dispatch-entry-points res))
717 last-entry)))
719 ;;; This function generates the entry point functions for the
720 ;;; OPTIONAL-DISPATCH RES. We accomplish this by recursion on the list
721 ;;; of arguments, analyzing the arglist on the way down and generating
722 ;;; entry points on the way up.
724 ;;; DEFAULT-VARS is a reversed list of all the argument vars processed
725 ;;; so far, including supplied-p vars. DEFAULT-VALS is a list of the
726 ;;; names of the DEFAULT-VARS.
728 ;;; ENTRY-VARS is a reversed list of processed argument vars,
729 ;;; excluding supplied-p vars. ENTRY-VALS is a list things that can be
730 ;;; evaluated to get the values for all the vars from the ENTRY-VARS.
731 ;;; It has the var name for each required or optional arg, and has T
732 ;;; for each supplied-p arg.
734 ;;; VARS is a list of the LAMBDA-VAR structures for arguments that
735 ;;; haven't been processed yet. SUPPLIED-P-P is true if a supplied-p
736 ;;; argument has already been processed; only in this case are the
737 ;;; DEFAULT-XXX and ENTRY-XXX different.
739 ;;; The result at each point is a lambda which should be called by the
740 ;;; above level to default the remaining arguments and evaluate the
741 ;;; body. We cause the body to be evaluated by converting it and
742 ;;; returning it as the result when the recursion bottoms out.
744 ;;; Each level in the recursion also adds its entry point function to
745 ;;; the result OPTIONAL-DISPATCH. For most arguments, the defaulting
746 ;;; function and the entry point function will be the same, but when
747 ;;; SUPPLIED-P args are present they may be different.
749 ;;; When we run into a &REST or &KEY arg, we punt out to
750 ;;; IR1-CONVERT-MORE, which finishes for us in this case.
751 (defun ir1-convert-hairy-args (res default-vars default-vals
752 entry-vars entry-vals
753 vars supplied-p-p body aux-vars
754 aux-vals
755 source-name debug-name
756 force post-binding-lexenv)
757 (declare (type optional-dispatch res)
758 (list default-vars default-vals entry-vars entry-vals vars body
759 aux-vars aux-vals))
760 (aver (or debug-name (neq '.anonymous. source-name)))
761 (cond ((not vars)
762 (if (optional-dispatch-keyp res)
763 ;; Handle &KEY with no keys...
764 (ir1-convert-more res default-vars default-vals
765 entry-vars entry-vals
766 nil nil nil vars supplied-p-p body aux-vars
767 aux-vals source-name debug-name
768 post-binding-lexenv)
769 (let* ((name (or debug-name source-name))
770 (fun (ir1-convert-lambda-body
771 body (reverse default-vars)
772 :aux-vars aux-vars
773 :aux-vals aux-vals
774 :post-binding-lexenv post-binding-lexenv
775 :source-name source-name
776 :debug-name debug-name)))
778 (setf (optional-dispatch-main-entry res) fun)
779 (register-entry-point fun res)
780 (push (if supplied-p-p
781 (register-entry-point
782 (convert-optional-entry fun entry-vars entry-vals ()
783 name)
784 res)
785 fun)
786 (optional-dispatch-entry-points res))
787 fun)))
788 ((not (lambda-var-arg-info (first vars)))
789 (let* ((arg (first vars))
790 (nvars (cons arg default-vars))
791 (nvals (cons (leaf-source-name arg) default-vals)))
792 (ir1-convert-hairy-args res nvars nvals nvars nvals
793 (rest vars) nil body aux-vars aux-vals
794 source-name debug-name
795 nil post-binding-lexenv)))
797 (let* ((arg (first vars))
798 (info (lambda-var-arg-info arg))
799 (kind (arg-info-kind info)))
800 (ecase kind
801 (:optional
802 (let ((ep (generate-optional-default-entry
803 res default-vars default-vals
804 entry-vars entry-vals vars supplied-p-p body
805 aux-vars aux-vals
806 source-name debug-name
807 force post-binding-lexenv)))
808 ;; See GENERATE-OPTIONAL-DEFAULT-ENTRY.
809 (push (if (lambda-p ep)
810 (register-entry-point
811 (if supplied-p-p
812 (convert-optional-entry
813 ep entry-vars entry-vals nil
814 (or debug-name source-name))
816 res)
817 (progn (aver (not supplied-p-p))
818 ep))
819 (optional-dispatch-entry-points res))
820 ep))
821 (:rest
822 (ir1-convert-more res default-vars default-vals
823 entry-vars entry-vals
824 arg nil nil (rest vars) supplied-p-p body
825 aux-vars aux-vals
826 source-name debug-name
827 post-binding-lexenv))
828 (:more-context
829 (ir1-convert-more res default-vars default-vals
830 entry-vars entry-vals
831 nil arg (second vars) (cddr vars) supplied-p-p
832 body aux-vars aux-vals
833 source-name debug-name
834 post-binding-lexenv))
835 (:keyword
836 (ir1-convert-more res default-vars default-vals
837 entry-vars entry-vals
838 nil nil nil vars supplied-p-p body aux-vars
839 aux-vals source-name debug-name
840 post-binding-lexenv)))))))
842 ;;; This function deals with the case where we have to make an
843 ;;; OPTIONAL-DISPATCH to represent a LAMBDA. We cons up the result and
844 ;;; call IR1-CONVERT-HAIRY-ARGS to do the work. When it is done, we
845 ;;; figure out the MIN-ARGS and MAX-ARGS.
846 (defun ir1-convert-hairy-lambda (body vars keyp allowp aux-vars aux-vals
847 &key post-binding-lexenv
848 (source-name '.anonymous.)
849 debug-name)
850 (declare (list body vars aux-vars aux-vals))
851 (aver (or debug-name (neq '.anonymous. source-name)))
852 (let ((res (make-optional-dispatch :arglist vars
853 :allowp allowp
854 :keyp keyp
855 :%source-name source-name
856 :%debug-name debug-name
857 :source-path *current-path*))
858 (min (or (position-if #'lambda-var-arg-info vars) (length vars))))
859 (aver-live-component *current-component*)
860 (ir1-convert-hairy-args res () () () () vars nil body aux-vars aux-vals
861 source-name debug-name nil post-binding-lexenv)
862 ;; ir1-convert-hairy-args can throw 'locall-already-let-converted
863 ;; push optional-dispatch into the current component only after it
864 ;; normally returned
865 (push res (component-new-functionals *current-component*))
866 (setf (optional-dispatch-min-args res) min)
867 (setf (optional-dispatch-max-args res)
868 (+ (1- (length (optional-dispatch-entry-points res))) min))
870 res))
872 (defvar *lambda-conversions*)
874 (defun add-types-for-fixed-args (fun vars)
875 (let ((fun-info (info :function :info fun)))
876 (when (or (and fun-info
877 (ir1-attributep (fun-info-attributes fun-info) fixed-args))
878 (typep fun '(cons (eql sb-impl::specialized-xep))))
879 (loop for type in (fun-type-required (if (typep fun '(cons (eql sb-impl::specialized-xep)))
880 (specifier-type `(function ,@(cddr fun)))
881 (info :function :type fun)))
882 for var in vars
883 for intersection = (type-intersection type (lambda-var-type var))
884 unless (eq intersection *empty-type*)
885 do (setf (lambda-var-type var) intersection))))
886 vars)
888 ;;; Convert a LAMBDA form into a LAMBDA leaf or an OPTIONAL-DISPATCH leaf.
889 (defun ir1-convert-lambda (form &key (source-name '.anonymous.)
890 debug-name maybe-add-debug-catch)
891 (unless (consp form)
892 (compiler-error "A ~S was found when expecting a lambda expression:~% ~S"
893 (type-of form)
894 form))
895 (unless (eq (car form) 'lambda)
896 (compiler-error "~S was expected but ~S was found:~% ~S"
897 'lambda
898 (car form)
899 form))
900 (unless (and (consp (cdr form)) (listp (cadr form)))
901 (compiler-error
902 "The lambda expression has a missing or non-list lambda list:~% ~S"
903 form))
904 (unless (or debug-name (neq '.anonymous. source-name))
905 (setf debug-name (name-lambdalike form)))
906 (binding* (((forms decls doc) (parse-body (cddr form) t))
907 ((*lexenv* source-form) (process-muffle-decls decls *lexenv*))
908 (*current-path* (or (and source-form
909 (get-source-path source-form))
910 *current-path*))
911 ((vars keyp allow-other-keys aux-vars aux-vals)
912 (make-lambda-vars (cadr form)))
913 ((*lexenv* result-type post-binding-lexenv
914 lambda-list explicit-check source-form
915 local-policy)
916 (process-decls decls (append aux-vars vars) nil
917 :binding-form-p t :allow-lambda-list t))
918 (debug-catch-p (and maybe-add-debug-catch
919 *allow-instrumenting*
920 (policy *lexenv*
921 (>= insert-debug-catch 2))))
922 (forms (if debug-catch-p
923 (wrap-forms-in-debug-catch forms)
924 forms))
925 (forms (if (eq result-type *wild-type*)
926 forms
927 `((the ,(type-specifier result-type) (progn ,@forms)))))
928 (res (if (or (find-if #'lambda-var-arg-info vars) keyp)
929 (ir1-convert-hairy-lambda forms vars keyp
930 allow-other-keys
931 aux-vars aux-vals
932 :post-binding-lexenv post-binding-lexenv
933 :source-name source-name
934 :debug-name debug-name)
935 (ir1-convert-lambda-body forms
936 (add-types-for-fixed-args source-name vars)
937 :aux-vars aux-vars
938 :aux-vals aux-vals
939 :post-binding-lexenv post-binding-lexenv
940 :source-name source-name
941 :debug-name debug-name
942 :local-policy local-policy))))
943 (when explicit-check
944 (setf (getf (functional-plist res) 'explicit-check) explicit-check))
945 (setf (functional-inline-expansion res) (or source-form form))
946 (setf (functional-arg-documentation res)
947 (if (eq lambda-list :unspecified)
948 (strip-lambda-list (cadr form) :arglist)
949 lambda-list))
950 (setf (functional-documentation res) doc)
951 (when (boundp '*lambda-conversions*)
952 ;; KLUDGE: Not counting TL-XEPs is a lie, of course, but
953 ;; keeps things less confusing to users of TIME, where this
954 ;; count gets used.
955 (unless (and (consp debug-name) (eq 'tl-xep (car debug-name)))
956 (incf *lambda-conversions*)))
957 res))
959 (defun wrap-forms-in-debug-catch (forms)
960 #+unwind-to-frame-and-call-vop
961 `((multiple-value-prog1
962 (progn
963 ,@forms)
964 ;; Just ensure that there won't be any tail-calls, IR2 magic will
965 ;; handle the rest.
966 (values)))
967 #-unwind-to-frame-and-call-vop
968 `( ;; Normally, we'll return from this block with the below RETURN-FROM.
969 (block
970 return-value-tag
971 ;; If DEBUG-CATCH-TAG is thrown (with a thunk as the value) the
972 ;; RETURN-FROM is elided and we funcall the thunk instead. That
973 ;; thunk might either return a value (for a RETURN-FROM-FRAME)
974 ;; or call this same function again (for a RESTART-FRAME).
975 ;; -- JES, 2007-01-09
976 (funcall
977 (the function
978 ;; Use a constant catch tag instead of consing a new one for every
979 ;; entry to this block. The uniquencess of the catch tags is
980 ;; ensured when the tag is throw by the debugger. It'll allocate a
981 ;; new tag, and modify the reference this tag in the proper
982 ;; catch-block structure to refer to that new tag. This
983 ;; significantly decreases the runtime cost of high debug levels.
984 ;; -- JES, 2007-01-09
985 (catch 'debug-catch-tag
986 (return-from return-value-tag
987 (progn
988 ,@forms))))))))
990 ;;; helper for LAMBDA-like things, to massage them into a form
991 ;;; suitable for IR1-CONVERT-LAMBDA.
992 (defun ir1-convert-lambdalike (thing
993 &key
994 (source-name '.anonymous.)
995 debug-name)
996 (when (and (not debug-name) (eq '.anonymous. source-name))
997 (setf debug-name (name-lambdalike thing)))
998 (ecase (car thing)
999 ((lambda)
1000 (ir1-convert-lambda thing
1001 :maybe-add-debug-catch t
1002 :source-name source-name
1003 :debug-name debug-name))
1004 ((named-lambda)
1005 (let* ((name (cadr thing))
1006 (lambda-expression `(lambda ,@(cddr thing)))
1007 (*inline-expansions* (list name 1 *inline-expansions*)))
1008 (if (and name (legal-fun-name-p name))
1009 (let ((simple-lexenv-p (simple-lexical-environment-p *lexenv*)))
1010 ;; If not in a simple environment, then discard any
1011 ;; forward references to this function. If the lexical
1012 ;; environment is too hairy, then we only install the
1013 ;; definition during the processing of this NAMED-LAMBDA,
1014 ;; ensuring that the function cannot be called outside of
1015 ;; the correct environment. If the function is globally
1016 ;; NOTINLINE, then that inhibits even local substitution.
1017 (unless simple-lexenv-p
1018 (remhash name (free-funs *ir1-namespace*)))
1019 (let ((var (get-defined-fun name)))
1020 (setf (defined-fun-same-block-p var) t)
1022 ;; If there is a type from a previous definition, blast it, since it is
1023 ;; obsolete.
1024 (when (neq :declared (leaf-where-from var))
1025 (setf (leaf-type var)
1026 ;; Use the type from the lambda list so that self
1027 ;; calls warn about mismatched args.
1028 (let ((lambda-list (second lambda-expression)))
1029 (or (and lambda-list
1030 (ignore-errors
1031 (ftype-from-lambda-list lambda-list)))
1032 (specifier-type 'function)))))
1033 (ir1-convert-lambda-for-defun lambda-expression var simple-lexenv-p)))
1034 (ir1-convert-lambda lambda-expression
1035 :maybe-add-debug-catch t
1036 :debug-name
1037 (or name (name-lambdalike thing))))))))
1039 (declaim (end-block))
1041 ;;;; defining global functions
1043 ;;; Given a lambda-list, return a FUN-TYPE object representing the signature:
1044 ;;; return type is *, and each individual arguments type is T -- but we get
1045 ;;; the argument counts and keywords.
1046 ;;; TODO: enhance this to optionally accept an alist of (var . type)
1047 ;;; and use that lieu of SB-INTERPRETER:APPROXIMATE-PROTO-FN-TYPE.
1048 (defun ftype-from-lambda-list (lambda-list)
1049 (multiple-value-bind (llks req opt rest key-list)
1050 (parse-lambda-list lambda-list :silent t)
1051 (flet ((list-of-t (list) (mapcar (constantly t) list)))
1052 (let ((reqs (list-of-t req))
1053 (opts (when opt (cons '&optional (list-of-t opt))))
1054 ;; When it comes to building a type, &REST means pretty much the
1055 ;; same thing as &MORE.
1056 (rest (when rest '(&rest t)))
1057 (keys (when (ll-kwds-keyp llks)
1058 (cons '&key (mapcar (lambda (spec)
1059 (list (parse-key-arg-spec spec) t))
1060 key-list))))
1061 (allow (when (ll-kwds-allowp llks) '(&allow-other-keys))))
1062 (careful-specifier-type `(function (,@reqs ,@opts ,@rest ,@keys ,@allow) *))))))
1064 ;;; Return a lambda form that has been "closed" with respect to
1065 ;;; LEXENV, returning a LAMBDA-WITH-LEXENV if there are interesting
1066 ;;; declarations. To handle local macros, rather than closing over
1067 ;;; definitions in the environment, expand all macros in the body of
1068 ;;; LAMBDA, so that nothing in the syntactic environment is needed in
1069 ;;; the expansion. If there is something too complex in the lexical
1070 ;;; environment (like a lexical variable), then we return NIL.
1071 (defun inline-syntactic-closure-lambda (lambda lexenv)
1072 (declare (type list lambda) (type lexenv-designator lexenv))
1073 (aver (eql (first lambda) 'lambda))
1074 (typecase lexenv
1075 (lexenv
1076 (let ((vars (lexenv-vars lexenv))
1077 (funs (lexenv-funs lexenv))
1078 (decls ()))
1079 (cond ((or (lexenv-blocks lexenv) (lexenv-tags lexenv)) nil)
1080 ((and (null vars) (null funs)) lambda)
1081 ((dolist (x vars nil)
1082 (let ((name (car x))
1083 (what (cdr x)))
1084 (when (eq x (assoc name vars :test #'eq))
1085 (typecase what
1086 (cons
1087 (aver (eq (car what) 'macro)))
1088 (global-var
1089 (aver (eq (global-var-kind what) :special))
1090 (push `(special ,name) decls))
1091 (t (return t))))))
1092 nil)
1093 ((dolist (x funs nil)
1094 (let ((name (car x))
1095 (what (cdr x)))
1096 (when (eq x (assoc name funs :test #'equal))
1097 (typecase what
1098 (cons)
1099 ;; FIXME: Is there a good reason for this not to be
1100 ;; DEFINED-FUN (which :INCLUDEs GLOBAL-VAR, in case
1101 ;; you're wondering how this ever worked :-)? Maybe
1102 ;; in conjunction with an AVERrance that it's not an
1103 ;; (AND GLOBAL-VAR (NOT GLOBAL-FUN))? -- CSR,
1104 ;; 2002-07-08
1105 (global-var
1106 (when (defined-fun-p what)
1107 (push `(,(car (defined-fun-inlinep what))
1108 ,name)
1109 decls)))
1110 (t (return t))))))
1111 nil)
1113 (let ((expansion (sb-walker:macroexpand-all lambda lexenv)))
1114 (if decls
1115 `(lambda-with-lexenv ((declare ,@decls)) ,@(cdr expansion))
1116 expansion))))))
1117 #+(and sb-fasteval (not sb-xc-host))
1118 (sb-interpreter:basic-env
1119 (sb-interpreter::inline-syntactic-closure-lambda lambda lexenv))
1120 #+sb-fasteval
1121 (null lambda))) ; trivial case. Never occurs in the compiler.
1123 ;;; Convert FUN as a lambda in the null environment, but use the
1124 ;;; current compilation policy. Note that FUN may be a
1125 ;;; LAMBDA-WITH-LEXENV, so we may have to augment the environment to
1126 ;;; reflect the state at the definition site.
1127 (defun ir1-convert-inline-lambda (fun
1128 &key
1129 (source-name '.anonymous.)
1130 debug-name)
1131 (when (and (not debug-name) (eq '.anonymous. source-name))
1132 (setf debug-name (name-lambdalike fun)))
1133 (destructuring-bind (decls &rest body)
1134 (if (eq (car fun) 'lambda-with-lexenv)
1135 (cdr fun)
1136 `(() . ,(cdr fun)))
1137 (let* ((notinlines
1138 (loop for fun in (lexenv-funs *lexenv*)
1139 when (and (defined-fun-p (cdr fun))
1140 (defined-fun-inlinep (cdr fun)))
1141 collect fun))
1142 (*lexenv*
1143 (if decls
1144 (make-lexenv
1145 :default (process-decls decls nil nil
1146 :lexenv (make-null-lexenv))
1147 ;; Inherit MUFFLE-CONDITIONS from the call-site lexenv
1148 ;; rather than the definition-site lexenv, since it seems
1149 ;; like a much more common case.
1150 :handled-conditions (lexenv-handled-conditions *lexenv*)
1151 :policy (lexenv-policy *lexenv*)
1152 :flushable (lexenv-flushable *lexenv*)
1153 :lambda (lexenv-lambda *lexenv*)
1154 :parent *lexenv*)
1155 (make-almost-null-lexenv
1156 (lexenv-policy *lexenv*)
1157 (lexenv-handled-conditions *lexenv*)
1158 (lexenv-flushable *lexenv*)
1159 (lexenv-lambda *lexenv*)
1160 *lexenv*)))
1161 (*inlining* (1+ *inlining*))
1162 (clambda (progn
1163 (when notinlines
1164 (setf (lexenv-funs *lexenv*)
1165 notinlines))
1166 (ir1-convert-lambda `(lambda ,@body)
1167 :source-name source-name
1168 :debug-name debug-name))))
1169 (setf (functional-inline-expanded clambda) t)
1170 clambda)))
1172 ;;; Get a DEFINED-FUN object for a function we are about to define. If
1173 ;;; the function has been forward referenced, then substitute for the
1174 ;;; previous references.
1175 (defun get-defined-fun (name)
1176 (proclaim-as-fun-name name)
1177 (let ((found (find-free-fun name "shouldn't happen! (defined-fun)"))
1178 (free-funs (free-funs *ir1-namespace*)))
1179 (note-name-defined name :function)
1180 (cond ((not (defined-fun-p found))
1181 ;; This assertion is wrong in block compilation mode, for
1182 ;; instance
1184 ;; (defun foo (x) (bar x))
1185 ;; (declaim (inline bar))
1186 ;; (defun bar (x) x)
1187 (aver (or (block-compile *compilation*)
1188 (not (info :function :inlinep name))))
1189 (let* ((where-from (leaf-where-from found))
1190 (res (make-defined-fun
1191 :%source-name name
1192 :where-from (if (memq where-from '(:declared :declared-verify))
1193 :declared
1194 :defined-here)
1195 :type (if (eq where-from :declared-verify)
1196 (leaf-defined-type found)
1197 (leaf-type found)))))
1198 (substitute-leaf res found)
1199 (setf (gethash name free-funs) res)))
1200 ;; If FREE-FUNS has a previously converted definition
1201 ;; for this name, then blow it away and try again.
1202 ((defined-fun-functional found)
1203 (remhash name free-funs)
1204 (get-defined-fun name))
1205 (t found))))
1207 ;;; Check a new global function definition for consistency with
1208 ;;; previous declaration or definition, and assert argument/result
1209 ;;; types if appropriate. This assertion is suppressed by the
1210 ;;; EXPLICIT-CHECK attribute, which is specified on functions that
1211 ;;; check their argument types as a consequence of type dispatching.
1212 ;;; This avoids redundant checks such as NUMBERP on the args to +, etc.
1213 (defun assert-new-definition (var fun)
1214 (let* ((type (massage-global-definition-type (leaf-type var) fun))
1215 (for-real (eq (leaf-where-from var) :declared))
1216 (name (leaf-source-name var))
1217 (info (info :function :info name))
1218 (explicit-check (getf (functional-plist fun) 'explicit-check)))
1219 (assert-definition-type
1220 fun type
1221 ;; KLUDGE: Common Lisp is such a dynamic language that in general
1222 ;; all we can do here is issue a STYLE-WARNING. It would be nice
1223 ;; to issue a full WARNING in the special case of type mismatches
1224 ;; within a compilation unit (as in section 3.2.2.3 of the spec)
1225 ;; but at least as of sbcl-0.6.11, we don't keep track of whether
1226 ;; the mismatched data came from the same compilation unit, so we
1227 ;; can't do that. -- WHN 2001-02-11
1228 :lossage-fun #'compiler-style-warn
1229 :unwinnage-fun (cond (info #'compiler-style-warn)
1230 (for-real #'compiler-notify)
1231 (t nil))
1232 :really-assert (if for-real
1233 (explicit-check->really-assert explicit-check))
1234 :where (if for-real
1235 "previous declaration"
1236 "previous definition"))))
1238 ;;; The lexical environment is hairy if it has stuff like lexical
1239 ;;; variables, blocks, or tags that are not load-time constants. Local
1240 ;;; functions and macros are OK, since we are worried about outside
1241 ;;; calls. Macros get expanded, and local functions are load-time
1242 ;;; constants.
1243 (defun simple-lexical-environment-p (lexenv)
1244 (and (null (lexenv-blocks lexenv))
1245 (null (lexenv-tags lexenv))
1246 (every (lambda (entry)
1247 (consp (cdr entry)))
1248 (lexenv-vars lexenv))))
1250 ;; FIXME: really should be an aspect of the lexical environment,
1251 ;; but LEXENVs don't know whether they are toplevel or not.
1252 (defun has-toplevelness-decl (lambda-expr)
1253 (dolist (expr (cddr lambda-expr)) ; Skip over (LAMBDA (ARGS))
1254 (cond ((equal expr '(declare (top-level-form))) (return t))
1255 ((typep expr '(or (cons (eql declare)) string))) ; DECL | DOCSTRING
1256 (t (return nil)))))
1258 ;;; Convert a lambda doing all the basic stuff we would do if we were
1259 ;;; converting a DEFUN.
1260 (defun ir1-convert-lambda-for-defun (lambda var simple-lexenv-p)
1261 (let* ((name (leaf-source-name var))
1262 (fun (ir1-convert-lambda lambda
1263 :maybe-add-debug-catch t
1264 :source-name name))
1265 (info (info :function :info name)))
1266 (setf (functional-inlinep fun) (info :function :inlinep name))
1267 (unless (and info
1268 (ir1-attributep (fun-info-attributes info) fixed-args))
1269 (assert-new-definition var fun))
1270 (when (has-toplevelness-decl lambda)
1271 (setf (functional-top-level-defun-p fun) t))
1272 ;; If definitely not an interpreter stub, then substitute for any
1273 ;; old references.
1274 (unless (or (eq (defined-fun-inlinep var) 'notinline)
1275 (and info
1276 (or (fun-info-transforms info)
1277 (fun-info-templates info)
1278 (fun-info-ir2-convert info))))
1279 (let (type)
1280 (if (block-compile *compilation*)
1281 (progn
1282 (substitute-leaf fun var)
1283 ;; If in a simple environment, then we can allow backward
1284 ;; references to this function from following top-level
1285 ;; forms.
1286 (when simple-lexenv-p
1287 (setf (defined-fun-functional var) fun)))
1288 (substitute-leaf-if
1289 (lambda (ref)
1290 (if (policy ref (> recognize-self-calls 0))
1292 (let ((type (or type
1293 (setf type (definition-type fun))))
1294 (call (node-dest ref)))
1295 (when (and (combination-p call)
1296 (eq (combination-fun call)
1297 (ref-lvar ref))
1298 (fun-type-p type))
1299 (assert-call-type call type t :defined-here))
1300 nil)))
1301 fun var))))
1302 fun))
1304 ;;; Convert a lambda for global inline expansion.
1306 ;;; Unless a INLINE function, we temporarily clobber the inline
1307 ;;; expansion. This prevents recursive inline expansion of
1308 ;;; opportunistic pseudo-inlines.
1309 (defun ir1-convert-inline-expansion (var inlinep)
1310 (declare (type defined-fun var))
1311 (let ((var-expansion (defined-fun-inline-expansion var)))
1312 (unless (eq inlinep 'inline)
1313 (setf (defined-fun-inline-expansion var) nil))
1314 (let* ((name (leaf-source-name var))
1315 (fun (ir1-convert-inline-lambda var-expansion
1316 :source-name name))
1317 (info (info :function :info name)))
1318 (setf (functional-inlinep fun) inlinep)
1319 (assert-new-definition var fun)
1320 (setf (defined-fun-inline-expansion var) var-expansion)
1322 ;; If definitely not an interpreter stub, then substitute for any
1323 ;; old references.
1324 (unless (or (eq (defined-fun-inlinep var) 'notinline)
1325 (not (block-compile *compilation*))
1326 (and info
1327 (or (fun-info-transforms info)
1328 (fun-info-templates info)
1329 (fun-info-ir2-convert info))))
1330 (substitute-leaf fun var)
1331 ;; If in a simple environment, then we can allow backward
1332 ;; references to this function from following top-level
1333 ;; forms.
1334 (when (simple-lexical-environment-p *lexenv*)
1335 (setf (defined-fun-functional var) fun)))
1336 fun)))
1339 ;;; Entry point utilities
1341 ;;; Return a function for the Nth entry point.
1342 (defun optional-dispatch-entry-point-fun (dispatcher n)
1343 (declare (type optional-dispatch dispatcher)
1344 (type unsigned-byte n))
1345 (let ((*lexenv* (functional-lexenv dispatcher))
1346 (*current-path* (optional-dispatch-source-path dispatcher)))
1347 (force (nth n (optional-dispatch-entry-points dispatcher)))))
1349 ;;; Store INLINE-LAMBDA as the inline expansion of NAME.
1350 ;;; EXTRA-INFO is either a keyword denoting that NAME pertains to
1351 ;;; an auto-generated defstruct function, or else it is the list of
1352 ;;; funargs that could be auto-dxified.
1353 (defun %set-inline-expansion (name defined-fun inline-lambda extra-info
1354 &aux (defstruct-snippet
1355 (when (keywordp extra-info)
1356 extra-info))
1357 (dxable-args
1358 (unless (keywordp extra-info)
1359 extra-info)))
1360 (cond (defstruct-snippet
1361 ;; In this case, NAME is a system-generated function. Warn if blowing away
1362 ;; a previously existing inline expansion coming from an ordinary DEFUN.
1363 ;; FIXME: It's tricky to correctly warn about stomping on a constructor
1364 ;; because it might actually be the right inline lambda.
1365 ;; Probably should compare with EQUALP.
1366 ;; FIXME: what does the below KLUDGE mean ?
1367 (unless (eq defstruct-snippet :constructor)
1368 (let ((old (info :function :inlining-data name)))
1369 ;; KLUDGE: This is like (NTH-VALUE 1 (FUN-NAME-INLINE-EXPANSION))
1370 ;; but expressed in a way that doesn't crash in cold-init.
1371 (when (or (typep old 'inlining-data) (consp old))
1372 ;; Any inline expansion that existed can't be useful.
1373 (warn "structure ~(~A~) ~S clobbers inline function"
1374 defstruct-snippet name)))))
1376 (let ((info (info :function :source-transform name)))
1377 ;; If NAME was a defstruct snippet, and now it isn't, then warn
1378 ;; and remove the transform.
1379 (when (consp info)
1380 (clear-info :function :source-transform name)
1381 ;; This is serious enough that you can get two warnings:
1382 ;; - one because you redefined a function at all,
1383 ;; - and one because the source-transform is erased.
1384 (warn "redefinition of ~S clobbers structure ~:[accessor~;~(~a~)~]"
1385 name (symbolp (cdr info)) (cdr info))))))
1386 ;; says CLHS: "Only an implementation that was willing to be responsible
1387 ;; for recompiling f if the definition of g changed incompatibly could
1388 ;; legitimately stack allocate the list argument to g in f."
1389 ;; Yeah, well, we're not going be responsible for bupkis.
1390 ;; If you want to do something dangerous, then do it.
1391 ;; Of course it would be nice NOT to warn when we haven't actually baked-in
1392 ;; any assumptions about callees, but I don't feel like adding more metadata
1393 ;; to track when we assumed something.
1394 (let ((old (fun-name-dx-args name)))
1395 (when (and old (not (subsetp old dxable-args)))
1396 (warn "redefinition of ~S with differing DYNAMIC-EXTENT declarations ~
1397 is potentially harmful to any already-compiled callers using (SAFETY 0)."
1398 name)))
1399 (if (or inline-lambda dxable-args)
1400 (setf (info :function :inlining-data name)
1401 (if dxable-args
1402 (if inline-lambda
1403 (make-inlining-data inline-lambda dxable-args)
1404 (make-dxable-args dxable-args))
1405 inline-lambda))
1406 (clear-info :function :inlining-data name))
1407 (when (and inline-lambda defined-fun)
1408 (setf (defined-fun-inline-expansion defined-fun)
1409 inline-lambda)))
1411 ;;; the even-at-compile-time part of DEFUN
1413 ;;; INLINE-LAMBDA is either (LAMBDA (...) ...) or (LAMBDA-WITH-LEXENV ...)
1414 ;;; EXTRA-INFO is one of:
1415 ;;; * a symbol in {:ACCESSOR, :PREDICATE, :COPIER, :CONSTRUCTOR} if the function
1416 ;;; came from defstruct; or
1417 ;;; * a possibly empty list of dynamic extent arguments.
1418 ;;; The inline lambda will be NIL for a structure accessor, predicate, or copier
1419 ;;; since those can always be reconstructed from a defstruct description.
1420 (defun %compiler-defun (name compile-toplevel inline-lambda extra-info &optional specialized-xep)
1421 (cond (compile-toplevel
1422 (let ((defined-fun nil))
1423 (with-single-package-locked-error
1424 (:symbol name "defining ~S as a function")
1425 (setf defined-fun (get-defined-fun name)))
1426 (when (boundp '*lexenv*)
1427 (aver (producing-fasl-file))
1428 (let ((names (fun-names-in-this-file *compilation*)))
1429 (if (hashset-find names name)
1430 (warn 'duplicate-definition :name name)
1431 (hashset-insert names name))))
1432 ;; I don't know why this is guarded by (WHEN compile-toplevel),
1433 ;; because regular old %DEFUN is going to call this anyway.
1434 (%set-inline-expansion name defined-fun inline-lambda extra-info)))
1435 ((boundp 'sb-fasl::*current-fasl-group*)
1436 (let ((names (sb-fasl::fasl-group-fun-names sb-fasl::*current-fasl-group*)))
1437 (if (hashset-find names name)
1438 (warn 'duplicate-definition :name name)
1439 (hashset-insert names name)))))
1441 (become-defined-fun-name name)
1442 (when specialized-xep
1443 (setf (info :function :specialized-xep name) specialized-xep)
1444 (let ((xep-name (list* 'sb-impl::specialized-xep name specialized-xep)))
1445 (setf (info :function :type xep-name) (specifier-type `(function ,@specialized-xep))
1446 (info :function :where-from xep-name) :declared)))
1448 (values))