diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-24 23:25:29 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-24 23:25:29 -0700 |
commit | bd4f590287953ab904a014764790feccb88becc9 (patch) | |
tree | 7e0e6110c1cdfea078946e66bd4992883c82592f | |
parent | a7ffb3583b2f805521372e511bafdce65318903c (diff) | |
download | txr-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.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -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); } |