diff options
author | Anthony Green <green@moxielogic.com> | 2011-11-12 17:18:51 -0500 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2011-11-12 17:18:51 -0500 |
commit | ff9454da44859716a5bd4eaa344499288c79694f (patch) | |
tree | d5ad99ea8bc87ff986f91db1401383d89aa49cc8 /src/prep_cif.c | |
parent | ea14ae85e8f54ff046b7fb8a9cfe349475272044 (diff) | |
download | libffi-ff9454da44859716a5bd4eaa344499288c79694f.tar.gz |
Add David Gilbert's variadic function call support
Diffstat (limited to 'src/prep_cif.c')
-rw-r--r-- | src/prep_cif.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/prep_cif.c b/src/prep_cif.c index 8548cfd..0e2e116 100644 --- a/src/prep_cif.c +++ b/src/prep_cif.c @@ -90,20 +90,33 @@ static ffi_status initialize_aggregate(ffi_type *arg) /* Perform machine independent ffi_cif preparation, then call machine dependent routine. */ -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, - ffi_type *rtype, ffi_type **atypes) +/* For non variadic functions isvariadic should be 0 and + nfixedargs==ntotalargs. + + For variadic calls, isvariadic should be 1 and nfixedargs + and ntotalargs set as appropriate. nfixedargs must always be >=1 */ + + +ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, + unsigned int isvariadic, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, ffi_type **atypes) { unsigned bytes = 0; unsigned int i; ffi_type **ptr; FFI_ASSERT(cif != NULL); + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); + FFI_ASSERT(nfixedargs <= ntotalargs); + if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) return FFI_BAD_ABI; cif->abi = abi; cif->arg_types = atypes; - cif->nargs = nargs; + cif->nargs = ntotalargs; cif->rtype = rtype; cif->flags = 0; @@ -159,10 +172,31 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, cif->bytes = bytes; /* Perform machine dependent cif processing */ +#ifdef FFI_TARGET_SPECIFIC_VARIADIC + if (isvariadic) + return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs); +#endif + return ffi_prep_cif_machdep(cif); } #endif /* not __CRIS__ */ +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, + ffi_type *rtype, ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes); +} + +ffi_status ffi_prep_cif_var(ffi_cif *cif, + ffi_abi abi, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, + ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes); +} + #if FFI_CLOSURES ffi_status |