diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-07 15:12:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-07 15:12:35 -0700 |
commit | 43275967b547f72dcb2f41c698c64575e1374214 (patch) | |
tree | 48eb04a086e78c2c93c8a6ef07790ed6bf88eeda /ffi.c | |
parent | 8a7aaea1c65efa10b23a70513b33707e208ca944 (diff) | |
download | txr-43275967b547f72dcb2f41c698c64575e1374214.tar.gz txr-43275967b547f72dcb2f41c698c64575e1374214.tar.bz2 txr-43275967b547f72dcb2f41c698c64575e1374214.zip |
ffi: rethink passing and alloc scheme for bufs.
Backing out of the scheme of (ptr buf) passing the
address of the internal pointer within buf objects.
Also giving buf in handlers, to prevent the fallback
on get.
* buf.c (buf_addr_of): Function removed.
* buf.h (buf_addr_of): Declaration removed.
* ffi.c (ffi_buf_in, ffi_buf_d_in): New functions.
(ffi_buf_alloc): Function removed.
(ffi_type_compile, ffi_init_types): Remove specialty alloc and
free functions from buffers, so the regular fixed allocator is
used. Give buffers the new in functions.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 50 |
1 files changed, 34 insertions, 16 deletions
@@ -672,6 +672,18 @@ static val ffi_bstr_d_get(struct txr_ffi_type *tft, mem_t *src, val self) return ret; } +static val ffi_buf_in(struct txr_ffi_type *tft, int copy, mem_t *src, + val obj, val self) +{ + mem_t **loc = coerce(mem_t **, src); + mem_t *origptr = buf_get(obj, self); + + if (copy && *loc != origptr) + obj = make_duplicate_buf(length_buf(obj), *loc); + + return obj; +} + static void ffi_buf_put(struct txr_ffi_type *tft, val buf, mem_t *dst, val self) { @@ -689,6 +701,22 @@ static val ffi_buf_get(struct txr_ffi_type *tft, mem_t *src, val self) return p ? make_duplicate_buf(num(tft->nelem), p) : nil; } +static val ffi_buf_d_in(struct txr_ffi_type *tft, int copy, mem_t *src, + val obj, val self) +{ + mem_t **loc = coerce(mem_t **, src); + mem_t *origptr = buf_get(obj, self); + + if (*loc != origptr) { + if (copy) + obj = make_borrowed_buf(length_buf(obj), *loc); + else + free(*loc); + } + + return obj; +} + static void ffi_buf_d_put(struct txr_ffi_type *tft, val buf, mem_t *dst, val self) { @@ -706,11 +734,6 @@ static val ffi_buf_d_get(struct txr_ffi_type *tft, mem_t *src, val self) return p ? make_borrowed_buf(num(tft->nelem), p) : nil; } -static mem_t *ffi_buf_alloc(struct txr_ffi_type *tft, val buf, val self) -{ - return coerce(mem_t *, buf_addr_of(buf, self)); -} - static void ffi_closure_put(struct txr_ffi_type *tft, val ptr, mem_t *dst, val self) { @@ -1447,8 +1470,7 @@ val ffi_type_compile(val syntax) uw_throwf(error_s, lit("~a: negative size in ~s"), self, syntax, nao); - tft->alloc = ffi_buf_alloc; - tft->free = ffi_noop_free; + tft->in = if3(sym == buf_s, ffi_buf_in, ffi_buf_d_in); tft->nelem = nelem; return type; } @@ -1589,15 +1611,11 @@ static void ffi_init_types(void) for (iter = list(buf_s, buf_d_s, nao); iter; iter = cdr(iter)) { val sym = car(iter); - val type = make_ffi_type_builtin(sym, buf_s, sizeof (mem_t *), - &ffi_type_pointer, - if3(sym == buf_s, - ffi_buf_put, ffi_buf_d_put), - ffi_void_get); - struct txr_ffi_type *tft = ffi_type_struct(type); - tft->alloc = ffi_buf_alloc; - tft->free = ffi_noop_free; - ffi_typedef(sym, type); + ffi_typedef(sym, make_ffi_type_builtin(sym, buf_s, sizeof (mem_t *), + &ffi_type_pointer, + if3(sym == buf_s, + ffi_buf_put, ffi_buf_d_put), + ffi_void_get)); } } |