diff options
-rw-r--r-- | ffi.c | 43 | ||||
-rw-r--r-- | tests/017/flexstruct.tl | 64 |
2 files changed, 97 insertions, 10 deletions
@@ -2446,17 +2446,33 @@ static void ffi_ptr_in_release(struct txr_ffi_type *tft, val obj, 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 = get_special_slot(strct, length_m); - + struct txr_ffi_type *lmtft = lastm->mtft; (void) self; - if (length_meth) { - val len = funcall1(length_meth, strct); - val memb = slot(strct, lastm->mname); - if (vectorp(memb)) - return vec_set_length(memb, len); - else - return slotset(strct, lastm->mname, vector(len, nil)); + if (lmtft->kind == FFI_KIND_ARRAY && !lmtft->null_term) { + val length_meth = get_special_slot(strct, length_m); + + if (length_meth) { + val len = funcall1(length_meth, strct); + + switch (lmtft->ch_conv) { + case conv_char: + case conv_zchar: + case conv_wchar: + case conv_bchar: + slotset(strct, lastm->mname, len); + break; + case conv_none: + { + val memb = slot(strct, lastm->mname); + if (memb) + return vec_set_length(memb, len); + else + return slotset(strct, lastm->mname, vector(len, nil)); + } + break; + } + } } return slot(strct, lastm->mname); @@ -2978,7 +2994,14 @@ static val ffi_varray_in(struct txr_ffi_type *tft, int copy, mem_t *src, { if (copy) { struct txr_ffi_type *etft = ffi_type_struct(tft->eltype); - cnum nelem = if3(vec, ffi_varray_dynsize(tft, vec, self) / etft->size, 0); + cnum nelem = 0; + + if (vectorp(vec)) { + nelem = ffi_varray_dynsize(tft, vec, self) / etft->size; + } else if (numberp(vec)) { + nelem = c_num(vec, self); + vec = nil; + } switch (tft->ch_conv) { case conv_char: diff --git a/tests/017/flexstruct.tl b/tests/017/flexstruct.tl new file mode 100644 index 00000000..c8feedef --- /dev/null +++ b/tests/017/flexstruct.tl @@ -0,0 +1,64 @@ +(load "../common") + +(typedef fs0 (struct fs0 + (a uint8) + (b (array char)))) + +(mtest + (sizeof fs0) 1 + (ffi-put #S(fs0 a 3 b "ABC") (ffi fs0)) #b'03414243' + (ffi-get #b'03414243' (ffi fs0)) #S(fs0 a 3 b "")) + +(defmeth fs0 length (s) + s.a) + +(mtest + (ffi-get #b'03414243' (ffi fs0)) #S(fs0 a 3 b "ABC") + (ffi-get #b'02e6bca2e5ad97' (ffi fs0)) #S(fs0 a 2 b "\xDCE6\xDCBC") + (ffi-get #b'06e6bca2e5ad97' (ffi fs0)) #S(fs0 a 6 b "漢字")) + +(typedef fs1 (struct fs1 + (a uint8) + (b (zarray char)))) + +(mtest + (sizeof fs1) 1 + (ffi-put #S(fs1 a 3 b "ABCDEF") (ffi fs1)) #b'0341424344454600' + (ffi-get #b'FF41424300' (ffi fs1)) #S(fs1 a 255 b "ABC")) + +(mtest + (ffi-get #b'0341424300' (ffi fs1)) #S(fs1 a 3 b "ABC") + (ffi-get #b'02e6bc00' (ffi fs1)) #S(fs1 a 2 b "\xDCE6\xDCBC") + (ffi-get #b'06e6bca2e5ad9700' (ffi fs1)) #S(fs1 a 6 b "漢字")) + +(typedef fs2 (struct fs2 + (a int8) + (b (array int8)))) + +(mtest + (sizeof fs2) 1 + (ffi-put #S(fs2 a 3 b "ABCD") (ffi fs2)) #b'0341424344' + (ffi-put #S(fs2 a 3 b #(65 66 67 68)) (ffi fs2)) #b'0341424344' + (ffi-get #b'FF414243' (ffi fs2)) #S(fs2 a 255 b #())) + +(defmeth fs2 length (s) + s.a) + +(mtest + (ffi-get #b'03010203' (ffi fs2)) #S(fs2 a 3 b #(1 2 3))) + +(typedef fs3 (struct fs3 + (a int8) + (b (array le-int16)))) + +(mtest + (sizeof fs3) 2 + (ffi-put #S(fs3 a 3 b "ABCD") (ffi fs3)) #b'03004100420043004400' + (ffi-put #S(fs3 a 3 b #(65 66 67 68)) (ffi fs3)) #b'03004100420043004400' + (ffi-get #b'FF414243' (ffi fs3)) #S(fs3 a 255 b #())) + +(defmeth fs3 length (s) + s.a) + +(mtest + (ffi-get #b'0300010002000300' (ffi fs3)) #S(fs3 a 3 b #(1 2 3))) |