;;; FIXME: It's confusing having one variable named *CURRENT-COMPONENT*
;;; and another named *COMPONENT-BEING-COMPILED*. (In CMU CL they
;;; were called *CURRENT-COMPONENT* and *COMPILE-COMPONENT* respectively,
-;;; which also confusing.)
+;;; which was also confusing.)
(declaim (type (or component null) *current-component*))
(defvar *current-component*)
;;; This function sets up the back link between the node and the
;;; continuation which continues at it.
-#!-sb-fluid (declaim (inline prev-link))
-(defun prev-link (node cont)
+(defun link-node-to-previous-continuation (node cont)
(declare (type node node) (type continuation cont))
(aver (not (continuation-next cont)))
(setf (continuation-next cont) node)
;;; the continuation has no block, then we make it be in the block
;;; that the node is in. If the continuation heads its block, we end
;;; our block and link it to that block. If the continuation is not
-;;; currently used, then we set the derived-type for the continuation
+;;; currently used, then we set the DERIVED-TYPE for the continuation
;;; to that of the node, so that a little type propagation gets done.
;;;
;;; We also deal with a bit of THE's semantics here: we weaken the
;;; otherwise NIL is returned.
;;;
;;; This function may have arbitrary effects on the global environment
-;;; due to processing of PROCLAIMs and EVAL-WHENs. All syntax error
-;;; checking is done, with erroneous forms being replaced by a proxy
-;;; which signals an error if it is evaluated. Warnings about possibly
-;;; inconsistent or illegal changes to the global environment will
-;;; also be given.
+;;; due to processing of EVAL-WHENs. All syntax error checking is
+;;; done, with erroneous forms being replaced by a proxy which signals
+;;; an error if it is evaluated. Warnings about possibly inconsistent
+;;; or illegal changes to the global environment will also be given.
;;;
;;; We make the initial component and convert the form in a PROGN (and
;;; an optional NIL tacked on the end.) We then return the lambda. We
(res (ir1-convert-lambda-body
forms ()
:debug-name (debug-namify "top level form ~S" form))))
- (setf (functional-entry-function res) res
+ (setf (functional-entry-fun res) res
(functional-arg-documentation res) ()
(functional-kind res) :toplevel)
res)))
(let* ((leaf (find-constant value))
(res (make-ref (leaf-type leaf) leaf)))
(push res (leaf-refs leaf))
- (prev-link res start)
+ (link-node-to-previous-continuation res start)
(use-continuation res cont)))
(values)))
-;;; Add FUN to the COMPONENT-REANALYZE-FUNS. FUN is returned.
+;;; Add FUN to the COMPONENT-REANALYZE-FUNS, unless it's some
+;;; trivial type for which reanalysis is a trivial no-op. FUN is returned.
(defun maybe-reanalyze-fun (fun)
(declare (type functional fun))
+
+ (aver-live-component *current-component*)
+ (when (lambda-p fun) ; when it's easy to ask FUN its COMPONENT
+ ;; general sanity check, specifically related to bug 138
+ (aver (eql (lambda-component fun) *current-component*)))
+
+ ;; I *think* this means "unless FUN is of some type for which
+ ;; reanalysis is a no-op". -- WHN 2001-01-06
(when (typep fun '(or optional-dispatch clambda))
(pushnew fun (component-reanalyze-funs *current-component*)))
+
fun)
;;; Generate a REF node for LEAF, frobbing the LEAF structure as
leaf)))
(push res (leaf-refs leaf))
(setf (leaf-ever-used leaf) t)
- (prev-link res start)
+ (link-node-to-previous-continuation res start)
(use-continuation res cont)))
;;; Convert a reference to a symbolic constant or variable. If the
;;; symbol is entered in the LEXENV-VARIABLES we use that definition,
;;; otherwise we find the current global definition. This is also
-;;; where we pick off symbol macro and Alien variable references.
+;;; where we pick off symbol macro and alien variable references.
(defun ir1-convert-variable (start cont name)
(declare (type continuation start cont) (symbol name))
(let ((var (or (lexenv-find name variables) (find-free-variable name))))
(etypecase var
(leaf
- (when (and (lambda-var-p var) (lambda-var-ignorep var))
- ;; (ANSI's specification for the IGNORE declaration requires
- ;; that this be a STYLE-WARNING, not a full WARNING.)
- (compiler-style-warning "reading an ignored variable: ~S" name))
+ (when (lambda-var-p var)
+ (let ((home (continuation-home-lambda-or-null start)))
+ (when home
+ (pushnew var (lambda-calls-or-closes home))))
+ (when (lambda-var-ignorep var)
+ ;; (ANSI's specification for the IGNORE declaration requires
+ ;; that this be a STYLE-WARNING, not a full WARNING.)
+ (compiler-style-warning "reading an ignored variable: ~S" name)))
(reference-leaf start cont var))
(cons
(aver (eq (car var) 'MACRO))
(t
(ir1-convert-global-functoid-no-cmacro start cont form fun)))))
-;;; Handle the case of where the call was not a compiler macro, or was a
-;;; compiler macro and passed.
+;;; Handle the case of where the call was not a compiler macro, or was
+;;; a compiler macro and passed.
(defun ir1-convert-global-functoid-no-cmacro (start cont form fun)
(declare (type continuation start cont) (list form))
;; FIXME: Couldn't all the INFO calls here be converted into
(return))
(let ((this-cont (make-continuation)))
(ir1-convert this-start this-cont form)
- (setq this-start this-cont forms (cdr forms)))))))
+ (setq this-start this-cont
+ forms (cdr forms)))))))
(values))
\f
;;;; converting combinations
;;; Convert a function call where the function (i.e. the FUN argument)
-;;; is a LEAF. We return the COMBINATION node so that we can poke at
-;;; it if we want to.
+;;; is a LEAF. We return the COMBINATION node so that the caller can
+;;; poke at it if it wants to.
(declaim (ftype (function (continuation continuation list leaf) combination)
ir1-convert-combination))
(defun ir1-convert-combination (start cont form fun)
(ir1-convert this-start this-cont arg)
(setq this-start this-cont)
(arg-conts this-cont)))
- (prev-link node this-start)
+ (link-node-to-previous-continuation node this-start)
(use-continuation node cont)
(setf (combination-args node) (arg-conts))))
node))
(values))
;;; Convert a call to a local function. If the function has already
-;;; been let converted, then throw FUN to LOCAL-CALL-LOSSAGE. This
+;;; been LET converted, then throw FUN to LOCAL-CALL-LOSSAGE. This
;;; should only happen when we are converting inline expansions for
;;; local functions during optimization.
(defun ir1-convert-local-combination (start cont form fun)
key))))
key))
-;;; Parse a lambda-list into a list of VAR structures, stripping off
-;;; any aux bindings. Each arg name is checked for legality, and
+;;; Parse a lambda list into a list of VAR structures, stripping off
+;;; any &AUX bindings. Each arg name is checked for legality, and
;;; duplicate names are checked for. If an arg is globally special,
;;; the var is marked as :SPECIAL instead of :LEXICAL. &KEY,
;;; &OPTIONAL and &REST args are annotated with an ARG-INFO structure
;;; 4. a list of the &AUX variables; and
;;; 5. a list of the &AUX values.
(declaim (ftype (function (list) (values list boolean boolean list list))
- find-lambda-vars))
-(defun find-lambda-vars (list)
+ make-lambda-vars))
+(defun make-lambda-vars (list)
(multiple-value-bind (required optional restp rest keyp keys allowp aux
morep more-context more-count)
(parse-lambda-list list)
;;; sequentially bind each AUX-VAR to the corresponding AUX-VAL before
;;; converting the body. If there are no bindings, just convert the
;;; body, otherwise do one binding and recurse on the rest.
+;;;
+;;; FIXME: This could and probably should be converted to use
+;;; SOURCE-NAME and DEBUG-NAME. But I (WHN) don't use &AUX bindings,
+;;; so I'm not motivated. Patches will be accepted...
(defun ir1-convert-aux-bindings (start cont body aux-vars aux-vals)
(declare (type continuation start cont) (list body aux-vars aux-vals))
(if (null aux-vars)
debug-name)
(declare (list body vars aux-vars aux-vals)
(type (or continuation null) result))
+
+ ;; We're about to try to put new blocks into *CURRENT-COMPONENT*.
+ (aver-live-component *current-component*)
+
(let* ((bind (make-bind))
(lambda (make-lambda :vars vars
:bind bind
:%debug-name debug-name))
(result (or result (make-continuation))))
- ;; This function should fail internal assertions if we didn't set
- ;; up a valid debug name above.
+ ;; just to check: This function should fail internal assertions if
+ ;; we didn't set up a valid debug name above.
;;
;; (In SBCL we try to make everything have a debug name, since we
;; lack the omniscient perspective the original implementors used
(let ((cont1 (make-continuation))
(cont2 (make-continuation)))
(continuation-starts-block cont1)
- (prev-link bind cont1)
+ (link-node-to-previous-continuation bind cont1)
(use-continuation bind cont2)
(ir1-convert-special-bindings cont2 result body aux-vars aux-vals
(svars)))
(let ((block (continuation-block result)))
(when block
(let ((return (make-return :result result :lambda lambda))
- (tail-set (make-tail-set :functions (list lambda)))
+ (tail-set (make-tail-set :funs (list lambda)))
(dummy (make-continuation)))
(setf (lambda-tail-set lambda) tail-set)
(setf (lambda-return lambda) return)
(setf (continuation-dest result) return)
(setf (block-last block) return)
- (prev-link return result)
+ (link-node-to-previous-continuation return result)
(use-continuation return dummy))
(link-blocks block (component-tail *current-component*))))))
(link-blocks (component-head *current-component*) (node-block bind))
(push lambda (component-new-funs *current-component*))
+
lambda))
;;; Create the actual entry-point function for an optional entry
(defun generate-optional-default-entry (res default-vars default-vals
entry-vars entry-vals
vars supplied-p-p body
- aux-vars aux-vals cont)
+ aux-vars aux-vals cont
+ source-name debug-name)
(declare (type optional-dispatch res)
(list default-vars default-vals entry-vars entry-vals vars body
aux-vars aux-vals)
(list* (leaf-source-name supplied-p) arg-name default-vals)
(cons arg entry-vars)
(list* t arg-name entry-vals)
- (rest vars) t body aux-vars aux-vals cont)
+ (rest vars) t body aux-vars aux-vals cont
+ source-name debug-name)
(ir1-convert-hairy-args
res
(cons arg default-vars)
(cons arg-name default-vals)
(cons arg entry-vars)
(cons arg-name entry-vals)
- (rest vars) supplied-p-p body aux-vars aux-vals cont))))
+ (rest vars) supplied-p-p body aux-vars aux-vals cont
+ source-name debug-name))))
(convert-optional-entry ep default-vars default-vals
(if supplied-p
;;; type when computing the type for the main entry's argument.
(defun ir1-convert-more (res default-vars default-vals entry-vars entry-vals
rest more-context more-count keys supplied-p-p
- body aux-vars aux-vals cont)
+ body aux-vars aux-vals cont
+ source-name debug-name)
(declare (type optional-dispatch res)
(list default-vars default-vals entry-vars entry-vals keys body
aux-vars aux-vals)
:aux-vars (append (bind-vars) aux-vars)
:aux-vals (append (bind-vals) aux-vals)
:result cont
- :debug-name (debug-namify "~S processor" '&more)))
+ :debug-name (debug-namify "varargs entry point for ~A"
+ (as-debug-name source-name
+ debug-name))))
(last-entry (convert-optional-entry main-entry default-vars
(main-vals) ())))
(setf (optional-dispatch-main-entry res) main-entry)
(defun ir1-convert-hairy-args (res default-vars default-vals
entry-vars entry-vals
vars supplied-p-p body aux-vars
- aux-vals cont)
+ aux-vals cont
+ source-name debug-name)
(declare (type optional-dispatch res)
(list default-vars default-vals entry-vars entry-vals vars body
aux-vars aux-vals)
(ir1-convert-more res default-vars default-vals
entry-vars entry-vals
nil nil nil vars supplied-p-p body aux-vars
- aux-vals cont)
+ aux-vals cont source-name debug-name)
(let ((fun (ir1-convert-lambda-body
body (reverse default-vars)
:aux-vars aux-vars
:aux-vals aux-vals
:result cont
- :debug-name "hairy arg processor")))
+ :debug-name (debug-namify
+ "hairy arg processor for ~A"
+ (as-debug-name source-name
+ debug-name)))))
(setf (optional-dispatch-main-entry res) fun)
(push (if supplied-p-p
(convert-optional-entry fun entry-vars entry-vals ())
(nvals (cons (leaf-source-name arg) default-vals)))
(ir1-convert-hairy-args res nvars nvals nvars nvals
(rest vars) nil body aux-vars aux-vals
- cont)))
+ cont
+ source-name debug-name)))
(t
(let* ((arg (first vars))
(info (lambda-var-arg-info arg))
(let ((ep (generate-optional-default-entry
res default-vars default-vals
entry-vars entry-vals vars supplied-p-p body
- aux-vars aux-vals cont)))
+ aux-vars aux-vals cont
+ source-name debug-name)))
(push (if supplied-p-p
(convert-optional-entry ep entry-vars entry-vals ())
ep)
(ir1-convert-more res default-vars default-vals
entry-vars entry-vals
arg nil nil (rest vars) supplied-p-p body
- aux-vars aux-vals cont))
+ aux-vars aux-vals cont
+ source-name debug-name))
(:more-context
(ir1-convert-more res default-vars default-vals
entry-vars entry-vals
nil arg (second vars) (cddr vars) supplied-p-p
- body aux-vars aux-vals cont))
+ body aux-vars aux-vals cont
+ source-name debug-name))
(:keyword
(ir1-convert-more res default-vars default-vals
entry-vars entry-vals
nil nil nil vars supplied-p-p body aux-vars
- aux-vals cont)))))))
+ aux-vals cont source-name debug-name)))))))
;;; This function deals with the case where we have to make an
;;; OPTIONAL-DISPATCH to represent a LAMBDA. We cons up the result and
:%source-name source-name
:%debug-name debug-name))
(min (or (position-if #'lambda-var-arg-info vars) (length vars))))
+ (aver-live-component *current-component*)
(push res (component-new-funs *current-component*))
(ir1-convert-hairy-args res () () () () vars nil body aux-vars aux-vals
- cont)
+ cont source-name debug-name)
(setf (optional-dispatch-min-args res) min)
(setf (optional-dispatch-max-args res)
(+ (1- (length (optional-dispatch-entry-points res))) min))
;;; Convert a LAMBDA form into a LAMBDA leaf or an OPTIONAL-DISPATCH leaf.
(defun ir1-convert-lambda (form &key (source-name '.anonymous.) debug-name)
+
(unless (consp form)
(compiler-error "A ~S was found when expecting a lambda expression:~% ~S"
(type-of form)
form))
(unless (and (consp (cdr form)) (listp (cadr form)))
(compiler-error
- "The lambda expression has a missing or non-list lambda-list:~% ~S"
+ "The lambda expression has a missing or non-list lambda list:~% ~S"
form))
(multiple-value-bind (vars keyp allow-other-keys aux-vars aux-vals)
- (find-lambda-vars (cadr form))
+ (make-lambda-vars (cadr form))
(multiple-value-bind (forms decls) (sb!sys:parse-body (cddr form))
- (let* ((cont (make-continuation))
+ (let* ((result-cont (make-continuation))
(*lexenv* (process-decls decls
(append aux-vars vars)
- nil cont))
+ nil result-cont))
(res (if (or (find-if #'lambda-var-arg-info vars) keyp)
(ir1-convert-hairy-lambda forms vars keyp
allow-other-keys
- aux-vars aux-vals cont
+ aux-vars aux-vals result-cont
:source-name source-name
:debug-name debug-name)
(ir1-convert-lambda-body forms vars
:aux-vars aux-vars
:aux-vals aux-vals
- :result cont
+ :result result-cont
:source-name source-name
:debug-name debug-name))))
(setf (functional-inline-expansion res) form)
(specifier-type 'function))))
(values))
-\f
-;;;; hacking function names
-
-;;; This is like LAMBDA, except the result is tweaked so that FUN-NAME
-;;; can extract a name. (Also possibly the name could also be used at
-;;; compile time to emit more-informative name-based compiler
-;;; diagnostic messages as well.)
-(defmacro-mundanely named-lambda (name args &body body)
-
- ;; FIXME: For now, in this stub version, we just discard the name. A
- ;; non-stub version might use either macro-level LOAD-TIME-VALUE
- ;; hackery or customized IR1-transform level magic to actually put
- ;; the name in place.
- (aver (legal-fun-name-p name))
- `(lambda ,args ,@body))