(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)
(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))))
(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)))
(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))))
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)