From 6947651d397d96dc14114e236468d182f003467b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 10 May 2017 06:49:21 -0700 Subject: ffi: do arg in semantics /after/ getting return val. What this allows is for situations when a foreign function returns the pointer that it has been passed. If that pointer is temporary storage allocated by FFI, then it is no longer valid after performing the in pass on the args. Therefore, we should decode the return value first, while the returned pointer is valid. * ffi.c (ffi_call_wrap): Move the return value get before the argument post-processing in pass. --- ffi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ffi.c b/ffi.c index 8c99f3d9..7734d1dd 100644 --- a/ffi.c +++ b/ffi.c @@ -1822,6 +1822,7 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) struct txr_ffi_type *rtft = ffi_type_struct(rtype); void *rc = alloca(rtft->size); int in_pass_needed = 0; + val ret; for (i = 0; i < n; i++) { val type = pop(&types); @@ -1834,6 +1835,8 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) ffi_call(&tfcd->cif, coerce(void (*)(void), fp), rc, values); + ret = rtft->get(rtft, convert(mem_t *, rc), self); + if (in_pass_needed) { types = tfcd->argtypes; args = args_in; @@ -1846,7 +1849,7 @@ val ffi_call_wrap(val ffi_call_desc, val fptr, val args_in) } } - return rtft->get(rtft, convert(mem_t *, rc), self); + return ret; } static void ffi_closure_dispatch(ffi_cif *cif, void *cret, -- cgit v1.2.3