summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--buf.c6
-rw-r--r--buf.h1
-rw-r--r--ffi.c50
3 files changed, 34 insertions, 23 deletions
diff --git a/buf.c b/buf.c
index 88f5f166..5f8f17f8 100644
--- a/buf.c
+++ b/buf.c
@@ -204,12 +204,6 @@ mem_t *buf_get(val buf, val self)
return b->data;
}
-mem_t **buf_addr_of(val buf, val self)
-{
- struct buf *b = buf_handle(buf, self);
- return &b->data;
-}
-
void buf_fill(val buf, mem_t *src, val self)
{
struct buf *b = buf_handle(buf, self);
diff --git a/buf.h b/buf.h
index b65f7037..8102fff8 100644
--- a/buf.h
+++ b/buf.h
@@ -32,7 +32,6 @@ val buf_trim(val buf);
val buf_set_length(val obj, val len, val init_val);
val length_buf(val buf);
mem_t *buf_get(val buf, val self);
-mem_t **buf_addr_of(val buf, val self);
void buf_fill(val buf, mem_t *src, val self);
#if HAVE_I8
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));
}
}