diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-22 06:56:03 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-22 06:56:03 -0700 |
commit | 4c1341f2d2be88f36e5799aac9275c88233e1abe (patch) | |
tree | c63ef068a2e182d54c18b40feda209b589ce841b /ffi.c | |
parent | 54adf777ed9e1ce358848b4477a69dd59b5f0753 (diff) | |
download | txr-4c1341f2d2be88f36e5799aac9275c88233e1abe.tar.gz txr-4c1341f2d2be88f36e5799aac9275c88233e1abe.tar.bz2 txr-4c1341f2d2be88f36e5799aac9275c88233e1abe.zip |
ffi: bugfix: flexible struct get not working right.
The get operation must use the flexible array's in virtual
function, because incomplete arrays have a no-op get function.
* ffi.c (ffi_flex_struct_in): return the value of the slot.
(ffi_struct_get): When processing the terminating slot of a
flexible struct, we invoke its in-semantics, using the updated
slot value as the object.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 20 |
1 files changed, 13 insertions, 7 deletions
@@ -2027,7 +2027,7 @@ static void ffi_ptr_in_release(struct txr_ffi_type *tft, val obj, mem_t *dst) *loc = 0; } -static void ffi_flex_struct_in(struct txr_ffi_type *tft, val strct, val self) +static val ffi_flex_struct_in(struct txr_ffi_type *tft, val strct, val self) { struct smemb *lastm = &tft->memb[tft->nelem - 1]; val length_meth = maybe_slot(strct, length_s); @@ -2036,10 +2036,12 @@ static void ffi_flex_struct_in(struct txr_ffi_type *tft, val strct, val self) val len = funcall1(length_meth, strct); val memb = slot(strct, lastm->mname); if (vectorp(memb)) - vec_set_length(memb, len); + return vec_set_length(memb, len); else - slotset(strct, lastm->mname, vector(len, nil)); + return slotset(strct, lastm->mname, vector(len, nil)); } + + return slot(strct, lastm->mname); } static val ffi_struct_in(struct txr_ffi_type *tft, int copy, mem_t *src, @@ -2129,10 +2131,14 @@ static val ffi_struct_get(struct txr_ffi_type *tft, mem_t *src, val self) struct txr_ffi_type *mtft = memb[i].mtft; ucnum offs = memb[i].offs; if (slsym) { - if (flexp && i == nmemb - 1) - ffi_flex_struct_in(tft, strct, self); - val slval = mtft->get(mtft, src + offs, self); - slotset(strct, slsym, slval); + if (flexp && i == nmemb - 1) { + val slval = ffi_flex_struct_in(tft, strct, self); + if (mtft->in != 0) + slotset(strct, slsym, mtft->in(mtft, 1, src + offs, slval, self)); + } else { + val slval = mtft->get(mtft, src + offs, self); + slotset(strct, slsym, slval); + } } } |