mirror of
https://github.com/janet-lang/janet
synced 2024-12-25 07:50:27 +00:00
Add support for 0-element arrays in FFI.
Allows for flexible array member construct mapping.
This commit is contained in:
parent
0a15a5ee56
commit
eecc388ebd
@ -99,7 +99,7 @@ static const JanetFFIPrimInfo janet_ffi_type_info[] = {
|
|||||||
struct JanetFFIType {
|
struct JanetFFIType {
|
||||||
JanetFFIStruct *st;
|
JanetFFIStruct *st;
|
||||||
JanetFFIPrimType prim;
|
JanetFFIPrimType prim;
|
||||||
size_t array_count;
|
ssize_t array_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -223,12 +223,12 @@ static JanetFFIType prim_type(JanetFFIPrimType pt) {
|
|||||||
JanetFFIType t;
|
JanetFFIType t;
|
||||||
t.prim = pt;
|
t.prim = pt;
|
||||||
t.st = NULL;
|
t.st = NULL;
|
||||||
t.array_count = 0;
|
t.array_count = -1;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t type_size(JanetFFIType t) {
|
static size_t type_size(JanetFFIType t) {
|
||||||
size_t count = t.array_count ? t.array_count : 1;
|
size_t count = t.array_count < 0 ? 1 : (size_t) t.array_count;
|
||||||
if (t.prim == JANET_FFI_TYPE_STRUCT) {
|
if (t.prim == JANET_FFI_TYPE_STRUCT) {
|
||||||
return t.st->size * count;
|
return t.st->size * count;
|
||||||
} else {
|
} else {
|
||||||
@ -294,6 +294,7 @@ static JanetFFIPrimType decode_ffi_prim(const uint8_t *name) {
|
|||||||
if (!janet_cstrcmp(name, "int")) return JANET_FFI_TYPE_INT32;
|
if (!janet_cstrcmp(name, "int")) return JANET_FFI_TYPE_INT32;
|
||||||
if (!janet_cstrcmp(name, "long")) return JANET_FFI_TYPE_INT64;
|
if (!janet_cstrcmp(name, "long")) return JANET_FFI_TYPE_INT64;
|
||||||
if (!janet_cstrcmp(name, "byte")) return JANET_FFI_TYPE_UINT8;
|
if (!janet_cstrcmp(name, "byte")) return JANET_FFI_TYPE_UINT8;
|
||||||
|
if (!janet_cstrcmp(name, "uchar")) return JANET_FFI_TYPE_UINT8;
|
||||||
if (!janet_cstrcmp(name, "ushort")) return JANET_FFI_TYPE_UINT16;
|
if (!janet_cstrcmp(name, "ushort")) return JANET_FFI_TYPE_UINT16;
|
||||||
if (!janet_cstrcmp(name, "uint")) return JANET_FFI_TYPE_UINT32;
|
if (!janet_cstrcmp(name, "uint")) return JANET_FFI_TYPE_UINT32;
|
||||||
if (!janet_cstrcmp(name, "ulong")) return JANET_FFI_TYPE_UINT64;
|
if (!janet_cstrcmp(name, "ulong")) return JANET_FFI_TYPE_UINT64;
|
||||||
@ -374,7 +375,7 @@ static JanetFFIType decode_ffi_type(Janet x) {
|
|||||||
return prim_type(decode_ffi_prim(janet_unwrap_keyword(x)));
|
return prim_type(decode_ffi_prim(janet_unwrap_keyword(x)));
|
||||||
}
|
}
|
||||||
JanetFFIType ret;
|
JanetFFIType ret;
|
||||||
ret.array_count = 0;
|
ret.array_count = -1;
|
||||||
ret.prim = JANET_FFI_TYPE_STRUCT;
|
ret.prim = JANET_FFI_TYPE_STRUCT;
|
||||||
if (janet_checkabstract(x, &janet_struct_type)) {
|
if (janet_checkabstract(x, &janet_struct_type)) {
|
||||||
ret.st = janet_unwrap_abstract(x);
|
ret.st = janet_unwrap_abstract(x);
|
||||||
@ -384,10 +385,9 @@ static JanetFFIType decode_ffi_type(Janet x) {
|
|||||||
const Janet *els;
|
const Janet *els;
|
||||||
if (janet_indexed_view(x, &els, &len)) {
|
if (janet_indexed_view(x, &els, &len)) {
|
||||||
if (janet_checktype(x, JANET_ARRAY)) {
|
if (janet_checktype(x, JANET_ARRAY)) {
|
||||||
if (len != 2) janet_panicf("array type must be of form @[type count], got %v", x);
|
if (len != 2 && len != 1) janet_panicf("array type must be of form @[type count], got %v", x);
|
||||||
int32_t array_count = janet_getnat(els, 1);
|
|
||||||
if (array_count == 0) janet_panic("vla not supported");
|
|
||||||
ret = decode_ffi_type(els[0]);
|
ret = decode_ffi_type(els[0]);
|
||||||
|
int32_t array_count = len == 1 ? 0 : janet_getnat(els, 1);
|
||||||
ret.array_count = array_count;
|
ret.array_count = array_count;
|
||||||
} else {
|
} else {
|
||||||
ret.st = build_struct_type(len, els);
|
ret.st = build_struct_type(len, els);
|
||||||
@ -447,12 +447,12 @@ static void *janet_ffi_getpointer(const Janet *argv, int32_t n) {
|
|||||||
* The alignment and space available is assumed to already be sufficient */
|
* The alignment and space available is assumed to already be sufficient */
|
||||||
static void janet_ffi_write_one(void *to, const Janet *argv, int32_t n, JanetFFIType type, int recur) {
|
static void janet_ffi_write_one(void *to, const Janet *argv, int32_t n, JanetFFIType type, int recur) {
|
||||||
if (recur == 0) janet_panic("recursion too deep");
|
if (recur == 0) janet_panic("recursion too deep");
|
||||||
if (type.array_count) {
|
if (type.array_count >= 0) {
|
||||||
JanetFFIType el_type = type;
|
JanetFFIType el_type = type;
|
||||||
el_type.array_count = 0;
|
el_type.array_count = -1;
|
||||||
size_t el_size = type_size(el_type);
|
size_t el_size = type_size(el_type);
|
||||||
JanetView els = janet_getindexed(argv, n);
|
JanetView els = janet_getindexed(argv, n);
|
||||||
if ((size_t) els.len != type.array_count) {
|
if (els.len != type.array_count) {
|
||||||
janet_panicf("bad array length, expected %d, got %d", type.array_count, els.len);
|
janet_panicf("bad array length, expected %d, got %d", type.array_count, els.len);
|
||||||
}
|
}
|
||||||
char *cursor = to;
|
char *cursor = to;
|
||||||
@ -528,12 +528,12 @@ static void janet_ffi_write_one(void *to, const Janet *argv, int32_t n, JanetFFI
|
|||||||
* size of the data is correct. */
|
* size of the data is correct. */
|
||||||
static Janet janet_ffi_read_one(const uint8_t *from, JanetFFIType type, int recur) {
|
static Janet janet_ffi_read_one(const uint8_t *from, JanetFFIType type, int recur) {
|
||||||
if (recur == 0) janet_panic("recursion too deep");
|
if (recur == 0) janet_panic("recursion too deep");
|
||||||
if (type.array_count) {
|
if (type.array_count >= 0) {
|
||||||
JanetFFIType el_type = type;
|
JanetFFIType el_type = type;
|
||||||
el_type.array_count = 0;
|
el_type.array_count = -1;
|
||||||
size_t el_size = type_size(el_type);
|
size_t el_size = type_size(el_type);
|
||||||
JanetArray *array = janet_array(type.array_count);
|
JanetArray *array = janet_array(type.array_count);
|
||||||
for (size_t i = 0; i < type.array_count; i++) {
|
for (ssize_t i = 0; i < type.array_count; i++) {
|
||||||
janet_array_push(array, janet_ffi_read_one(from, el_type, recur - 1));
|
janet_array_push(array, janet_ffi_read_one(from, el_type, recur - 1));
|
||||||
from += el_size;
|
from += el_size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user