1.0.4.39: get rid of hardcoded mutex and spinlock slot indexes
[sbcl.git] / src / code / target-alieneval.lisp
index 822dd7d..5d0036a 100644 (file)
 (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.
 
 (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
@@ -792,18 +810,20 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
          (argument-names arguments)
          (argument-specs (cddr specifier)))
     `(lambda (args-pointer result-pointer function)
+       ;; FIXME: the saps are not gc safe
        (let ((args-sap (int-sap
                         (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
                  for spec in argument-specs
-                 for offset = 0 ; FIXME: Should this not be AND OFFSET ...?
-                 then (+ offset (alien-callback-argument-bytes spec env))
                  collect `(,(pop argument-names) ,spec
                             :local ,(alien-callback-accessor-form
-                                     spec 'args-sap offset)))
+                                     spec 'args-sap offset))
+                 do (incf offset (alien-callback-argument-bytes spec env)))
            ,(flet ((store (spec)
                           (if spec
                               `(setf (deref (sap-alien res-sap (* ,spec)))
@@ -837,7 +857,8 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
   (destructuring-bind (function result-type &rest argument-types)
       specifier
     (aver (eq 'function function))
-    (values (parse-alien-type result-type env)
+    (values (let ((*values-type-okay* t))
+              (parse-alien-type result-type env))
             (mapcar (lambda (spec)
                       (parse-alien-type spec env))
                     argument-types))))
@@ -852,7 +873,8 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.")
   (let ((type (parse-alien-type spec env)))
     (if (or (alien-integer-type-p type)
             (alien-float-type-p type)
-            (alien-pointer-type-p type))
+            (alien-pointer-type-p type)
+            (alien-system-area-pointer-type-p type))
         (ceiling (alien-type-word-aligned-bits type) sb!vm:n-byte-bits)
         (error "Unsupported callback argument type: ~A" type))))
 
@@ -861,6 +883,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)
@@ -876,8 +903,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)
@@ -924,8 +952,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?
 ;;;