summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-02 20:48:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-02 20:48:10 -0700
commit5f8e2b6572241951c5b264707a05af76e3e9cda9 (patch)
tree51ddb2621fad79a07fddee6340f63d90e16a9aae /ffi.c
parentf1d1bd225fc3fe149dfae02533605e0f78b5e882 (diff)
downloadtxr-5f8e2b6572241951c5b264707a05af76e3e9cda9.tar.gz
txr-5f8e2b6572241951c5b264707a05af76e3e9cda9.tar.bz2
txr-5f8e2b6572241951c5b264707a05af76e3e9cda9.zip
ffi: use single type node in arrays.
Since we don't have the rtidx members in the txr_ffi_type structure, there is no need to instantiate a type for each element of an array. All elements can now share the one type. * ffi.c (ffi_array_in, ffi_array_put, ffi_array_out, ffi_array_get, make_ffi_type_array): Refactor according to tft->mtypes no longer being a list but a single type. (ffi_type_compile): Do not recompile the syntax n times for each element.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/ffi.c b/ffi.c
index b75cbacb..fe18b23f 100644
--- a/ffi.c
+++ b/ffi.c
@@ -902,12 +902,13 @@ static val ffi_struct_get(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec,
val self)
{
- val eltypes = tft->mtypes;
+ val eltype = tft->mtypes;
+ cnum nelem = tft->nelem;
if (tft->char_conv) {
val str;
- if (!eltypes) {
+ if (nelem == 0) {
str = null_string;
} else {
const char *chptr = coerce(const char *, src);
@@ -922,7 +923,7 @@ static void ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec,
} else if (tft->wchar_conv) {
val str;
- if (!eltypes) {
+ if (nelem == 0) {
str = null_string;
} else {
cnum nchar = tft->size / sizeof (wchar_t);
@@ -937,24 +938,20 @@ static void ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec,
}
replace(vec, str, zero, t);
} else {
- if (eltypes) {
- cnum nelem = tft->nelem, i;
- ucnum offs = 0;
-
- for (i = 0; i < nelem; i++) {
- val eltype = pop(&eltypes);
- struct txr_ffi_type *etft = ffi_type_struct(eltype);
- cnum elsize = etft->size;
-
- if (etft->in != 0) {
- val elval = ref(vec, num_fast(i));
- etft->in(etft, src + offs, elval, self);
- } else {
- val elval = etft->get(etft, src + offs, self);
- refset(vec, num_fast(i), elval);
- }
- offs += elsize;
+ ucnum offs = 0;
+ struct txr_ffi_type *etft = ffi_type_struct(eltype);
+ cnum elsize = etft->size, i;
+
+ for (i = 0; i < nelem; i++) {
+
+ if (etft->in != 0) {
+ val elval = ref(vec, num_fast(i));
+ etft->in(etft, src + offs, elval, self);
+ } else {
+ val elval = etft->get(etft, src + offs, self);
+ refset(vec, num_fast(i), elval);
}
+ offs += elsize;
}
}
}
@@ -962,15 +959,14 @@ static void ffi_array_in(struct txr_ffi_type *tft, mem_t *src, val vec,
static void ffi_array_put(struct txr_ffi_type *tft, val vec, mem_t *dst,
val self)
{
- val eltypes = tft->mtypes;
+ val eltype = tft->mtypes;
+ struct txr_ffi_type *etft = ffi_type_struct(eltype);
+ cnum elsize = etft->size;
cnum nelem = tft->nelem, i;
int nt = tft->null_term;
ucnum offs = 0;
for (i = 0; i < nelem; i++) {
- val eltype = pop(&eltypes);
- struct txr_ffi_type *etft = ffi_type_struct(eltype);
- cnum elsize = etft->size;
val elval = ref(vec, num_fast(i));
if (nt && i == nelem - 1) {
memset(dst + offs, 0, elsize);
@@ -984,15 +980,14 @@ static void ffi_array_put(struct txr_ffi_type *tft, val vec, mem_t *dst,
static void ffi_array_out(struct txr_ffi_type *tft, int copy, val vec,
mem_t *dst, val self)
{
- val eltypes = tft->mtypes;
+ val eltype = tft->mtypes;
+ struct txr_ffi_type *etft = ffi_type_struct(eltype);
+ cnum elsize = etft->size;
cnum nelem = tft->nelem, i;
int nt = tft->null_term;
ucnum offs = 0;
for (i = 0; i < nelem; i++) {
- val eltype = pop(&eltypes);
- struct txr_ffi_type *etft = ffi_type_struct(eltype);
- cnum elsize = etft->size;
if (nt && i == nelem - 1) {
memset(dst + offs, 0, elsize);
break;
@@ -1007,10 +1002,11 @@ static void ffi_array_out(struct txr_ffi_type *tft, int copy, val vec,
static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self)
{
- val eltypes = tft->mtypes;
+ val eltype = tft->mtypes;
+ cnum nelem = tft->nelem;
if (tft->char_conv) {
- if (!eltypes) {
+ if (nelem == 0) {
return null_string;
} else {
const char *chptr = coerce(const char *, src);
@@ -1022,7 +1018,7 @@ static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self)
}
}
} else if (tft->wchar_conv) {
- if (!eltypes) {
+ if (nelem == 0) {
return null_string;
} else {
cnum nchar = tft->size / sizeof (wchar_t);
@@ -1036,14 +1032,12 @@ static val ffi_array_get(struct txr_ffi_type *tft, mem_t *src, val self)
}
}
} else {
- cnum nelem = tft->nelem;
val vec = vector(num_fast(nelem), 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++) {
- val eltype = pop(&eltypes);
- struct txr_ffi_type *etft = ffi_type_struct(eltype);
- cnum elsize = etft->size;
val elval = etft->get(etft, src + offs, self);
refset(vec, num_fast(i), elval);
offs += elsize;
@@ -1171,7 +1165,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
}
static val make_ffi_type_array(val syntax, val lisp_type,
- val dim, val eltypes)
+ val dim, val eltype)
{
struct txr_ffi_type *tft = coerce(struct txr_ffi_type *,
chk_calloc(1, sizeof *tft));
@@ -1182,6 +1176,8 @@ static val make_ffi_type_array(val syntax, val lisp_type,
(nelem + 1)));
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
+ struct txr_ffi_type *etft = ffi_type_struct(eltype);
+
ft->type = FFI_TYPE_STRUCT;
ft->size = 0;
@@ -1189,7 +1185,7 @@ static val make_ffi_type_array(val syntax, val lisp_type,
tft->syntax = syntax;
tft->lt = lisp_type;
tft->mnames = nil;
- tft->mtypes = eltypes;
+ tft->mtypes = eltype;
tft->put = ffi_array_put;
tft->get = ffi_array_get;
tft->in = ffi_array_in;
@@ -1197,8 +1193,6 @@ static val make_ffi_type_array(val syntax, val lisp_type,
tft->free = free;
for (i = 0; i < nelem; i++) {
- val eltype = pop(&eltypes);
- struct txr_ffi_type *etft = ffi_type_struct(eltype);
elements[i] = etft->ft;
if (i == 0) {
tft->size = etft->size * nelem;
@@ -1260,13 +1254,10 @@ val ffi_type_compile(val syntax)
} else if (sym == array_s || sym == zarray_s) {
val dim = cadr(syntax);
val eltype_syntax = caddr(syntax);
- list_collect_decl (eltypes, ptail);
- cnum dimn = c_num(dim), i;
- for (i = 0; i < dimn; i++)
- ptail = list_collect(ptail, ffi_type_compile(eltype_syntax));
+ val eltype = ffi_type_compile(eltype_syntax);
{
- val type = make_ffi_type_array(syntax, eltypes, dim, eltypes);
+ val type = make_ffi_type_array(syntax, vec_s, dim, eltype);
struct txr_ffi_type *tft = ffi_type_struct(type);
if (sym == zarray_s)
tft->null_term = 1;