summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-03 20:58:12 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-03 20:58:12 -0700
commite9c5c1a6108242c4585ada4ecf0235b2c796887a (patch)
treec11d1234f223b923abcc832478aafcd4f7385bbc
parent26dd7d045823e42fdcadd6c81e1f82f2ba48323d (diff)
downloadtxr-e9c5c1a6108242c4585ada4ecf0235b2c796887a.tar.gz
txr-e9c5c1a6108242c4585ada4ecf0235b2c796887a.tar.bz2
txr-e9c5c1a6108242c4585ada4ecf0235b2c796887a.zip
ffi: fix semantics of ptr-out-d.
Since the callee allocates the buffer for a ptr-out-d, the FFI mechanism should not also be allocating a buffer to receive the object. The buffer pointer will just be overwritten by the callee with its own dynamic pointer. We should pass a null pointer which the callee fills in (making a ptr-out-d not suitable as a by-value parameter). Initially, ptr-out-d was envisioned for return values only and for use in callbacks, which is why I neglected this aspect. * ffi.c (ffi_ptr_out_null_put): New static function. (ffi_type_compile): Use ffi_ptr_out_null_put for the ffi_ptr_out_d case, so caller places a null pointer, then frees the pointer that the callee places there.
-rw-r--r--ffi.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/ffi.c b/ffi.c
index 29d943be..8664ea64 100644
--- a/ffi.c
+++ b/ffi.c
@@ -780,6 +780,12 @@ static void ffi_ptr_in_put(struct txr_ffi_type *tft, val s, mem_t *dst,
}
}
+static void ffi_ptr_out_null_put(struct txr_ffi_type *tft, val s, mem_t *dst,
+ val self)
+{
+ *coerce(mem_t **, dst) = 0;
+}
+
static val ffi_struct_in(struct txr_ffi_type *tft, mem_t *src, val strct,
val self)
{
@@ -1282,7 +1288,7 @@ val ffi_type_compile(val syntax)
val target_type = ffi_type_compile(cadr(syntax));
return make_ffi_type_pointer(syntax, cptr_s, sizeof (mem_t *),
&ffi_type_pointer,
- ffi_ptr_out_put, ffi_ptr_d_get,
+ ffi_ptr_out_null_put, ffi_ptr_d_get,
ffi_ptr_out_in, ffi_ptr_out_out,
target_type);
} else if (sym == ptr_s) {