c2ffi handling va_list

Martin Simmons martin at lispworks.com
Thu Jul 16 10:39:20 UTC 2020


>>>>> On Thu, 16 Jul 2020 11:42:17 +0530 (IST), Madhu  said:
> 
> *  Luís Oliveira <luismbo at gmail.com> <CAB-HnLQJE9Y0+kyq3-COjCk-GD3mzOOE+h2f+7upkdkCGu9+Ww at mail.gmail.com>
> Wrote on Wed, 15 Jul 2020 14:50:27 +0100
> 
> > On Wed, 15 Jul 2020 at 06:16, Madhu <enometh at meer.net> wrote:
> >> one of the cffi/TODO items has
> >> -> Handle va_list. For now it's treated as any other argument.
> >>
> >> Maybe someone has thought deeply about how to do this?  Please let me
> >> know if you have any suggestions.
> >>
> >> [It seems borodust/claw tries to handle this by converting va_list
> >> args to variadic lisp arguments - but it still seems to blow up at a
> >> cffi:parse-type.  Or maybe it is a defect with my Clang-7.0 stdarg
> >> vs. what is included with gcc]
> > The TODO item should probably be removed. DEFCFUN has syntax for
> > varargs and that's implemented on top of FOREIGN-FUNCALL-VARARGS and
> > FOREIGN-FUNCALL-VARARGS-POINTER. The implementation so far is simple,
> > it only takes care of promoting floats to doubles, and chars/short to
> > ints. The test suite tracks whether this works and it seems to work so
> > far.
> 
> The TODO entry was about specifically va_list.  Now I'm not sure how
> the "new" stdargs API can be manipulated through CFFI - AFAIK it is
> purely a C compiler thing - you cannot foreign funcall to va_start and
> va_copy.  The only way I could use it is through lisp implementations
> that support a form of c-inline, or through "grovelled" code which
> would be loaded through a shared library.
> 
> > Not sure about what c2ffi needs to do, though.
> 
> In order to "treat va_list as any other argument" I tried adding an
> opaque (cffi:defcstruct (:builtin-va-list :size 192)) -- 192 being
> sizeof(va_list) with x86_64-pc-linux-gnu-gcc -- having
> %json-type-to-cffi-type return that when it comes across a cffi tag
> "__builtin_va_list". cffi/c2ffi can generate defcfns for functions
> which use va_list in the signature.  I think the user would still be
> hardpressed to find a way to use them.
> 
> Unless I'm missing something... ??

I think this defcstruct is wrong on x86_64-pc-linux-gnu-gcc for two reasons:

1. sizeof(va_list) is 24 bytes for me.

2. It is an array, not a struct, so it is passed as a pointer.

I.e.

int bar(va_list z)
{
  return sizeof(z);
}

will return the same as sizeof(void *).

__Martin



More information about the cffi-devel mailing list