summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-24 23:25:29 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-24 23:25:29 -0700
commitbd4f590287953ab904a014764790feccb88becc9 (patch)
tree7e0e6110c1cdfea078946e66bd4992883c82592f
parenta7ffb3583b2f805521372e511bafdce65318903c (diff)
downloadtxr-bd4f590287953ab904a014764790feccb88becc9.tar.gz
txr-bd4f590287953ab904a014764790feccb88becc9.tar.bz2
txr-bd4f590287953ab904a014764790feccb88becc9.zip
ffi: fix incorrect cptr type tag implementation.
We can't use the eltype field of the type structure to store the cptr tag symbol, because that is expected to be a type object and not a symbol. * ffi.c (struct txr_ffi_type): New member, tag. (ffi_cptr_put, ffi_cptr_get, ffi_cptr_alloc): Refer to tag rather than eltype. (ffi_type_compile): Handle the compound cptr type using the same code as the simple one in ffi_init_types: use make_ffi_type_builtin rather than make_ffi_type_pointer. Install the tag into the tag field. Also set up the forgotten alloc and free routines. (ffi_init_types): For cptr, explicitly initialize the tag to nil. This is not necessary since the structure is calloced, and we rely on that for nil all over the place, but here it serves as a reminder that cptr has a tag.
-rw-r--r--ffi.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/ffi.c b/ffi.c
index def21a38..0600f83b 100644
--- a/ffi.c
+++ b/ffi.c
@@ -168,6 +168,7 @@ struct txr_ffi_type {
unsigned shift, mask;
cnum nelem;
struct smemb *memb;
+ val tag;
val sym_num, num_sym;
unsigned null_term : 1;
unsigned by_value_in : 1;
@@ -1755,19 +1756,19 @@ static val ffi_le_u32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_cptr_put(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- mem_t *p = cptr_handle(n, tft->eltype, self);
+ mem_t *p = cptr_handle(n, tft->tag, self);
*coerce(mem_t **, dst) = p;
}
static val ffi_cptr_get(struct txr_ffi_type *tft, mem_t *src, val self)
{
mem_t *p = *coerce(mem_t **, src);
- return cptr_typed(p, tft->eltype, 0);
+ return cptr_typed(p, tft->tag, 0);
}
static mem_t *ffi_cptr_alloc(struct txr_ffi_type *tft, val ptr, val self)
{
- return coerce(mem_t *, cptr_addr_of(ptr, tft->eltype, self));
+ return coerce(mem_t *, cptr_addr_of(ptr, tft->tag, self));
}
static val ffi_str_in(struct txr_ffi_type *tft, int copy,
@@ -3362,9 +3363,15 @@ val ffi_type_compile(val syntax)
return type;
} else if (sym == cptr_s) {
val tag = cadr(syntax);
- return make_ffi_type_pointer(syntax, cptr_s,
- ffi_cptr_put, ffi_cptr_get,
- 0, 0, 0, tag);
+ val type = make_ffi_type_builtin(cptr_s, cptr_s, sizeof (mem_t *),
+ alignof (mem_t *),
+ &ffi_type_pointer,
+ ffi_cptr_put, ffi_cptr_get, 0, 0);
+ struct txr_ffi_type *tft = ffi_type_struct(type);
+ tft->alloc = ffi_cptr_alloc;
+ tft->free = ffi_noop_free;
+ tft->tag = tag;
+ return type;
} else if (sym == carray_s) {
val eltype = ffi_type_compile(cadr(syntax));
return make_ffi_type_pointer(syntax, carray_s,
@@ -3730,6 +3737,7 @@ static void ffi_init_types(void)
struct txr_ffi_type *tft = ffi_type_struct(type);
tft->alloc = ffi_cptr_alloc;
tft->free = ffi_noop_free;
+ tft->tag = nil;
ffi_typedef(cptr_s, type);
}