0.7.13.pcl-class.1
[sbcl.git] / src / compiler / typetran.lisp
index 03b4c0b..06f0de1 100644 (file)
@@ -72,6 +72,8 @@
           nil)
          ((csubtypep otype type)
           t)
+          ((eq type *empty-type*)
+           nil)
          (t
           (give-up-ir1-transform)))))
 
@@ -81,7 +83,7 @@
     (give-up-ir1-transform))
   (ir1-transform-type-predicate
    object
-   (specifier-type (continuation-value type))))
+   (ir1-transform-specifier-type (continuation-value type))))
 
 ;;; This is the IR1 transform for simple type predicates. It checks
 ;;; whether the single argument is known to (not) be of the
 
 ;;; If FIND-CLASS is called on a constant class, locate the CLASS-CELL
 ;;; at load time.
-(deftransform find-class ((name) ((constant-argument symbol)) *
-                         :when :both)
+(deftransform find-classoid ((name) ((constant-arg symbol)) *)
   (let* ((name (continuation-value name))
-        (cell (find-class-cell name)))
-    `(or (class-cell-class ',cell)
+        (cell (find-classoid-cell name)))
+    `(or (classoid-cell-classoid ',cell)
         (error "class not yet defined: ~S" name))))
 \f
 ;;;; standard type predicates, i.e. those defined in package COMMON-LISP,
             (satisfies `(if (funcall #',(second spec) ,object) t nil))
             ((not and)
              (once-only ((n-obj object))
-               `(,(first spec) ,@(mapcar #'(lambda (x)
-                                             `(typep ,n-obj ',x))
+               `(,(first spec) ,@(mapcar (lambda (x)
+                                           `(typep ,n-obj ',x))
                                          (rest spec))))))))))
 
+(defun source-transform-negation-typep (object type)
+  (declare (type negation-type type))
+  (let ((spec (type-specifier (negation-type-type type))))
+    `(not (typep ,object ',spec))))
+
 ;;; Do source transformation for TYPEP of a known union type. If a
 ;;; union type contains LIST, then we pull that out and make it into a
 ;;; single LISTP call. Note that if SYMBOL is in the union, then LIST
 ;;; then we also check whether the layout for the object is invalid
 ;;; and signal an error if so. Otherwise, look up the indirect
 ;;; class-cell and call CLASS-CELL-TYPEP at runtime.
-(deftransform %instance-typep ((object spec) (* *) * :node node :when :both)
+(deftransform %instance-typep ((object spec) (* *) * :node node)
   (aver (constant-continuation-p spec))
   (let* ((spec (continuation-value spec))
         (class (specifier-type spec))
-        (name (sb!xc:class-name class))
+        (name (classoid-name class))
         (otype (continuation-type object))
         (layout (let ((res (info :type :compiler-layout name)))
                   (if (and res (not (layout-invalid res)))
       ((csubtypep otype class)
        t)
       ;; If not properly named, error.
-      ((not (and name (eq (sb!xc:find-class name) class)))
+      ((not (and name (eq (find-classoid name) class)))
        (compiler-error "can't compile TYPEP of anonymous or undefined ~
                        class:~%  ~S"
                       class))
             (t
              (values '(lambda (x) (declare (ignore x)) t) 'layout-of)))
         (cond
-          ((and (eq (class-state class) :sealed) layout
-                (not (class-subclasses class)))
+          ((and (eq (classoid-state class) :sealed) layout
+                (not (classoid-subclasses class)))
            ;; Sealed and has no subclasses.
            (let ((n-layout (gensym)))
              `(and (,pred object)
                              `((when (layout-invalid ,n-layout)
                                  (%layout-invalid-error object ',layout))))
                      (eq ,n-layout ',layout)))))
-          ((and (typep class 'basic-structure-class) layout)
+          ((and (typep class 'basic-structure-classoid) layout)
            ;; structure type tests; hierarchical layout depths
            (let ((depthoid (layout-depthoid layout))
                  (n-layout (gensym)))
           (t
            (/noshow "default case -- ,PRED and CLASS-CELL-TYPEP")
            `(and (,pred object)
-                 (class-cell-typep (,get-layout object)
-                                   ',(find-class-cell name)
-                                   object)))))))))
+                 (classoid-cell-typep (,get-layout object)
+                                      ',(find-classoid-cell name)
+                                      object)))))))))
 
 ;;; If the specifier argument is a quoted constant, then we consider
 ;;; converting into a simple predicate or other stuff. If the type is
   ;; source transform another chance, so it all works out OK, in a
   ;; weird roundabout way. -- WHN 2001-03-18
   (if (and (consp spec) (eq (car spec) 'quote))
-      (let ((type (specifier-type (cadr spec))))
-       (or (let ((pred (cdr (assoc type *backend-type-predicates*
+      (let ((type (careful-specifier-type (cadr spec))))
+       (or (when (not type)
+              (compiler-warn "illegal type specifier for TYPEP: ~S"
+                             (cadr spec))
+              `(%typep ,object ,spec))
+            (let ((pred (cdr (assoc type *backend-type-predicates*
                                    :test #'type=))))
              (when pred `(,pred ,object)))
            (typecase type
              (hairy-type
               (source-transform-hairy-typep object type))
+             (negation-type
+              (source-transform-negation-typep object type))
              (union-type
               (source-transform-union-typep object type))
              (intersection-type
              (member-type
               `(member ,object ',(member-type-members type)))
              (args-type
-              (compiler-warning "illegal type specifier for TYPEP: ~S"
-                                (cadr spec))
+              (compiler-warn "illegal type specifier for TYPEP: ~S"
+                             (cadr spec))
               `(%typep ,object ,spec))
              (t nil))
            (typecase type
              (numeric-type
               (source-transform-numeric-typep object type))
-             (sb!xc:class
+             (classoid
               `(%instance-typep ,object ,spec))
              (array-type
               (source-transform-array-typep object type))
 \f
 ;;;; coercion
 
-(deftransform coerce ((x type) (* *) * :when :both)
+(deftransform coerce ((x type) (* *) * :node node)
   (unless (constant-continuation-p type)
     (give-up-ir1-transform))
-  (let ((tspec (specifier-type (continuation-value type))))
+  (let ((tspec (ir1-transform-specifier-type (continuation-value type))))
     (if (csubtypep (continuation-type x) tspec)
        'x
        ;; Note: The THE here makes sure that specifiers like
        `(the ,(continuation-value type)
           ,(cond
             ((csubtypep tspec (specifier-type 'double-float))
-             '(%double-float x))       
+             '(%double-float x))
             ;; FIXME: #!+long-float (t ,(error "LONG-FLOAT case needed"))
             ((csubtypep tspec (specifier-type 'float))
              '(%single-float x))
-            ((csubtypep tspec (specifier-type 'simple-vector))
-             '(coerce-to-simple-vector x))
+            ((and (csubtypep tspec (specifier-type 'simple-vector))
+                  (policy node (< safety 3)))
+             `(if (simple-vector-p x)
+                  x
+                  (replace (make-array (length x)) x)))
+            ;; FIXME: other VECTOR types?
             (t
              (give-up-ir1-transform)))))))