diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-03 20:58:12 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-03 20:58:12 -0700 |
commit | e9c5c1a6108242c4585ada4ecf0235b2c796887a (patch) | |
tree | c11d1234f223b923abcc832478aafcd4f7385bbc | |
parent | 26dd7d045823e42fdcadd6c81e1f82f2ba48323d (diff) | |
download | txr-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.c | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -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) { |