X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-alieneval.lisp;h=3150c14febe167d5d5b2c22f9d59450de96427b3;hb=e0814eee6f6dea52db010b45a330100f2fe65832;hp=054e282a19cc77985d26eaf30cbfd3c55d1fc732;hpb=cea4896b2482b7b2b429c1631d774b4cfbc0efba;p=sbcl.git diff --git a/src/code/target-alieneval.lisp b/src/code/target-alieneval.lisp index 054e282..3150c14 100644 --- a/src/code/target-alieneval.lisp +++ b/src/code/target-alieneval.lisp @@ -11,6 +11,8 @@ ;;;; files for more information. (in-package "SB!ALIEN") + +(/show0 "target-alieneval.lisp 15") ;;;; alien variables @@ -43,7 +45,7 @@ (error "badly formed alien name")) (values (cadr name) (car name)))))) -(defmacro def-alien-variable (name type &environment env) +(defmacro define-alien-variable (name type &environment env) #!+sb-doc "Define NAME as an external alien variable of type TYPE. NAME should be a list of a string holding the alien name and a symbol to use as the Lisp @@ -55,13 +57,17 @@ `(eval-when (:compile-toplevel :load-toplevel :execute) ,@(when *new-auxiliary-types* `((%def-auxiliary-alien-types ',*new-auxiliary-types*))) - (%def-alien-variable ',lisp-name - ',alien-name - ',alien-type)))))) + (%define-alien-variable ',lisp-name + ',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 DEF-ALIEN-VARIABLE. +;;; Do the actual work of DEFINE-ALIEN-VARIABLE. (eval-when (:compile-toplevel :load-toplevel :execute) - (defun %def-alien-variable (lisp-name alien-name type) + (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) @@ -95,12 +101,16 @@ :EXTERN No alien is allocated, but VAR is established as a local name for the external alien given by EXTERNAL-NAME." + (/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)) binding + (/show symbol type opt1 opt2) (let ((alien-type (parse-alien-type type env))) + (/show alien-type) (multiple-value-bind (allocation initial-value) (if opt2p (values opt1 opt2) @@ -111,6 +121,7 @@ (values opt1 nil)) (t (values :local opt1)))) + (/show allocation initial-value) (setf body (ecase allocation #+nil @@ -126,6 +137,7 @@ `((setq ,symbol ,initial-value))) ,@body))))) (:extern + (/show ":EXTERN case") (let ((info (make-heap-alien-info :type alien-type :sap-form `(foreign-symbol-address @@ -134,9 +146,11 @@ ((,symbol (%heap-alien ',info))) ,@body)))) (:local + (/show ":LOCAL case") (let ((var (gensym)) (initval (if initial-value (gensym))) (info (make-local-alien-info :type alien-type))) + (/show var initval info) `((let ((,var (make-local-alien ',info)) ,@(when initial-value `((,initval ,initial-value)))) @@ -148,7 +162,9 @@ `((setq ,symbol ,initval))) ,@body) (dispose-local-alien ',info ,var)))))))))))) + (/show "revised" body) (verify-local-auxiliaries-okay) + (/show "back from VERIFY-LOCAL-AUXILIARIES-OK, returning") `(symbol-macrolet ((&auxiliary-type-definitions& ,(append *new-auxiliary-types* (auxiliary-type-definitions env)))) @@ -156,8 +172,6 @@ ;;;; runtime C values that don't correspond directly to Lisp types -;;; ALIEN-VALUE -;;; ;;; Note: The DEFSTRUCT for ALIEN-VALUE lives in a separate file ;;; 'cause it has to be real early in the cold-load order. #!-sb-fluid (declaim (freeze-type alien-value)) @@ -242,15 +256,16 @@ ;;; system area pointer to it. #!-sb-fluid (declaim (inline %make-alien)) (defun %make-alien (bits) - (declare (type index bits) (optimize-interface (safety 2))) - (alien-funcall (extern-alien "malloc" (function system-area-pointer unsigned)) + (declare (type index bits)) + (alien-funcall (extern-alien "malloc" + (function system-area-pointer unsigned)) (ash (the index (+ bits 7)) -3))) #!-sb-fluid (declaim (inline free-alien)) (defun free-alien (alien) #!+sb-doc "Dispose of the storage pointed to by ALIEN. ALIEN must have been allocated - by MAKE-ALIEN or ``malloc''." + by MAKE-ALIEN or malloc(3)." (alien-funcall (extern-alien "free" (function (values) system-area-pointer)) (alien-sap alien)) nil) @@ -263,7 +278,7 @@ (type symbol slot)) (or (find slot (alien-record-type-fields type) :key #'alien-record-field-name) - (error "There is no slot named ~S in ~S" slot type))) + (error "There is no slot named ~S in ~S." slot type))) ;;; Extract the value from the named slot from the record ALIEN. If ;;; ALIEN is actually a pointer, then DEREF it first. @@ -314,13 +329,14 @@ (let* ((field (slot-or-lose type slot)) (offset (alien-record-field-offset field)) (field-type (alien-record-field-type field))) - (%sap-alien (sap+ (alien-sap alien) (/ offset sb!vm:byte-bits)) + (%sap-alien (sap+ (alien-sap alien) (/ offset sb!vm:n-byte-bits)) (make-alien-pointer-type :to field-type))))))) ;;;; the DEREF operator -;;; Does most of the work of the different DEREF methods. Returns two values: -;;; the type and the offset (in bits) of the refered to alien. +;;; This function does most of the work of the different DEREF +;;; methods. It returns two values: the type and the offset (in bits) +;;; of the referred-to alien. (defun deref-guts (alien indices) (declare (type alien-value alien) (type list indices) @@ -329,7 +345,7 @@ (etypecase type (alien-pointer-type (when (cdr indices) - (error "too many indices when derefing ~S: ~D" + (error "too many indices when DEREF'ing ~S: ~W" type (length indices))) (let ((element-type (alien-pointer-type-to type))) @@ -341,7 +357,7 @@ 0)))) (alien-array-type (unless (= (length indices) (length (alien-array-type-dimensions type))) - (error "incorrect number of indices when derefing ~S: ~D" + (error "incorrect number of indices when DEREF'ing ~S: ~W" type (length indices))) (labels ((frob (dims indices offset) (if (null dims) @@ -387,7 +403,7 @@ (type list indices) (optimize (inhibit-warnings 3))) (multiple-value-bind (target-type offset) (deref-guts alien indices) - (%sap-alien (sap+ (alien-value-sap alien) (/ offset sb!vm:byte-bits)) + (%sap-alien (sap+ (alien-value-sap alien) (/ offset sb!vm:n-byte-bits)) (make-alien-pointer-type :to target-type)))) ;;;; accessing heap alien variables @@ -420,10 +436,10 @@ (alien-sap (alien-sap alien))) (finalize alien - #'(lambda () - (alien-funcall - (extern-alien "free" (function (values) system-area-pointer)) - alien-sap))) + (lambda () + (alien-funcall + (extern-alien "free" (function (values) system-area-pointer)) + alien-sap))) alien)) (defun note-local-alien-type (info alien) @@ -448,12 +464,10 @@ (values nil nil (list value) - (if sb!c:*converting-for-interpreter* - `(%set-local-alien ',info ,alien ,value) - `(if (%local-alien-forced-to-memory-p ',info) - (%set-local-alien ',info ,alien ,value) - (setf ,alien - (deport ,value ',(local-alien-info-type info))))) + `(if (%local-alien-forced-to-memory-p ',info) + (%set-local-alien ',info ,alien ,value) + (setf ,alien + (deport ,value ',(local-alien-info-type info)))) whole))) (defun %local-alien-forced-to-memory-p (info) @@ -481,15 +495,15 @@ (defun %cast (alien target-type) (declare (type alien-value alien) (type alien-type target-type) - (optimize-interface (safety 2)) + (optimize (safety 2)) (optimize (inhibit-warnings 3))) (if (or (alien-pointer-type-p target-type) (alien-array-type-p target-type) - (alien-function-type-p target-type)) + (alien-fun-type-p target-type)) (let ((alien-type (alien-value-type alien))) (if (or (alien-pointer-type-p alien-type) (alien-array-type-p alien-type) - (alien-function-type-p alien-type)) + (alien-fun-type-p alien-type)) (naturalize (alien-value-sap alien) target-type) (error "~S cannot be casted." alien))) (error "cannot cast to alien type ~S" (unparse-alien-type target-type)))) @@ -506,8 +520,8 @@ (values (ceiling bits (ecase units (:bits 1) - (:bytes sb!vm:byte-bits) - (:words sb!vm:word-bits)))) + (:bytes sb!vm:n-byte-bits) + (:words sb!vm:n-word-bits)))) (error "unknown size for alien type ~S" (unparse-alien-type alien-type))))) @@ -537,7 +551,7 @@ (funcall (coerce (compute-deposit-lambda type) 'function) sap offset type value)) -;;;; ALIEN-FUNCALL, DEF-ALIEN-ROUTINE +;;;; ALIEN-FUNCALL, DEFINE-ALIEN-ROUTINE (defun alien-funcall (alien &rest args) #!+sb-doc @@ -548,14 +562,14 @@ (typecase type (alien-pointer-type (apply #'alien-funcall (deref alien) args)) - (alien-function-type - (unless (= (length (alien-function-type-arg-types type)) + (alien-fun-type + (unless (= (length (alien-fun-type-arg-types type)) (length args)) - (error "wrong number of arguments for ~S~%expected ~D, got ~D" + (error "wrong number of arguments for ~S~%expected ~W, got ~W" type - (length (alien-function-type-arg-types type)) + (length (alien-fun-type-arg-types type)) (length args))) - (let ((stub (alien-function-type-stub type))) + (let ((stub (alien-fun-type-stub type))) (unless stub (setf stub (let ((fun (gensym)) @@ -564,28 +578,32 @@ `(lambda (,fun ,@parms) (declare (type (alien ,type) ,fun)) (alien-funcall ,fun ,@parms))))) - (setf (alien-function-type-stub type) stub)) + (setf (alien-fun-type-stub type) stub)) (apply stub alien args))) (t (error "~S is not an alien function." alien))))) -(defmacro def-alien-routine (name result-type &rest args &environment env) +(defmacro define-alien-routine (name result-type + &rest args + &environment lexenv) #!+sb-doc - "Def-C-Routine Name Result-Type - {(Arg-Name Arg-Type [Style])}* + "DEFINE-ALIEN-ROUTINE Name Result-Type {(Arg-Name Arg-Type [Style])}* + + Define a foreign interface function for the routine with the specified NAME. + Also automatically DECLAIM the FTYPE of the defined function. + + NAME may be either a string, a symbol, or a list of the form (string symbol). - Define a foreign interface function for the routine with the specified Name, - which may be either a string, symbol or list of the form (string symbol). - Return-Type is the Alien type for the function return value. VOID may be - used to specify a function with no result. + RETURN-TYPE is the alien type for the function return value. VOID may be + used to specify a function with no result. - The remaining forms specifiy individual arguments that are passed to the - routine. Arg-Name is a symbol that names the argument, primarily for - documentation. Arg-Type is the C-Type of the argument. Style specifies the - say that the argument is passed. + The remaining forms specify individual arguments that are passed to the + routine. ARG-NAME is a symbol that names the argument, primarily for + documentation. ARG-TYPE is the C type of the argument. STYLE specifies the + way that the argument is passed. :IN - An :In argument is simply passed by value. The value to be passed is + An :IN argument is simply passed by value. The value to be passed is obtained from argument(s) to the interface function. No values are returned for :In arguments. This is the default mode. @@ -597,14 +615,15 @@ to arrays, records or functions. :COPY - Similar to :IN, except that the argument values are stored in on - the stack, and a pointer to the object is passed instead of - the values themselves. + This is similar to :IN, except that the argument values are stored + on the stack, and a pointer to the object is passed instead of + the value itself. :IN-OUT - A combination of :OUT and :COPY. A pointer to the argument is passed, - with the object being initialized from the supplied argument and - the return value being determined by accessing the object on return." + This is a combination of :OUT and :COPY. A pointer to the argument is + passed, with the object being initialized from the supplied argument + and the return value being determined by accessing the object on + return." (multiple-value-bind (lisp-name alien-name) (pick-lisp-and-alien-names name) (collect ((docs) (lisp-args) (arg-types) (alien-vars) @@ -618,7 +637,7 @@ (unless (eq style :out) (lisp-args name)) (when (and (member style '(:out :in-out)) - (typep (parse-alien-type type env) + (typep (parse-alien-type type lexenv) 'alien-pointer-type)) (error "can't use :OUT or :IN-OUT on pointer-like type:~% ~S" type)) @@ -633,21 +652,36 @@ (alien-args `(addr ,name)))) (when (or (eq style :out) (eq style :in-out)) (results name))))) - `(defun ,lisp-name ,(lisp-args) - ,@(docs) - (with-alien - ((,lisp-name (function ,result-type ,@(arg-types)) - :extern ,alien-name) - ,@(alien-vars)) - ,(if (alien-values-type-p result-type) - (let ((temps (make-gensym-list - (length - (alien-values-type-values result-type))))) - `(multiple-value-bind ,temps - (alien-funcall ,lisp-name ,@(alien-args)) - (values ,@temps ,@(results)))) - `(values (alien-funcall ,lisp-name ,@(alien-args)) - ,@(results)))))))) + `(progn + + ;; The theory behind this automatic DECLAIM is that (1) if + ;; you're calling C, static typing is what you're doing + ;; anyway, and (2) such a declamation can be (especially for + ;; alien values) both messy to do by hand and very important + ;; for performance of later code which uses the return value. + (declaim (ftype (function ,(mapcar (constantly t) args) + (alien ,result-type)) + ,lisp-name)) + + (defun ,lisp-name ,(lisp-args) + ,@(docs) + (with-alien + ((,lisp-name (function ,result-type ,@(arg-types)) + :extern ,alien-name) + ,@(alien-vars)) + ,(if (alien-values-type-p result-type) + (let ((temps (make-gensym-list + (length + (alien-values-type-values result-type))))) + `(multiple-value-bind ,temps + (alien-funcall ,lisp-name ,@(alien-args)) + (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)) (defun alien-typep (object type) #!+sb-doc