summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-20 14:48:28 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-20 14:48:28 -0700
commit66479625440d34dbb43b8e8a5f645dca95f9cc97 (patch)
tree7bc12b030275e4410711f4016184159d2c97f165 /ffi.c
parent914368cbdca3a26a0e790bf47acec4a393a481c4 (diff)
downloadtxr-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.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/ffi.c b/ffi.c
index 31666020..226e1063 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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));