Fix hidden bug in immobile space defrag.
[sbcl.git] / contrib / sb-cltl2 / env.lisp
blobc26596bfb5fff8f8e1efed74783e7e6bb466a03d
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3 ;;;;
4 ;;;; The software is in the public domain and is provided with
5 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
6 ;;;; more information.
8 (in-package :sb-cltl2)
10 #| TODO:
11 (map-environment)
15 (defvar *null-lexenv* (make-null-lexenv))
17 (defun augment-environment
18 (env &key variable symbol-macro function macro declare)
19 "Create a new lexical environment by augmenting ENV with new information.
21 VARIABLE
22 is a list of symbols to introduce as new variable bindings.
24 SYMBOL-MACRO
25 is a list symbol macro bindings of the form (name definition).
27 MACRO
28 is a list of macro definitions of the form (name definition), where
29 definition is a function of two arguments (a form and an environment).
31 FUNCTION
32 is a list of symbols to introduce as new local function bindings.
34 DECLARE
35 is a list of declaration specifiers. Declaration specifiers attach to the
36 new variable or function bindings as if they appeared in let, let*, flet
37 or labels form. For example:
39 (augment-environment env :variable '(x) :declare '((special x)))
41 is like
43 (let (x) (declare (special x)) ....)
45 but
47 (augment-environment (augment-environment env :variable '(x))
48 :declare '((special x)))
50 is like
52 (let (x) (locally (declare (special x))) ...)
54 (setq env (copy-structure (sb-c::coerce-to-lexenv env)))
55 (collect ((lvars)
56 (clambdas))
57 (unless (or variable symbol-macro function macro declare)
58 (return-from augment-environment env))
60 ;; a null policy is used to identify a null lexenv
61 (when (sb-c::null-lexenv-p env)
62 (setf (sb-c::lexenv-%policy env) sb-c::*policy*))
64 (when macro
65 (setf (sb-c::lexenv-funs env)
66 (nconc
67 (loop for (name def) in macro
68 collect (cons name (cons 'sb-sys::macro def)))
69 (sb-c::lexenv-funs env))))
71 (when symbol-macro
72 (setf (sb-c::lexenv-vars env)
73 (nconc
74 (loop for (name def) in symbol-macro
75 collect (cons name (cons 'sb-sys::macro def)))
76 (sb-c::lexenv-vars env))))
78 (dolist (name variable)
79 (lvars (sb-c::make-lambda-var :%source-name name)))
81 (dolist (name function)
82 (clambdas
83 (sb-c::make-lambda
84 :lexenv *null-lexenv*
85 :%source-name name
86 :allow-instrumenting nil)))
88 (when declare
89 ;; process-decls looks in *lexenv* policy to decide what warnings to print
90 (let ((*lexenv* *null-lexenv*))
91 (setq env (sb-c::process-decls
92 (list `(declare ,@declare))
93 (lvars) (clambdas) :lexenv env :context nil))))
95 (when function
96 (setf (sb-c::lexenv-funs env)
97 (nconc
98 (loop for name in function for lambda in (clambdas)
99 collect (cons name lambda))
100 (sb-c::lexenv-funs env))))
102 (when variable
103 (setf (sb-c::lexenv-vars env)
104 (nconc
105 (loop for name in variable for lvar in (lvars)
106 collect
107 (cons name
108 ;; If one of the lvars is declared special then
109 ;; process-decls will set it's specvar.
110 (if (sb-c::lambda-var-specvar lvar)
111 (sb-c::lambda-var-specvar lvar)
112 lvar)))
113 (sb-c::lexenv-vars env))))
115 env))
117 ;;; Retrieve the user-supplied (from define-declaration) pairs for a
118 ;;; function or a variable from a lexical environment.
120 ;;; KEYWORD should be :function or :variable, VAR should be a
121 ;;; function or variable name, respectively.
122 (defun extra-pairs (keyword var binding env)
123 (when env
124 (let ((ret nil))
125 (dolist (entry (sb-c::lexenv-user-data env))
126 (destructuring-bind
127 (entry-keyword entry-var entry-binding &rest entry-cons)
128 entry
129 (when (and (eq keyword entry-keyword)
130 (typecase binding
131 (sb-c::global-var
132 (and (eq var entry-var)
133 (typecase entry-binding
134 (sb-c::global-var t)
135 (sb-c::lambda-var
136 (sb-c::lambda-var-specvar entry-binding))
137 (null t)
138 (t nil))))
140 (eq binding entry-binding))))
141 (push entry-cons ret))))
142 (nreverse ret))))
144 (defun maybe-deprecation-entry (info)
145 (when info
146 (with-accessors ((state sb-int:deprecation-info-state)
147 (software sb-int:deprecation-info-software)
148 (version sb-int:deprecation-info-version)
149 (replacements sb-int:deprecation-info-replacements))
150 info
151 (list (cons 'sb-ext:deprecated
152 (list :state state
153 :since (list software version)
154 :replacements replacements))))))
156 ;;; Retrieve the user-supplied (from define-declaration) value for
157 ;;; the declaration with the given NAME
158 (defun extra-decl-info (name env)
159 (when env
160 (dolist (entry (sb-c::lexenv-user-data env))
161 (when (and (eq :declare (car entry))
162 (eq name (cadr entry)))
163 (return-from extra-decl-info (cddr entry))))
164 nil))
167 (eval-when (:compile-toplevel :load-toplevel :execute)
168 (defmacro list-cons-when (test car cdr)
169 `(when ,test
170 (list (cons ,car ,cdr)))))
172 (declaim (ftype (sfunction ((or symbol cons) &optional lexenv-designator)
173 (values (member nil :function :macro :special-form)
174 boolean
175 list))
176 function-information))
177 (defun function-information (name &optional env)
178 "Return information about the function NAME in the lexical environment ENV.
179 Note that the global function binding may differ from the local one.
181 This function returns three values. The first indicates the type of
182 function definition or binding:
185 There is no apparent definition for NAME.
187 :FUNCTION
188 NAME refers to a function.
190 :MACRO
191 NAME refers to a macro.
193 :SPECIAL-FORM
194 NAME refers to a special operator. If the name refers to both a
195 macro and a special operator, the macro takes precedence.
197 The second value is true if NAME is bound locally.
199 The third value is an alist describing the declarations that apply to
200 the function NAME. Standard declaration specifiers that may appear in
201 CARS of the alist include:
203 DYNAMIC-EXTENT
204 If the CDR is T, NAME has been declared DYNAMIC-EXTENT. If the CDR
205 is NIL, the alist element may be omitted.
207 INLINE
208 The CDR is one of the symbols INLINE, NOTINLINE, or NIL, to
209 indicate if the function has been declared INLINE or NOTINLINE. If
210 the CDR is NIL the alist element may be omitted.
212 FTYPE
213 The CDR is the type specifier associated with NAME, or the symbol
214 FUNCTION if there is functional type declaration or proclamation
215 associated with NAME. If the CDR is FUNCTION the alist element may
216 be omitted.
218 SB-EXT:DEPRECATED
219 \(SBCL specific)
220 The CDR is a plist containing the following properties
222 :STATE ( :EARLY | :LATE | :FINAL )
223 Use of :EARLY deprecated functions signals a STYLE-WARNING at
224 compile-time.
226 Use of :LATE deprecated functions signals a full WARNING at
227 compile-time.
229 Use of :FINAL deprecated functions signals a full WARNING at
230 compile-time and an error at runtime.
232 :SINCE (SOFTWARE VERSION)
233 VERSION is a string designating the version since which the
234 function has been deprecated. SOFTWARE is NIL or the name of
235 the software to which VERSION refers, e.g. \"SBCL\" for
236 deprecated functions in SBCL.
238 :REPLACEMENTS REPLACEMENTS
239 When this property is present, REPLACEMENTS is a list of
240 symbols naming functions that should be used instead of the
241 deprecated function.
243 In addition to these declarations defined using DEFINE-DECLARATION may
244 appear."
245 (let* ((*lexenv*
246 (typecase env
247 #+sb-fasteval
248 (sb-interpreter:basic-env (sb-interpreter::lexenv-from-env env))
249 (null (make-null-lexenv))
250 (t env)))
251 (fun (lexenv-find name funs))
252 binding localp ftype dx inlinep)
253 (etypecase fun
254 (sb-c::leaf
255 (let ((env-type (or (lexenv-find fun type-restrictions)
256 *universal-fun-type*)))
257 (setf binding :function
258 ftype (type-intersection (sb-c::leaf-type fun) env-type)
259 dx (sb-c::leaf-dynamic-extent fun))
260 (etypecase fun
261 (sb-c::functional
262 (setf localp t
263 inlinep (sb-c::functional-inlinep fun)))
264 (sb-c::defined-fun
265 ;; Inlined known functions.
266 (setf localp nil
267 inlinep (sb-c::defined-fun-inlinep fun))))))
268 (cons
269 (setf binding :macro
270 localp t))
271 (null
272 ;; FIXME: we document above that :MACRO trumps :SPECIAL-FORM
273 ;; but that is clearly untrue.
274 (case (info :function :kind name)
275 (:macro
276 (setf binding :macro
277 localp nil))
278 (:special-form
279 (setf binding :special-form
280 localp nil))
281 (:function
282 (setf binding :function
283 localp nil
284 ftype (when (eq :declared (info :function :where-from name))
285 (proclaimed-ftype name))
286 inlinep (info :function :inlinep name))))))
287 (values binding
288 localp
289 (nconc (ecase inlinep
290 ((:inline :maybe-inline)
291 (list '(inline . inline)))
292 (:notinline
293 (list '(inline . notinline)))
294 ((nil)))
295 (list-cons-when (and ftype (neq *universal-fun-type* ftype))
296 'ftype (type-specifier ftype))
297 (list-cons-when dx 'dynamic-extent t)
298 (unless localp
299 (maybe-deprecation-entry
300 (info :function :deprecated name)))
301 (extra-pairs :function name fun *lexenv*)))))
303 (declaim (ftype (sfunction
304 (symbol &optional lexenv-designator)
305 (values (member nil :special :lexical :symbol-macro :constant :global :alien)
306 boolean
307 list))
308 variable-information))
309 (defun variable-information (name &optional env)
310 "Return information about the variable name VAR in the lexical environment ENV.
311 Note that the global binding may differ from the local one.
313 This function returns three values. The first indicated the type of the variable
314 binding:
317 There is no apparent binding for NAME.
319 :SPECIAL
320 NAME refers to a special variable.
322 :LEXICAL
323 NAME refers to a lexical variable.
325 :SYMBOL-MACRO
326 NAME refers to a symbol macro.
328 :CONSTANT
329 NAME refers to a named constant defined using DEFCONSTANT, or NAME
330 is a keyword.
332 :GLOBAL
333 NAME refers to a global variable. (SBCL specific extension.)
335 :ALIEN
336 NAME refers to an alien variable. (SBCL specific extension.)
338 The second value is true if NAME is bound locally. This is currently
339 always NIL for special variables, although arguably it should be T
340 when there is a lexically apparent binding for the special variable.
342 The third value is an alist describing the declarations that apply to
343 the function NAME. Standard declaration specifiers that may appear in
344 CARS of the alist include:
346 DYNAMIC-EXTENT
347 If the CDR is T, NAME has been declared DYNAMIC-EXTENT. If the CDR
348 is NIL, the alist element may be omitted.
350 IGNORE
351 If the CDR is T, NAME has been declared IGNORE. If the CDR is NIL,
352 the alist element may be omitted.
354 TYPE
355 The CDR is the type specifier associated with NAME, or the symbol
356 T if there is explicit type declaration or proclamation associated
357 with NAME. The type specifier may be equivalent to or a supertype
358 of the original declaration. If the CDR is T the alist element may
359 be omitted.
361 SB-EXT:ALWAYS-BOUND
362 \(SBCL specific)
363 If CDR is T, NAME has been declared as SB-EXT:ALWAYS-BOUND
365 SB-EXT:DEPRECATED
366 \(SBCL specific)
367 The CDR is a plist containing the following properties
369 :STATE ( :EARLY | :LATE | :FINAL )
370 Use of :EARLY deprecated variables signals a STYLE-WARNING at
371 compile-time.
373 Use of :LATE deprecated variables signals a full WARNING at
374 compile-time.
376 Use of :FINAL deprecated variables signals a full WARNING at
377 compile-time and an error at runtime.
379 :SINCE (SOFTWARE VERSION)
380 VERSION is a string designating the version since which the
381 variable has been deprecated. SOFTWARE is NIL or the name of
382 the software to which VERSION refers, e.g. \"SBCL\" for
383 deprecated variables in SBCL.
385 :REPLACEMENTS REPLACEMENTS
386 When this property is present, REPLACEMENTS is a list of
387 symbols naming variables that should be used instead of the
388 deprecated variable.
390 In addition to these declarations defined using DEFINE-DECLARATION may
391 appear."
392 (let* ((*lexenv* (sb-c::coerce-to-lexenv env))
393 (kind (info :variable :kind name))
394 (var (lexenv-find name vars))
395 binding localp dx ignorep type)
396 (etypecase var
397 (sb-c::leaf
398 (let ((env-type (or (lexenv-find var type-restrictions)
399 *universal-type*)))
400 (setf type (type-intersection (sb-c::leaf-type var) env-type)
401 dx (sb-c::leaf-dynamic-extent var)))
402 (etypecase var
403 (sb-c::lambda-var
404 (setf binding :lexical
405 localp t
406 ignorep (sb-c::lambda-var-ignorep var)))
407 ;; FIXME: IGNORE doesn't make sense for specials or constants
408 ;; -- though it is _possible_ to declare them ignored, but
409 ;; we don't keep the information around.
410 (sb-c::global-var
411 (setf binding (if (eq :global kind)
412 :global
413 :special)
414 ;; FIXME: Lexically apparent binding or not for specials?
415 localp nil))
416 (sb-c::constant
417 (setf binding :constant
418 localp nil))))
419 (cons
420 (setf binding :symbol-macro
421 localp t))
422 (null
423 (let ((global-type (info :variable :type name)))
424 (setf binding (case kind
425 (:macro :symbol-macro)
426 (:unknown nil)
427 (t kind))
428 type (if (eq *universal-type* global-type)
430 global-type)
431 localp nil))))
432 (values binding
433 localp
434 (nconc (list-cons-when ignorep 'ignore t)
435 (list-cons-when (and type (neq *universal-type* type))
436 'type (type-specifier type))
437 (list-cons-when dx 'dynamic-extent t)
438 (list-cons-when (info :variable :always-bound name)
439 'sb-ext:always-bound t)
440 (maybe-deprecation-entry
441 (info :variable :deprecated name))
442 (extra-pairs :variable name var *lexenv*)))))
444 ;;; Unlike policy-related declarations which the interpeter itself needs
445 ;;; for correct operation of some macros, muffled conditions are irrelevant,
446 ;;; since warnings are not signaled much, if at all.
447 ;;; This is even more useless than env-package-locks.
448 ;;; It's only for SB-CLTL2, and not tested in the least.
449 #+sb-fasteval
450 (defun compute-handled-conditions (env)
451 (named-let recurse ((env env))
452 (let ((result (acond ((sb-interpreter::env-parent env)
453 (compute-handled-conditions it))
454 (t sb-c::*handled-conditions*))))
455 (sb-interpreter::do-decl-spec
456 (declaration (sb-interpreter::env-declarations env) result)
457 (let ((f (case (car declaration)
458 (sb-ext:muffle-conditions
459 #'sb-c::process-muffle-conditions-decl)
460 (sb-ext:unmuffle-conditions
461 #'sb-c::process-unmuffle-conditions-decl))))
462 (when f
463 (setq result (funcall f declaration result))))))))
465 (declaim (ftype (sfunction (symbol &optional lexenv-designator) t)
466 declaration-information))
467 (defun declaration-information (declaration-name &optional env)
468 "Return information about declarations named by DECLARATION-NAME.
470 If DECLARATION-NAME is OPTIMIZE return a list who's entries are of the
471 form \(QUALITY VALUE).
473 If DECLARATION-NAME is DECLARATION return a list of declaration names that
474 have been proclaimed as valid.
476 If DECLARATION-NAME is a name that has defined via DEFINE-DECLARATION return a
477 user defined value.
479 If DECLARATION-NAME is SB-EXT:MUFFLE-CONDITIONS return a type specifier for
480 the condition types that have been muffled."
481 (let ((env (or env (make-null-lexenv))))
482 (case declaration-name
483 (optimize
484 ;; CLtL2-mandated behavior:
485 ;; "The returned list always contains an entry for each of the standard
486 ;; qualities and for each of the implementation-specific qualities"
487 (sb-c::policy-to-decl-spec
488 (typecase env
489 #+sb-fasteval
490 (sb-interpreter:basic-env (sb-interpreter:env-policy env))
491 (t (sb-c::lexenv-policy env)))
492 nil t))
493 (sb-ext:muffle-conditions
494 (let ((handled-conditions
495 (typecase env
496 #+sb-fasteval
497 (sb-interpreter:basic-env (compute-handled-conditions env))
498 (t (sb-c::lexenv-handled-conditions env)))))
499 (sb-int:awhen (car (rassoc 'muffle-warning handled-conditions))
500 (sb-kernel:type-specifier it))))
501 (declaration
502 (copy-list sb-int:*recognized-declarations*))
503 (t (if (info :declaration :handler declaration-name)
504 (extra-decl-info
505 declaration-name
506 (typecase env
507 #+sb-fasteval
508 (sb-interpreter:basic-env (sb-interpreter::lexenv-from-env env))
509 (t env)))
510 (error "Unsupported declaration ~S." declaration-name))))))
513 (defun parse-macro (name lambda-list body &optional env)
514 "Process a macro definition of the kind that might appear in a DEFMACRO form
515 into a lambda expression of two variables: a form and an environment. The
516 lambda expression will parse its form argument, binding the variables in
517 LAMBDA-LIST appropriately, and then execute BODY with those bindings in
518 effect."
519 (declare (ignore env))
520 (values
521 ;; lp#1545148 says that some people don't like NAMED-LAMBDA,
522 ;; so pass NIL instead of a name.
523 (make-macro-lambda nil ; (if (and name (symbolp name)) (string name) "PARSE-MACRO")
524 lambda-list body 'parse-macro name)))
526 (defun enclose (lambda-expression &optional environment)
527 "Return a function consistent with LAMBDA-EXPRESSION in ENVIRONMENT: the
528 lambda expression is allowed to reference the declarations and macro
529 definitions in ENVIRONMENT, but consequences are undefined if lexical
530 variables, functions, tags or any other run-time entity defined in ENVIRONMENT
531 is referred to by the expression."
532 (let ((env (if environment
533 (sb-c::make-restricted-lexenv environment)
534 (make-null-lexenv))))
535 (compile-in-lexenv nil lambda-expression env)))
537 ;;; Add a bit of user-data to a lexenv.
539 ;;; If KIND is :declare then DATA should be of the form
540 ;;; (declaration-name . value)
541 ;;; If KIND is :variable then DATA should be of the form
542 ;;; (variable-name key value)
543 ;;; If KIND is :function then DATA should be of the form
544 ;;; (function-name key value)
546 ;;; PD-VARS and PD-FVARS are are the vars and fvars arguments
547 ;;; of the process-decls call that called this function.
548 (defun update-lexenv-user-data (env kind data pd-vars pd-fvars)
549 (let ((user-data (sb-c::lexenv-user-data env)))
550 ;; user-data looks like this:
551 ;; ((:declare d . value)
552 ;; (:variable var binding key . value)
553 ;; (:function var binding key . value))
554 (let ((*lexenv* env))
555 (ecase kind
556 (:variable
557 (loop
558 for (name key value) in data
559 for binding1 = (sb-c::find-in-bindings pd-vars name)
560 for binding = (if binding1 binding1 (lexenv-find name vars))
561 do (push (list* :variable name binding key value) user-data)))
562 (:function
563 (loop
564 for (name key value) in data
565 for binding = (or (loop for fvar in pd-fvars
566 for source-name = (if (consp fvar) ;; MACROLET
567 (car fvar)
568 (sb-c::leaf-source-name fvar))
569 when (equal name source-name)
570 return (if (consp fvar)
571 (cdr fvar)
572 fvar))
573 (lexenv-find name funs))
574 do (push (list* :function name binding key value) user-data)))
575 (:declare
576 (destructuring-bind (decl-name . value) data
577 (push (list* :declare decl-name value) user-data)))))
578 (sb-c::make-lexenv :default env :user-data user-data)))
580 (defmacro define-declaration (decl-name lambda-list &body body)
581 "Define a handler for declaration specifiers starting with DECL-NAME.
583 The function defined by this macro is called with two arguments: a declaration
584 specifier and a environment. It must return two values. The first value must
585 be :VARIABLE, :FUNCTION, or :DECLARE.
587 If the first value is :VARIABLE or :FUNCTION then the second value should be a
588 list of elements of the form (BINDING-NAME KEY VALUE). conses (KEY . VALUE)
589 will be added to the alist returned by:
591 (function-information binding-name env)
595 (variable-information binding-name env)
597 If the first value is :DECLARE then the second value should be a
598 cons (DECL-NAME . VALUE). VALUE will be returned by:
600 (declaration-information decl-name env)
602 `(eval-when (:compile-toplevel :load-toplevel :execute)
603 (proclaim '(declaration ,decl-name))
604 (flet ((func ,lambda-list
605 ,@body))
606 (setf
607 (info :declaration :handler ',decl-name)
608 (lambda (lexenv spec pd-vars pd-fvars)
609 (multiple-value-bind (kind data) (func spec lexenv)
610 (update-lexenv-user-data lexenv kind data pd-vars pd-fvars)))))))