0.8.21.37: fix bug 305
[sbcl.git] / src / compiler / ir1tran.lisp
index 6764c3a..5f37066 100644 (file)
   the efficiency of stable code.")
 
 (defvar *fun-names-in-this-file* nil)
-
-;;; *ALLOW-DEBUG-CATCH-TAG* controls whether we should allow the
-;;; insertion a (CATCH ...) around code to allow the debugger RETURN
-;;; command to function.
-(defvar *allow-debug-catch-tag* t)
 \f
 ;;;; namespace management utilities
 
@@ -71,7 +66,6 @@
   (unless (info :function :kind name)
     (setf (info :function :kind name) :function)
     (setf (info :function :where-from name) :assumed))
-
   (let ((where (info :function :where-from name)))
     (when (and (eq where :assumed)
               ;; In the ordinary target Lisp, it's silly to report
               ;; can't contain other objects
               (unless (typep value
                              '(or #-sb-xc-host unboxed-array
+                                  #+sb-xc-host (simple-array (unsigned-byte 8) (*))
                                   symbol
                                   number
                                   character
   (declare (list path))
   (let* ((*current-path* path)
         (component (make-empty-component))
-        (*current-component* component))
-    (setf (component-name component) "initial component")
+        (*current-component* component)
+         (*allow-instrumenting* t))
+    (setf (component-name component) 'initial-component)
     (setf (component-kind component) :initial)
     (let* ((forms (if for-value `(,form) `(,form nil)))
           (res (ir1-convert-lambda-body
                 forms ()
-                :debug-name (debug-namify "top level form " form))))
+                :debug-name (debug-name 'top-level-form form))))
       (setf (functional-entry-fun res) res
            (functional-arg-documentation res) ()
            (functional-kind res) :toplevel)
     (ir1-error-bailout (start next result form)
       (let ((*current-path* (or (gethash form *source-paths*)
                                (cons form *current-path*))))
-       (if (atom form)
-           (cond ((and (symbolp form) (not (keywordp form)))
-                  (ir1-convert-var start next result form))
-                 ((leaf-p form)
-                  (reference-leaf start next result form))
-                 (t
-                  (reference-constant start next result form)))
-           (let ((opname (car form)))
-             (cond ((or (symbolp opname) (leaf-p opname))
-                    (let ((lexical-def (if (leaf-p opname)
-                                            opname
-                                            (lexenv-find opname funs))))
-                      (typecase lexical-def
-                        (null
-                          (ir1-convert-global-functoid start next result
-                                                       form))
-                        (functional
-                         (ir1-convert-local-combination start next result
-                                                        form
-                                                        lexical-def))
-                        (global-var
-                         (ir1-convert-srctran start next result
-                                               lexical-def form))
-                        (t
-                         (aver (and (consp lexical-def)
-                                    (eq (car lexical-def) 'macro)))
-                         (ir1-convert start next result
-                                      (careful-expand-macro (cdr lexical-def)
-                                                            form))))))
-                   ((or (atom opname) (not (eq (car opname) 'lambda)))
-                    (compiler-error "illegal function call"))
-                   (t
-                    ;; implicitly (LAMBDA ..) because the LAMBDA
-                    ;; expression is the CAR of an executed form
-                    (ir1-convert-combination start next result
-                                             form
-                                             (ir1-convert-lambda
-                                              opname
-                                              :debug-name (debug-namify
-                                                           "LAMBDA CAR "
-                                                           opname)
-                                              :allow-debug-catch-tag t))))))))
+       (cond ((step-form-p form)
+               (ir1-convert-step start next result form))
+              ((atom form)
+               (cond ((and (symbolp form) (not (keywordp form)))
+                      (ir1-convert-var start next result form))
+                     ((leaf-p form)
+                      (reference-leaf start next result form))
+                     (t
+                      (reference-constant start next result form))))
+              (t
+               (let ((opname (car form)))
+                 (cond ((or (symbolp opname) (leaf-p opname))
+                        (let ((lexical-def (if (leaf-p opname)
+                                               opname
+                                               (lexenv-find opname funs))))
+                          (typecase lexical-def
+                            (null
+                             (ir1-convert-global-functoid start next result
+                                                          form))
+                            (functional
+                             (ir1-convert-local-combination start next result
+                                                            form
+                                                            lexical-def))
+                            (global-var
+                             (ir1-convert-srctran start next result
+                                                  lexical-def form))
+                            (t
+                             (aver (and (consp lexical-def)
+                                        (eq (car lexical-def) 'macro)))
+                             (ir1-convert start next result
+                                          (careful-expand-macro (cdr lexical-def)
+                                                                form))))))
+                       ((or (atom opname) (not (eq (car opname) 'lambda)))
+                        (compiler-error "illegal function call"))
+                       (t
+                        ;; implicitly (LAMBDA ..) because the LAMBDA
+                        ;; expression is the CAR of an executed form
+                        (ir1-convert-combination start next result
+                                                 form
+                                                 (ir1-convert-lambda
+                                                  opname
+                                                  :debug-name (debug-name
+                                                               'lambda-car 
+                                                               opname))))))))))
     (values))
-
+  
   ;; Generate a reference to a manifest constant, creating a new leaf
   ;; if necessary. If we are producing a fasl file, make sure that
   ;; MAKE-LOAD-FORM gets used on any parts of the constant that it
                                  :notinline))
                         (let ((functional (defined-fun-functional leaf)))
                           (when (and functional
-                                     (not (functional-kind functional)))
+                                     (not (functional-kind functional))
+                                     ;; Bug MISC.320: ir1-transform
+                                     ;; can create a reference to a
+                                     ;; inline-expanded function,
+                                     ;; defined in another component.
+                                     (not (and (lambda-p functional)
+                                               (neq (lambda-component functional)
+                                                    *current-component*))))
                             (maybe-reanalyze-functional functional))))
                    (when (and (lambda-p leaf)
                               (memq (functional-kind leaf)
              (new-vars nil cons))
       (dolist (var-name (rest decl))
        (when (boundp var-name)
-          (compiler-assert-symbol-home-package-unlocked var-name
-                                                        "declaring the type of ~A"))
+          (compiler-assert-symbol-home-package-unlocked
+          var-name "declaring the type of ~A"))
        (let* ((bound-var (find-in-bindings vars var-name))
               (var (or bound-var
                        (lexenv-find var-name vars)
     (collect ((res nil cons))
       (dolist (name names)
        (when (fboundp name)
-         (compiler-assert-symbol-home-package-unlocked name
-                                                        "declaring the ftype of ~A"))
-       (let ((found (find name fvars
-                          :key #'leaf-source-name
-                          :test #'equal)))
+         (compiler-assert-symbol-home-package-unlocked 
+          name "declaring the ftype of ~A"))
+       (let ((found (find name fvars :key #'leaf-source-name :test #'equal)))
          (cond
           (found
            (setf (leaf-type found) type)
        res)))
 
 ;;; Return a DEFINED-FUN which copies a GLOBAL-VAR but for its INLINEP
-;;; (and TYPE if notinline).
-(defun make-new-inlinep (var inlinep)
+;;; (and TYPE if notinline), plus type-restrictions from the lexenv.
+(defun make-new-inlinep (var inlinep local-type)
   (declare (type global-var var) (type inlinep inlinep))
-  (let ((res (make-defined-fun
-             :%source-name (leaf-source-name var)
-             :where-from (leaf-where-from var)
-             :type (if (and (eq inlinep :notinline)
-                            (not (eq (leaf-where-from var) :declared)))
-                       (specifier-type 'function)
-                       (leaf-type var))
-             :inlinep inlinep)))
+  (let* ((type (if (and (eq inlinep :notinline)
+                       (not (eq (leaf-where-from var) :declared)))
+                  (specifier-type 'function)
+                  (leaf-type var)))
+        (res (make-defined-fun
+              :%source-name (leaf-source-name var)
+              :where-from (leaf-where-from var)
+              :type (if local-type 
+                        (type-intersection local-type type)
+                        type)
+              :inlinep inlinep)))
     (when (defined-fun-p var)
       (setf (defined-fun-inline-expansion res)
            (defined-fun-inline-expansion var))
   (let ((sense (cdr (assoc (first spec) *inlinep-translations* :test #'eq)))
        (new-fenv ()))
     (dolist (name (rest spec))
-      (let ((fvar (find name fvars
-                       :key #'leaf-source-name
-                       :test #'equal)))
+      (let ((fvar (find name fvars :key #'leaf-source-name :test #'equal)))
        (if fvar
            (setf (functional-inlinep fvar) sense)
-           (let ((found
-                  (find-lexically-apparent-fun
-                   name "in an inline or notinline declaration")))
+           (let ((found (find-lexically-apparent-fun
+                         name "in an inline or notinline declaration")))
              (etypecase found
                (functional
                 (when (policy *lexenv* (>= speed inhibit-warnings))
                   (compiler-notify "ignoring ~A declaration not at ~
-                                    definition of local function:~%  ~S"
+                                     definition of local function:~%  ~S"
                                    sense name)))
                (global-var
-                (push (cons name (make-new-inlinep found sense))
-                      new-fenv)))))))
-
+                (let ((type 
+                       (cdr (assoc found (lexenv-type-restrictions res)))))
+                  (push (cons name (make-new-inlinep found sense type))
+                        new-fenv))))))))
     (if new-fenv
        (make-lexenv :default res :funs new-fenv)
        res)))
        (setf (lambda-var-ignorep var) t)))))
   (values))
 
-(defun process-dx-decl (names vars)
+(defun process-dx-decl (names vars fvars)
   (flet ((maybe-notify (control &rest args)
           (when (policy *lexenv* (> speed inhibit-warnings))
             (apply #'compiler-notify control args))))
                  (eq (car name) 'function)
                  (null (cddr name))
                  (valid-function-name-p (cadr name)))
-            (maybe-notify "ignoring DYNAMIC-EXTENT declaration for ~S" name))
+             (let* ((fname (cadr name))
+                    (bound-fun (find fname fvars
+                                     :key #'leaf-source-name
+                                     :test #'equal)))
+              (etypecase bound-fun
+                (leaf
+                  #!+stack-allocatable-closures
+                 (setf (leaf-dynamic-extent bound-fun) t)
+                  #!-stack-allocatable-closures
+                  (maybe-notify
+                   "ignoring DYNAMIC-EXTENT declaration on a function ~S ~
+                    (not supported on this platform)." fname))
+                (cons
+                 (compiler-error "DYNAMIC-EXTENT on macro: ~S" fname))
+                 (null
+                  (maybe-notify
+                   "ignoring DYNAMIC-EXTENT declaration for free ~S"
+                   fname)))))
            (t (compiler-error "DYNAMIC-EXTENT on a weird thing: ~S" name))))
       (maybe-notify "ignoring DYNAMIC-EXTENT declarations for ~S" names))))
 
                        `(values ,@types)))))
           res))
        (dynamic-extent
-       (process-dx-decl (cdr spec) vars)
+       (process-dx-decl (cdr spec) vars fvars)
         res)
        ((disable-package-locks enable-package-locks)
         (make-lexenv
          :default res
-         :disabled-package-locks (process-package-lock-decl 
+         :disabled-package-locks (process-package-lock-decl
                                   spec (lexenv-disabled-package-locks res))))
        (t
         (unless (info :declaration :recognized (first spec))