diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-20 14:48:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-20 14:48:28 -0700 |
commit | 66479625440d34dbb43b8e8a5f645dca95f9cc97 (patch) | |
tree | 7bc12b030275e4410711f4016184159d2c97f165 /ffi.c | |
parent | 914368cbdca3a26a0e790bf47acec4a393a481c4 (diff) | |
download | txr-66479625440d34dbb43b8e8a5f645dca95f9cc97.tar.gz txr-66479625440d34dbb43b8e8a5f645dca95f9cc97.tar.bz2 txr-66479625440d34dbb43b8e8a5f645dca95f9cc97.zip |
ffi: overhaul ffi-call API and document it.
* ffi.c (ffi_call_wrap): Take struct args * parameters
rather than a list. Check that number of arguments
matches required number from call desc. No need
to build argument array any more; we just refer to
the one in args. Also, the first two parameters
are reversed for consistency with other functions.
(ffi_init): Update registration of ffi-call to
reflect type change.
* ffi.h (ffi_call_wrap): Declaration updated.
* txr.1: Documented ffi-call.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 24 |
1 files changed, 17 insertions, 7 deletions
@@ -2140,14 +2140,13 @@ val ffi_make_call_desc(val ntotal, val nfixed, val rettype, val argtypes) return obj; } -val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) +val ffi_call_wrap(val fptr, val ffi_call_desc, struct args *args) { val self = lit("ffi-call"); struct txr_ffi_call_desc *tfcd = ffi_call_desc_checked(ffi_call_desc); mem_t *fp = cptr_get(fptr); cnum n = tfcd->ntotal; void **values = convert(void **, alloca(sizeof *values * tfcd->ntotal)); - val args = args_in; val types = tfcd->argtypes; val rtype = tfcd->rettype; struct txr_ffi_type *rtft = ffi_type_struct(rtype); @@ -2159,9 +2158,20 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) struct txr_ffi_type **type = convert(struct txr_ffi_type **, alloca(n * sizeof *type)); + if (args->argc < n) { + args_decl(args_copy, n); + args_copy_zap(args_copy, args); + args = args_copy; + } + + args_normalize(args, n); + + if (args->fill < n || args->list) + uw_throwf(error_s, lit("~a: ~s requires ~s arguments"), + self, ffi_call_desc, num(n), nao); + for (i = 0; i < n; i++) { struct txr_ffi_type *mtft = type[i] = ffi_type_struct(pop(&types)); - arg[i] = pop(&args); values[i] = zalloca(mtft->size); in_pass_needed = in_pass_needed || mtft->in != 0; } @@ -2170,7 +2180,7 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) for (i = 0; i < n; i++) { struct txr_ffi_type *mtft = type[i]; - mtft->put(mtft, arg[i], convert(mem_t *, values[i]), self); + mtft->put(mtft, args->arg[i], convert(mem_t *, values[i]), self); in_pass_needed = in_pass_needed || mtft->in != 0; } @@ -2182,7 +2192,7 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) for (i = 0; i < nreached; i++) { struct txr_ffi_type *mtft = type[i]; if (mtft->release != 0) - mtft->release(mtft, arg[i], convert(mem_t *, values[i])); + mtft->release(mtft, args->arg[i], convert(mem_t *, values[i])); } } } @@ -2197,7 +2207,7 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) for (i = 0; i < n; i++) { struct txr_ffi_type *mtft = type[i]; if (mtft->in != 0) - mtft->in(mtft, 0, convert(mem_t *, values[i]), arg[i], self); + mtft->in(mtft, 0, convert(mem_t *, values[i]), args->arg[i], self); } } @@ -2785,7 +2795,7 @@ void ffi_init(void) ffi_closure_s = intern(lit("ffi-closure"), user_package); reg_fun(intern(lit("ffi-type-compile"), user_package), func_n1(ffi_type_compile)); reg_fun(intern(lit("ffi-make-call-desc"), user_package), func_n4(ffi_make_call_desc)); - reg_fun(intern(lit("ffi-call"), user_package), func_n3(ffi_call_wrap)); + reg_fun(intern(lit("ffi-call"), user_package), func_n2v(ffi_call_wrap)); reg_fun(intern(lit("ffi-make-closure"), user_package), func_n4o(ffi_make_closure, 2)); reg_fun(intern(lit("ffi-typedef"), user_package), func_n2(ffi_typedef)); reg_fun(intern(lit("ffi-size"), user_package), func_n1(ffi_size)); |