On Tue, 2014-01-28 at 16:11 +0100, Stelian Ionescu wrote:
On Tue, 2014-01-28 at 15:33 +0100, Felix Filozov wrote:
Hi Luís, I am hoping to resurrect this thread. Did you by any chance take a look at the pull request I made a few months ago relating to this feature?
I strongly object to anything that slows down the common call path, which is the case here because capture-errno is always called when not using libffi.
In addition, IMO this is a hairy-enough case that we should ask the implementors to add this feature and not do it ourselves.
As for the interface, the simplest thing might be to add it as last value - not second because custom foreign types can return multiple values, e.g. string+ptr - but that will turn out to be slow because I don't think our current type system knows about arity of custom types and marshalling unknown numbers of multiple values will cons.
For example
(cffi:defcfun foo :string+ptr (a :int))
on SBCL expands to
(DEFUN FOO (A) (LET ((#:G1087 A)) (CFFI:TRANSLATE-FROM-FOREIGN (CFFI-SYS:%FOREIGN-FUNCALL "foo" (:INT #:G1087 :POINTER) :CONVENTION :CDECL :LIBRARY :DEFAULT) #<CFFI::FOREIGN-STRING+PTR-TYPE :UTF-8>)))
Since translate-from-foreign is in a tail position we currently don't care about the number of values it returns, but with errno and knowledge of multiple values we must make it expand to this:
(defun foo (a) (let ((#:g1087 a)) (multiple-value-bind (ret errno) (cffi-sys:%foreign-funcall "foo" (:int #:g1087 :pointer) :convention :cdecl :library :default) (multiple-value-bind (val0 val1) (cffi:translate-from-foreign ptr #<cffi::foreign-string+ptr-type :utf-8>))) (values val0 val1 errno)))