1.0.20.26: nicer ONCE-ONLY expansion
[sbcl.git] / src / code / target-alieneval.lisp
index 21585e6..fec2359 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)
     (setf (info :variable :kind lisp-name) :alien)
     (setf (info :variable :where-from lisp-name) :defined)
-    (clear-info :variable :constant-value lisp-name)
     (setf (info :variable :alien-info lisp-name)
           (make-heap-alien-info :type type
                                 :sap-form `(foreign-symbol-sap ',alien-name t)))))
    ALLOCATION should be one of:
      :LOCAL (the default)
        The alien is allocated on the stack, and has dynamic extent.
-     :STATIC
-       The alien is allocated on the heap, and has infinite extent. The alien
-       is allocated at load time, so the same piece of memory is used each time
-       this form executes.
      :EXTERN
        No alien is allocated, but VAR is established as a local name for
        the external alien given by EXTERNAL-NAME."
+  ;; FIXME:
+  ;;      :STATIC
+  ;;        The alien is allocated on the heap, and has infinite extent. The alien
+  ;;        is allocated at load time, so the same piece of memory is used each time
+  ;;        this form executes.
   (/show "entering WITH-ALIEN" bindings)
   (with-auxiliary-alien-types env
     (dolist (binding (reverse bindings))
       (/show binding)
       (destructuring-bind
-          (symbol type &optional (opt1 nil opt1p) (opt2 nil opt2p))
+            (symbol type &optional (opt1 nil opt1p) (opt2 nil opt2p))
           binding
         (/show symbol type opt1 opt2)
         (let* ((alien-type (parse-alien-type type env))
                        `((let ((,sap (load-time-value (%make-alien ...))))
                            (declare (type system-area-pointer ,sap))
                            (symbol-macrolet
-                            ((,symbol (sap-alien ,sap ,type)))
-                            ,@(when initial-value
-                                `((setq ,symbol ,initial-value)))
-                            ,@body)))))
+                               ((,symbol (sap-alien ,sap ,type)))
+                             ,@(when initial-value
+                                 `((setq ,symbol ,initial-value)))
+                             ,@body)))))
                     (:extern
                      (/show0 ":EXTERN case")
                      (let ((info (make-heap-alien-info
                                   :sap-form `(foreign-symbol-sap ',initial-value
                                                                  ,datap))))
                        `((symbol-macrolet
-                          ((,symbol (%heap-alien ',info)))
-                          ,@body))))
+                             ((,symbol (%heap-alien ',info)))
+                           ,@body))))
                     (:local
                      (/show0 ":LOCAL case")
-                     (let ((var (gensym))
-                           (initval (if initial-value (gensym)))
-                           (info (make-local-alien-info :type alien-type)))
+                     (let* ((var (gensym))
+                            (initval (if initial-value (gensym)))
+                            (info (make-local-alien-info :type alien-type))
+                            (inner-body
+                             `((note-local-alien-type ',info ,var)
+                               (symbol-macrolet ((,symbol (local-alien ',info ,var)))
+                                 ,@(when initial-value
+                                     `((setq ,symbol ,initval)))
+                                 ,@body)))
+                            (body-forms
+                             (if initial-value
+                                 `((let ((,initval ,initial-value))
+                                     ,@inner-body))
+                                 inner-body)))
                        (/show var initval info)
-                       `((let ((,var (make-local-alien ',info))
-                               ,@(when initial-value
-                                   `((,initval ,initial-value))))
-                           (note-local-alien-type ',info ,var)
-                           (multiple-value-prog1
-                               (symbol-macrolet
-                                ((,symbol (local-alien ',info ,var)))
-                                ,@(when initial-value
-                                    `((setq ,symbol ,initval)))
-                                ,@body)
-                               (dispose-local-alien ',info ,var))))))))))))
+                       #!+(or x86 x86-64)
+                       `((let ((,var (make-local-alien ',info)))
+                           ,@body-forms))
+                       ;; FIXME: This version is less efficient then it needs to be, since
+                       ;; it could just save and restore the number-stack pointer once,
+                       ;; instead of doing multiple decrements if there are multiple bindings.
+                       #!-(or x86 x86-64)
+                       `((let (,var)
+                           (unwind-protect
+                               (progn
+                                 (setf ,var (make-local-alien ',info))
+                                 (let ((,var ,var))
+                                   ,@body-forms))
+                             (dispose-local-alien ',info ,var))))))))))))
     (/show "revised" body)
     (verify-local-auxiliaries-okay)
     (/show0 "back from VERIFY-LOCAL-AUXILIARIES-OK, returning")
     `(symbol-macrolet ((&auxiliary-type-definitions&
                         ,(append *new-auxiliary-types*
                                  (auxiliary-type-definitions env))))
+       #!+(or x86 x86-64)
+       (let ((sb!vm::*alien-stack* sb!vm::*alien-stack*))
+         ,@body)
+       #!-(or x86 x86-64)
        ,@body)))
 \f
 ;;;; runtime C values that don't correspond directly to Lisp types
@@ -446,7 +460,8 @@ allocated using ``malloc'', so it can be passed to foreign functions which use
      (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)
@@ -538,33 +553,38 @@ allocated using ``malloc'', so it can be passed to foreign functions which use
 \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 (compute-deport-alloc-lambda type) 'function)
+  (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
@@ -722,10 +742,6 @@ allocated using ``malloc'', so it can be passed to foreign functions which use
                       (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
@@ -787,6 +803,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