X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-alieneval.lisp;h=7a6e04195f20e5da8c70d844609d47b537fd68fc;hb=62b6c13eaaefa20b790e10a28d292e1821cd4446;hp=822dd7d0ca1175b4d82efe82ed6f611ffd78640c;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/target-alieneval.lisp b/src/code/target-alieneval.lisp index 822dd7d..7a6e041 100644 --- a/src/code/target-alieneval.lisp +++ b/src/code/target-alieneval.lisp @@ -587,6 +587,37 @@ (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) @@ -792,18 +823,19 @@ 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)))) (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 +869,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 +885,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))))