;; A continuation that is the CONT of some node in BLOCK.
(kind :unused :type (member :unused :deleted :inside-block :block-start
:deleted-block-start))
- ;; The node which receives this value, if any. In a deleted continuation,
- ;; this is null even though the node that receives this continuation may not
- ;; yet be deleted.
+ ;; The node which receives this value, if any. In a deleted
+ ;; continuation, this is null even though the node that receives
+ ;; this continuation may not yet be deleted.
(dest nil :type (or node null))
;; If this is a NODE, then it is the node which is to be evaluated
;; next. This is always null in :DELETED and :UNUSED continuations,
;; called for, but it believes it has proven that the check won't
;; be done for policy reasons or because a safe implementation
;; will be used. In the latter case, LTN must ensure that a safe
- ;; implementation *is* be used.
+ ;; implementation *is* used.
;;
;; :ERROR
;; There is a compile-time type error in some use of this
(def!method print-object ((x continuation) stream)
(print-unreadable-object (x stream :type t :identity t)))
-(defstruct (node (:constructor nil))
+(defstruct (node (:constructor nil)
+ (:copier nil))
;; the bottom-up derived type for this node. This does not take into
;; consideration output type assertions on this node (actually on its CONT).
(derived-type *wild-type* :type ctype)
;; Following the introduced forms is a representation of the
;; location of the enclosing original source form. This transition
;; is indicated by the magic ORIGINAL-SOURCE-START marker. The first
- ;; element of the orignal source is the "form number", which is the
+ ;; element of the original source is the "form number", which is the
;; ordinal number of this form in a depth-first, left-to-right walk
;; of the truly top-level form in which this appears.
;;
;;
;; The last element in the list is the top-level form number, which
;; is the ordinal number (in this call to the compiler) of the truly
- ;; top-level form containing the orignal source.
+ ;; top-level form containing the original source.
(source-path *current-path* :type list)
;; If this node is in a tail-recursive position, then this is set to
;; T. At the end of IR1 (in environment analysis) this is computed
;;; The Block-Annotation structure is shared (via :INCLUDE) by
;;; different block-info annotation structures so that code
;;; (specifically control analysis) can be shared.
-(defstruct (block-annotation (:constructor nil))
+(defstruct (block-annotation (:constructor nil)
+ (:copier nil))
;; The IR1 block that this block is in the INFO for.
(block (required-argument) :type cblock)
;; the next and previous block in emission order (not DFO). This
;;; The Component structure provides a handle on a connected piece of
;;; the flow graph. Most of the passes in the compiler operate on
;;; components rather than on the entire flow graph.
-(defstruct component
+(defstruct (component (:copier nil))
;; The kind of component:
;;
;; NIL
name
(reanalyze :test reanalyze))
-;;; The Cleanup structure represents some dynamic binding action.
+;;; The CLEANUP structure represents some dynamic binding action.
;;; Blocks are annotated with the current cleanup so that dynamic
;;; bindings can be removed when control is transferred out of the
;;; binding environment. We arrange for changes in dynamic bindings to
;;; by requiring that the exit continuations initially head their
;;; blocks, and then by not merging blocks when there is a cleanup
;;; change.
-(defstruct cleanup
+(defstruct (cleanup (:copier nil))
;; The kind of thing that has to be cleaned up.
(kind (required-argument)
:type (member :special-bind :catch :unwind-protect :block :tagbody))
(nlx-info :test nlx-info))
;;; The ENVIRONMENT structure represents the result of environment analysis.
-(defstruct environment
+(defstruct (environment (:copier nil))
;; the function that allocates this environment
(function (required-argument) :type clambda)
;; a list of all the lambdas that allocate variables in this environment
;;; The tail set is somewhat approximate, because it is too early to
;;; be sure which calls will be TR. Any call that *might* end up TR
;;; causes tail-set merging.
-(defstruct tail-set
+(defstruct (tail-set (:copier nil))
;; a list of all the lambdas in this tail set
(functions nil :type list)
;; our current best guess of the type returned by these functions.
;; :DECLARED, from a declaration.
;; :ASSUMED, from uses of the object.
;; :DEFINED, from examination of the definition.
- ;; FIXME: This should be a named type. (LEAF-WHERE-FROM?)
+ ;; FIXME: This should be a named type. (LEAF-WHERE-FROM? Or
+ ;; perhaps just WHERE-FROM, since it's not just used in LEAF,
+ ;; but also in various DEFINE-INFO-TYPEs in globaldb.lisp,
+ ;; and very likely elsewhere too.)
(where-from :assumed :type (member :declared :assumed :defined))
;; list of the REF nodes for this leaf
(refs () :type list)
;;; defined in the same compilation block, or that have inline
;;; expansions, or have a non-NIL INLINEP value. Whenever we change
;;; the INLINEP state (i.e. an inline proclamation) we copy the
-;;; structure so that former inlinep values are preserved.
+;;; structure so that former INLINEP values are preserved.
(def!struct (defined-function (:include global-var
(where-from :defined)
(kind :global-function)))
(arglist nil :type list)
;; true if &ALLOW-OTHER-KEYS was supplied
(allowp nil :type boolean)
- ;; true if &KEY was specified (doesn't necessarily mean that there
- ;; are any keyword arguments...)
+ ;; true if &KEY was specified (which doesn't necessarily mean that
+ ;; there are any &KEY arguments..)
(keyp nil :type boolean)
;; the number of required arguments. This is the smallest legal
;; number of arguments.
;; defaults even when there is no user-specified supplied-p var.
(supplied-p nil :type (or lambda-var null))
;; the default for a keyword or optional, represented as the
- ;; original Lisp code. This is set to NIL in keyword arguments that
- ;; are defaulted using the SUPPLIED-P arg.
+ ;; original Lisp code. This is set to NIL in &KEY arguments that are
+ ;; defaulted using the SUPPLIED-P arg.
(default nil :type t)
- ;; the actual keyword for a keyword argument
- (keyword nil :type (or keyword null)))
+ ;; the actual key for a &KEY argument. Note that in ANSI CL this is not
+ ;; necessarily a keyword: (DEFUN FOO (&KEY ((BAR BAR))) ..).
+ (key nil :type symbol))
(defprinter (arg-info)
(specialp :test specialp)
kind
(supplied-p :test supplied-p)
(default :test default)
- (keyword :test keyword))
+ (key :test key))
;;; The LAMBDA-VAR structure represents a lexical lambda variable.
;;; This structure is also used during IR1 conversion to describe
;;; initially (and forever) NIL, since REFs don't receive any values
;;; and don't have any IR1 optimizer.
(defstruct (ref (:include node (:reoptimize nil))
- (:constructor make-ref (derived-type leaf)))
+ (:constructor make-ref (derived-type leaf))
+ (:copier nil))
;; The leaf referenced.
(leaf nil :type leaf))
(defprinter (ref)
;;; function appears as the successor. The NODE-CONT remains the
;;; continuation which receives the value of the call.
(defstruct (basic-combination (:include node)
- (:constructor nil))
+ (:constructor nil)
+ (:copier nil))
;; continuation for the function
(fun (required-argument) :type continuation)
;; list of CONTINUATIONs for the args. In a local call, an argument
;;; including FUNCALL. This is distinct from BASIC-COMBINATION so that
;;; an MV-COMBINATION isn't COMBINATION-P.
(defstruct (combination (:include basic-combination)
- (:constructor make-combination (fun))))
+ (:constructor make-combination (fun))
+ (:copier nil)))
(defprinter (combination)
(fun :prin1 (continuation-use fun))
- (args :prin1 (mapcar #'(lambda (x)
- (if x
- (continuation-use x)
- "<deleted>"))
+ (args :prin1 (mapcar (lambda (x)
+ (if x
+ (continuation-use x)
+ "<deleted>"))
args)))
-;;; An MV-Combination is to Multiple-Value-Call as a Combination is to
-;;; Funcall. This is used to implement all the multiple-value
+;;; An MV-COMBINATION is to MULTIPLE-VALUE-CALL as a COMBINATION is to
+;;; FUNCALL. This is used to implement all the multiple-value
;;; receiving forms.
(defstruct (mv-combination (:include basic-combination)
- (:constructor make-mv-combination (fun))))
+ (:constructor make-mv-combination (fun))
+ (:copier nil)))
(defprinter (mv-combination)
(fun :prin1 (continuation-use fun))
(args :prin1 (mapcar #'continuation-use args)))
-;;; The Bind node marks the beginning of a lambda body and represents
+;;; The BIND node marks the beginning of a lambda body and represents
;;; the creation and initialization of the variables.
-(defstruct (bind (:include node))
+(defstruct (bind (:include node)
+ (:copier nil))
;; the lambda we are binding variables for. Null when we are
;; creating the LAMBDA during IR1 translation.
(lambda nil :type (or clambda null)))
(defprinter (bind)
lambda)
-;;; The Return node marks the end of a lambda body. It collects the
+;;; The RETURN node marks the end of a lambda body. It collects the
;;; return values and represents the control transfer on return. This
-;;; is also where we stick information used for Tail-Set type
+;;; is also where we stick information used for TAIL-SET type
;;; inference.
(defstruct (creturn (:include node)
(:conc-name return-)
;;; The ENTRY node serves to mark the start of the dynamic extent of a
;;; lexical exit. It is the mess-up node for the corresponding :Entry
;;; cleanup.
-(defstruct (entry (:include node))
+(defstruct (entry (:include node)
+ (:copier nil))
;; All of the Exit nodes for potential non-local exits to this point.
(exits nil :type list)
;; The cleanup for this entry. NULL only temporarily.
;;; the returned value being delivered directly to the exit
;;; continuation, it is delivered to our VALUE continuation. The
;;; original exit continuation is the exit node's CONT.
-(defstruct (exit (:include node))
+(defstruct (exit (:include node)
+ (:copier nil))
;; The Entry node that this is an exit for. If null, this is a
;; degenerate exit. A degenerate exit is used to "fill" an empty
;; block (which isn't allowed in IR1.) In a degenerate exit, Value
#-no-ansi-print-object
(:print-object (lambda (x s)
(print-unreadable-object (x s :type t)
- (prin1 (undefined-warning-name x) s)))))
- ;; The name of the unknown thing.
+ (prin1 (undefined-warning-name x) s))))
+ (:copier nil))
+ ;; the name of the unknown thing
(name nil :type (or symbol list))
- ;; The kind of reference to Name.
+ ;; the kind of reference to NAME
(kind (required-argument) :type (member :function :type :variable))
- ;; The number of times this thing was used.
+ ;; the number of times this thing was used
(count 0 :type unsigned-byte)
- ;; A list of COMPILER-ERROR-CONTEXT structures describing places
+ ;; a list of COMPILER-ERROR-CONTEXT structures describing places
;; where this thing was used. Note that we only record the first
;; *UNDEFINED-WARNING-LIMIT* calls.
(warnings () :type list))
\f
+;;; a helper for the POLICY macro, defined late here so that the
+;;; various type tests can be inlined
+(declaim (ftype (function ((or list lexenv node functional)) list)
+ %coerce-to-policy))
+(defun %coerce-to-policy (thing)
+ (let ((result (etypecase thing
+ (list thing)
+ (lexenv (lexenv-policy thing))
+ (node (lexenv-policy (node-lexenv thing)))
+ (functional (lexenv-policy (functional-lexenv thing))))))
+ ;; Test the first element of the list as a rudimentary sanity
+ ;; that it really does look like a valid policy.
+ (aver (or (null result) (policy-quality-name-p (caar result))))
+ ;; Voila.
+ result))
+\f
;;;; Freeze some structure types to speed type testing.
#!-sb-fluid