diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-03 21:15:12 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-03 21:15:12 -0700 |
commit | 80c4f6545a7b0a8ee7519f35756396be48f1bfa9 (patch) | |
tree | 4288d8b63e2b4a4323acbf420b2660d2bc71a39f /ffi.c | |
parent | e9c5c1a6108242c4585ada4ecf0235b2c796887a (diff) | |
download | txr-80c4f6545a7b0a8ee7519f35756396be48f1bfa9.tar.gz txr-80c4f6545a7b0a8ee7519f35756396be48f1bfa9.tar.bz2 txr-80c4f6545a7b0a8ee7519f35756396be48f1bfa9.zip |
ffi: new ptr-out-s type.
One more ptr type is useful. This type is for objects returned via
pointers embedded in arrays or structures, whereby the callee
establishes both the pointer and the data.
This is similar to ptr-out-d; the difference is that the
data has an indefinite lifetime ("s" denotes "static")
and so the pointer is not freed after the call takes place
and the data is extracted into Lisp objects.
* ffi.c (ptr_out_s_s): New symbol variable.
(ffi_ptr_out_s_in): New function.
(ffi_type_compile): Handle new ptr_out_s_s.
(ffi_init): Initialize ptr_out_s.
* ffi.h (ptr_out_s_s): Declared.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 22 |
1 files changed, 21 insertions, 1 deletions
@@ -77,7 +77,7 @@ val str_d_s, wstr_s, wstr_d_s; val buf_d_s; -val ptr_in_s, ptr_out_s, ptr_in_d_s, ptr_out_d_s, ptr_s; +val ptr_in_s, ptr_out_s, ptr_in_d_s, ptr_out_d_s, ptr_out_s_s, ptr_s; val closure_s; @@ -786,6 +786,18 @@ static void ffi_ptr_out_null_put(struct txr_ffi_type *tft, val s, mem_t *dst, *coerce(mem_t **, dst) = 0; } +static val ffi_ptr_out_s_in(struct txr_ffi_type *tft, mem_t *src, val obj, + val self) +{ + val tgttype = tft->mtypes; + struct txr_ffi_type *tgtft = ffi_type_struct(tgttype); + mem_t **loc = coerce(mem_t **, src); + if (tgtft->in != 0) + obj = tgtft->in(tgtft, *loc, obj, self); + return obj; +} + + static val ffi_struct_in(struct txr_ffi_type *tft, mem_t *src, val strct, val self) { @@ -1298,6 +1310,13 @@ val ffi_type_compile(val syntax) ffi_ptr_in_put, ffi_ptr_get, ffi_ptr_out_in, ffi_ptr_out_out, target_type); + } else if (sym == ptr_out_s_s) { + 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_null_put, ffi_ptr_get, + ffi_ptr_out_s_in, ffi_ptr_out_out, + target_type); } else if (sym == buf_s || sym == buf_d_s) { cnum nelem = c_num(cadr(syntax)); val type = make_ffi_type_builtin(syntax, cptr_s, sizeof (mem_t *), @@ -1792,6 +1811,7 @@ void ffi_init(void) ptr_out_s = intern(lit("ptr-out"), user_package); ptr_in_d_s = intern(lit("ptr-in-d"), user_package); ptr_out_d_s = intern(lit("ptr-out-d"), user_package); + ptr_out_s_s = intern(lit("ptr-out-s"), user_package); ptr_s = intern(lit("ptr"), user_package); closure_s = intern(lit("closure"), user_package); ffi_type_s = intern(lit("ffi-type"), user_package); |