diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-04 20:51:44 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-04 20:51:44 -0700 |
commit | 33c229bbbbf75ab8b3f048579eb2b7a63acaae7d (patch) | |
tree | 18aee90ef9ac3054fdcbf6285711532ea4862ad2 /ffi.c | |
parent | e5186dace2ce5c13c2a178b67507a3f917f4ed25 (diff) | |
download | txr-33c229bbbbf75ab8b3f048579eb2b7a63acaae7d.tar.gz txr-33c229bbbbf75ab8b3f048579eb2b7a63acaae7d.tar.bz2 txr-33c229bbbbf75ab8b3f048579eb2b7a63acaae7d.zip |
ffi: bugfix: zarray put accessing last element.
A zarray of length N is requiring the Lisp vector to be
of length N.
* ffi.c (ffi_array_put): Reorder logic in the loop so that
when we are putting out the terminating null element of a
zarray, we do not access the corresponding element of the Lisp
vector. Thus if the zarray is N elements wide, the Lisp
vector need only be at least N-1 elements wide, not N.
(ffi_array_in): Copy the null element of a zarray to the
vector only if the vector object at least N elements.
If the vector is nil so that we have to construct one,
construct a vector of N-1 for a zarray.
(ffi_array_get): For a zarray, construct a vector of N-1
elements. Do not even fetch the null.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -963,11 +963,13 @@ static val ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec, ucnum offs = 0; struct txr_ffi_type *etft = ffi_type_struct(eltype); cnum elsize = etft->size, i; + cnum znelem = if3(tft->null_term && nelem > 0 && + vec && length(vec) < num_fast(nelem), nelem - 1, nelem); if (vec == nil) - vec = vector(num_fast(nelem), nil); + vec = vector(num_fast(znelem), nil); - for (i = 0; i < nelem; i++) { + for (i = 0; i < znelem; i++) { if (etft->in != 0) { val elval = ref(vec, num_fast(i)); refset(vec, num_fast(i), etft->in(etft, src + offs, elval, self)); @@ -993,13 +995,14 @@ static void ffi_array_put(struct txr_ffi_type *tft, val vec, mem_t *dst, ucnum offs = 0; for (i = 0; i < nelem; i++) { - val elval = ref(vec, num_fast(i)); if (nt && i == nelem - 1) { memset(dst + offs, 0, elsize); break; + } else { + val elval = ref(vec, num_fast(i)); + etft->put(etft, elval, dst + offs, self); + offs += elsize; } - etft->put(etft, elval, dst + offs, self); - offs += elsize; } } @@ -1058,12 +1061,13 @@ static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self) } } } else { - val vec = vector(num_fast(nelem), nil); + cnum znelem = if3(tft->null_term && nelem > 0, nelem - 1, nelem); + val vec = vector(num_fast(znelem), nil); struct txr_ffi_type *etft = ffi_type_struct(eltype); cnum elsize = etft->size; cnum offs, i; - for (i = 0, offs = 0; i < nelem; i++) { + for (i = 0, offs = 0; i < znelem; i++) { val elval = etft->get(etft, src + offs, self); refset(vec, num_fast(i), elval); offs += elsize; |