summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-07 15:12:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-07 15:12:35 -0700
commit43275967b547f72dcb2f41c698c64575e1374214 (patch)
tree48eb04a086e78c2c93c8a6ef07790ed6bf88eeda /ffi.c
parent8a7aaea1c65efa10b23a70513b33707e208ca944 (diff)
downloadtxr-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.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/ffi.c b/ffi.c
index 89c8d5f8..d194a9bf 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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));
}
}