1.0.12.13: sequence optimizations: SUBSEQ, part 3
[sbcl.git] / src / code / target-alieneval.lisp
index 7a6e041..d674b64 100644 (file)
                                    ',alien-name
                                    ',alien-type))))))
 
-(defmacro def-alien-variable (&rest rest)
-  (deprecation-warning 'def-alien-variable 'define-alien-variable)
-  `(define-alien-variable ,@rest))
-
 ;;; Do the actual work of DEFINE-ALIEN-VARIABLE.
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun %define-alien-variable (lisp-name alien-name type)
 (defmacro make-alien (type &optional size &environment env)
   #!+sb-doc
   "Allocate an alien of type TYPE and return an alien pointer to it. If SIZE
-   is supplied, how it is interpreted depends on TYPE. If TYPE is an array
-   type, SIZE is used as the first dimension for the allocated array. If TYPE
-   is not an array, then SIZE is the number of elements to allocate. The
-   memory is allocated using ``malloc'', so it can be passed to foreign
-   functions which use ``free''."
+is supplied, how it is interpreted depends on TYPE. If TYPE is an array type,
+SIZE is used as the first dimension for the allocated array. If TYPE is not an
+array, then SIZE is the number of elements to allocate. The memory is
+allocated using ``malloc'', so it can be passed to foreign functions which use
+``free''."
   (let ((alien-type (if (alien-type-p type)
                         type
                         (parse-alien-type type env))))
         (if (alien-array-type-p alien-type)
             (let ((dims (alien-array-type-dimensions alien-type)))
               (cond
-               (size
-                (unless dims
-                  (error
-                   "cannot override the size of zero-dimensional arrays"))
-                (when (constantp size)
-                  (setf alien-type (copy-alien-array-type alien-type))
-                  (setf (alien-array-type-dimensions alien-type)
-                        (cons (eval size) (cdr dims)))))
-               (dims
-                (setf size (car dims)))
-               (t
-                (setf size 1)))
+                (size
+                 (unless dims
+                   (error
+                    "cannot override the size of zero-dimensional arrays"))
+                 (when (constantp size)
+                   (setf alien-type (copy-alien-array-type alien-type))
+                   (setf (alien-array-type-dimensions alien-type)
+                         (cons (constant-form-value size) (cdr dims)))))
+                (dims
+                 (setf size (car dims)))
+                (t
+                 (setf size 1)))
               (values `(* ,size ,@(cdr dims))
                       (alien-array-type-element-type alien-type)))
             (values (or size 1) alien-type))
         (unless alignment
           (error "The alignment of ~S is unknown."
                  (unparse-alien-type element-type)))
-        `(%sap-alien (%make-alien (* ,(align-offset bits alignment)
-                                     ,size-expr))
-                     ',(make-alien-pointer-type :to alien-type))))))
+        ;; This is the one place where the %SAP-ALIEN note is quite
+        ;; undesirable, in most uses of MAKE-ALIEN the %SAP-ALIEN
+        ;; cannot be optimized away.
+        `(locally (declare (muffle-conditions compiler-note))
+           (%sap-alien (%make-alien (* ,(align-offset bits alignment)
+                                       ,size-expr))
+                       ',(make-alien-pointer-type :to alien-type)))))))
 
 ;;; Allocate a block of memory at least BITS bits long and return a
 ;;; system area pointer to it.
      (lambda ()
        (alien-funcall
         (extern-alien "free" (function (values) system-area-pointer))
-        alien-sap)))
+        alien-sap))
+     :dont-save t)
     alien))
 
 (defun note-local-alien-type (info alien)
 
 (define-setf-expander local-alien (&whole whole info alien)
   (let ((value (gensym))
+        (info-var (gensym))
+        (alloc-tmp (gensym))
         (info (if (and (consp info)
                        (eq (car info) 'quote))
                   (second info)
             (list value)
             `(if (%local-alien-forced-to-memory-p ',info)
                  (%set-local-alien ',info ,alien ,value)
-                 (setf ,alien
-                       (deport ,value ',(local-alien-info-type info))))
+                   (let* ((,info-var ',(local-alien-info-type info))
+                          (,alloc-tmp (deport-alloc ,value ,info-var)))
+                     (maybe-with-pinned-objects (,alloc-tmp) (,(local-alien-info-type info))
+                       (setf ,alien (deport ,alloc-tmp ,info-var)))))
             whole)))
 
 (defun %local-alien-forced-to-memory-p (info)
 \f
 ;;;; NATURALIZE, DEPORT, EXTRACT-ALIEN-VALUE, DEPOSIT-ALIEN-VALUE
 
+(defun coerce-to-interpreted-function (lambda-form)
+  (let (#!+sb-eval
+        (*evaluator-mode* :interpret))
+    (coerce lambda-form 'function)))
+
 (defun naturalize (alien type)
   (declare (type alien-type type))
-  (funcall (coerce (compute-naturalize-lambda type) 'function)
+  (funcall (coerce-to-interpreted-function (compute-naturalize-lambda type))
            alien type))
 
 (defun deport (value type)
   (declare (type alien-type type))
-  (funcall (coerce (compute-deport-lambda type) 'function)
+  (funcall (coerce-to-interpreted-function (compute-deport-lambda type))
+           value type))
+
+(defun deport-alloc (value type)
+  (declare (type alien-type type))
+  (funcall (coerce-to-interpreted-function (compute-deport-alloc-lambda type))
            value type))
 
 (defun extract-alien-value (sap offset type)
   (declare (type system-area-pointer sap)
            (type unsigned-byte offset)
            (type alien-type type))
-  (funcall (coerce (compute-extract-lambda type) 'function)
+  (funcall (coerce-to-interpreted-function (compute-extract-lambda type))
            sap offset type))
 
 (defun deposit-alien-value (sap offset type value)
   (declare (type system-area-pointer sap)
            (type unsigned-byte offset)
            (type alien-type type))
-  (funcall (coerce (compute-deposit-lambda type) 'function)
+  (funcall (coerce-to-interpreted-function (compute-deposit-lambda type))
            sap offset type value))
 \f
 ;;;; ALIEN-FUNCALL, DEFINE-ALIEN-ROUTINE
       (t
        (error "~S is not an alien function." alien)))))
 
-(defun alien-funcall-stdcall (alien &rest args)
-  #!+sb-doc
-  "Call the foreign function ALIEN with the specified arguments. ALIEN's
-   type specifies the argument and result types."
-  (declare (type alien-value alien))
-  (let ((type (alien-value-type alien)))
-    (typecase type
-      (alien-pointer-type
-       (apply #'alien-funcall-stdcall (deref alien) args))
-      (alien-fun-type
-       (unless (= (length (alien-fun-type-arg-types type))
-                  (length args))
-         (error "wrong number of arguments for ~S~%expected ~W, got ~W"
-                type
-                (length (alien-fun-type-arg-types type))
-                (length args)))
-       (let ((stub (alien-fun-type-stub type)))
-         (unless stub
-           (setf stub
-                 (let ((fun (gensym))
-                       (parms (make-gensym-list (length args))))
-                   (compile nil
-                            `(lambda (,fun ,@parms)
-                               (declare (optimize (sb!c::insert-step-conditions 0)))
-                               (declare (type (alien ,type) ,fun))
-                               (alien-funcall-stdcall ,fun ,@parms)))))
-           (setf (alien-fun-type-stub type) stub))
-         (apply stub alien args)))
-      (t
-       (error "~S is not an alien function." alien)))))
-
 (defmacro define-alien-routine (name result-type
                                      &rest args
                                      &environment lexenv)
                       (values ,@temps ,@(results))))
                  (values (alien-funcall ,lisp-name ,@(alien-args))
                          ,@(results)))))))))
-
-(defmacro def-alien-routine (&rest rest)
-  (deprecation-warning 'def-alien-routine 'define-alien-routine)
-  `(define-alien-routine ,@rest))
 \f
 (defun alien-typep (object type)
   #!+sb-doc
@@ -805,6 +785,7 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
                 (vector-push-extend
                  (alien-callback-lisp-trampoline wrapper function)
                  *alien-callback-trampolines*)
+                ;; Assembler-wrapper is static, so sap-taking is safe.
                 (let ((sap (vector-sap assembler-wrapper)))
                   (push (cons sap (make-callback-info :specifier specifier
                                                       :function function
@@ -828,6 +809,7 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
                         (sb!kernel:get-lisp-obj-address args-pointer)))
              (res-sap (int-sap
                        (sb!kernel:get-lisp-obj-address result-pointer))))
+         (declare (ignorable args-sap res-sap))
          (with-alien
              ,(loop
                  with offset = 0
@@ -895,6 +877,11 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
            return
            arguments))
 
+;;; To ensure that callback wrapper functions continue working even
+;;; if #'ENTER-ALIEN-CALLBACK moves in memory, access to it is indirected
+;;; through the *ENTER-ALIEN-CALLBACK* static symbol. -- JES, 2006-01-01
+(defvar *enter-alien-callback* #'enter-alien-callback)
+
 ;;;; interface (not public, yet) for alien callbacks
 
 (defmacro alien-callback (specifier function &environment env)
@@ -910,8 +897,9 @@ one."
                            ,function
                            (or (gethash ',specifier *alien-callback-wrappers*)
                                (setf (gethash ',specifier *alien-callback-wrappers*)
-                                     ,(alien-callback-lisp-wrapper-lambda
-                                       specifier result-type argument-types env))))
+                                     (compile nil
+                                              ',(alien-callback-lisp-wrapper-lambda
+                                                 specifier result-type argument-types env)))))
       ',(parse-alien-type specifier env))))
 
 (defun alien-callback-p (alien)
@@ -958,8 +946,8 @@ callback signal an error."
       (setf (callback-info-function info) nil)
       t)))
 
-;;; FIXME: This calls assembles a new callback for every closure,
-;;; which suck hugely. ...not that I can think of an obvious
+;;; FIXME: This call assembles a new callback for every closure,
+;;; which sucks hugely. ...not that I can think of an obvious
 ;;; solution. Possibly maybe we could write a generalized closure
 ;;; callback analogous to closure_tramp, and share the actual wrapper?
 ;;;