diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-07 09:09:03 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-07 09:09:03 -0700 |
commit | feea17487b17ca381b6d740ac50a76248f1d033c (patch) | |
tree | 03deaf4a659c7459c2600d3b916baa867c1ee4bc | |
parent | b6b83892c085740529d0c38e9cf45ee1df42f97c (diff) | |
download | txr-feea17487b17ca381b6d740ac50a76248f1d033c.tar.gz txr-feea17487b17ca381b6d740ac50a76248f1d033c.tar.bz2 txr-feea17487b17ca381b6d740ac50a76248f1d033c.zip |
ffi: bugfix: all in calls must fall back on get.
* ffi.c (ffi_ptr_out_in, ffi_ptr_out_s_in): If the target type
has no in handler, fall back on its get. Here, it is without
regard for the copy flag, because a zero value of that flag
just indicates that the ptr-out itself is passed by-value.
The target object is never by value
(ffi_in): Add copy flag parameter, so the full interface
is exposed, like in ffi_out. Fall back on get, if there is
no in and the copy flag is true. Just return the original
object if the type has no in, and copy is false.
(ffi_init): Registration of ffi-in adjusted to four
parameters.
* ffi.h (ffi_in): Declaration updated.
-rw-r--r-- | ffi.c | 14 | ||||
-rw-r--r-- | ffi.h | 2 |
2 files changed, 12 insertions, 4 deletions
@@ -760,6 +760,8 @@ static val ffi_ptr_out_in(struct txr_ffi_type *tft, int copy, mem_t *src, mem_t **loc = coerce(mem_t **, src); if (tgtft->in != 0) obj = tgtft->in(tgtft, 1, *loc, obj, self); + else + obj = tgtft->get(tgtft, *loc, self); tgtft->free(*loc); *loc = 0; return obj; @@ -836,6 +838,8 @@ static val ffi_ptr_out_s_in(struct txr_ffi_type *tft, int copy, mem_t **loc = coerce(mem_t **, src); if (tgtft->in != 0) obj = tgtft->in(tgtft, 1, *loc, obj, self); + else + obj = tgtft->get(tgtft, *loc, self); return obj; } @@ -1925,7 +1929,7 @@ val ffi_put(val obj, val type) return buf; } -val ffi_in(val srcbuf, val obj, val type) +val ffi_in(val srcbuf, val obj, val type, val copy_p) { val self = lit("ffi-in"); struct txr_ffi_type *tft = ffi_type_struct_checked(type); @@ -1933,7 +1937,11 @@ val ffi_in(val srcbuf, val obj, val type) if (lt(length_buf(srcbuf), num_fast(tft->size))) uw_throwf(lit("~a: buffer ~s is too small for type ~s"), self, srcbuf, type, nao); - return tft->in(tft, 1, src, obj, self); + if (tft->in != 0) + return tft->in(tft, copy_p != nil, src, obj, self); + else if (copy_p) + return tft->get(tft, src, self); + return obj; } val ffi_get(val srcbuf, val type) @@ -2014,7 +2022,7 @@ void ffi_init(void) reg_fun(intern(lit("ffi-size"), user_package), func_n1(ffi_size)); reg_fun(intern(lit("ffi-put-into"), user_package), func_n3(ffi_put_into)); reg_fun(intern(lit("ffi-put"), user_package), func_n2(ffi_put)); - reg_fun(intern(lit("ffi-in"), user_package), func_n3(ffi_in)); + reg_fun(intern(lit("ffi-in"), user_package), func_n4(ffi_in)); reg_fun(intern(lit("ffi-get"), user_package), func_n2(ffi_get)); reg_fun(intern(lit("ffi-out"), user_package), func_n4(ffi_out)); reg_varl(intern(lit("cptr-null"), user_package), cptr(0)); @@ -60,7 +60,7 @@ val ffi_typedef(val name, val type); val ffi_size(val type); val ffi_put_into(val dstbuf, val obj, val type); val ffi_put(val obj, val type); -val ffi_in(val srcbuf, val obj, val type); +val ffi_in(val srcbuf, val obj, val type, val copy_p); val ffi_get(val srcbuf, val type); val ffi_out(val dstbuf, val obj, val type, val copy_p); void ffi_init(void); |