Yaroslav Kavenchuk <kavenchuk(a)jenty.by> writes in cffi-devel:
>> clisp from CVS head, cffi-051229.tar.gz
>> 2 out of 101 total tests failed: CFFI-TESTS::FUNCALL.VARARGS.DOUBLE,
>> CFFI-TESTS::STRUCT.NAMES.
>About the FUNCALL.VARARGS.DOUBLE test, it passes on Linux and OSX but
>fails on Win32.
Yaroslav, I'd be grateful if you could express the testcase in terms of CLISP FFI forms (not CFFI) and submit it to the SF CLISP bugtracker, mentioning varargs in the subject line. So the clisp project would have a bugtracker issue for varargs and a place where to post comments.
The current bugtracker FFI issues (long long, sparc64 etc.) are distinct from the specific varargs issue.
Still, I maintain that attempts to interface to varargs is going to lead to errors here and there. E.g. I found the following comment in ffcall/avcall.h:
:#ifdef rs6000 (applies to MacOS AFAIK)
:float/double can be passed in float registers, but we also push them to the :corresponding int registers in case of varargs.
I.e. ffcall contains special provision to make varargs work with doubles on PowerPC. It's nice to have, but it need not be there on other systems.
And I must retract my recommendation to James to attempt o interface to *v() functions (those that take a va_list*). That's a priori not easier than the other functions. I expect the ffcall package may make this job easier in the future, since basically it itself builds up a similar array internally, so it could just pass a pointer to it to the *v() functions, but that's just a supposition of mine.
So far my opinion remains that general infrastructure for varargs is not present in ffcall (despite particular work-around for e.g. PowerPC above), and that alone can explain the mentioned test results:
+ success on Linux and PowerPC/OSX
- failure on Win32 (cygwin? mingw32? MS-VC?)
IIRC, someody reported Lispworks explicitly mentions varargs not being supported, and Duane Rettig from Franz reported issues in cll etc.
Furthermore, I wonder how a varargs call would look from the Lisp side?
While the C compiler knows the args to printf() and can push either int, pointer or double on the stack, what should Lisp code do?
A) Do a TYPECASE
((integer character) :int-or-long) ; but what about longlong?
(string :string-or-pointer)
(float :double via (coerce x 'double-float))
on each argument, at run-time?
B) Or, for each call, declare a particular usage, e.g. corresponding to sprintf("%d%s%lld%f")
and have the programmer write
(foreign-funcall :int :string :long-long :[double-]float) ?
That's IMHO still no solution with unknwon (at compile-time) format strings or other such arguments.
James Bielman particular problem of interfacing to objc_msgSend[v]() might be solved like this:
a) it's only relevant to one architecture (PowerPC/OSX)
b) it could restrict itself to either :pointer or :long (ignore :double).
Then the the stack layout (and the platform ABI) could be so regular that building the array and calling objc_msgSend() might work across all Lisps.
Regards,
Jörg Höhle.