diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-25 06:19:09 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-25 06:19:09 -0700 |
commit | 02c9c3c46a4e77939f0b2f58b9dcfab950980a82 (patch) | |
tree | 35da71725ab7381105be957037fae2a2c6249078 /ffi.c | |
parent | 2948a2b1e01b91e17d90d2e7954f0d3a499a3a4d (diff) | |
download | txr-02c9c3c46a4e77939f0b2f58b9dcfab950980a82.tar.gz txr-02c9c3c46a4e77939f0b2f58b9dcfab950980a82.tar.bz2 txr-02c9c3c46a4e77939f0b2f58b9dcfab950980a82.zip |
ffi: precompute member offsets in struct type.
This change will make bitfield support easier.
* ffi.c (struct smemb): New member, offs.
(ffi_struct_in, ffi_struct_put, ffi_struct_out,
ffi_struct_get, ffi_struct_release): For each member, refer to
the offset in the memb array, rather than calculating it
on-the-fly.
(make_ffi_type_struct): Calculate the offset for each member.
This is exactly the same as the total_size calculation before;
just the name is changed to offs, and bit operations are used
for the alignment calculations.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 40 |
1 files changed, 14 insertions, 26 deletions
@@ -99,6 +99,7 @@ struct smemb { val mname; val mtype; struct txr_ffi_type *mtft; + cnum offs; }; struct txr_ffi_type { @@ -965,7 +966,6 @@ static val ffi_struct_in(struct txr_ffi_type *tft, int copy, mem_t *src, { cnum i, nmemb = tft->nelem; struct smemb *memb = tft->memb; - ucnum offs = 0; if (strct == nil) { args_decl(args, 0); @@ -975,8 +975,7 @@ static val ffi_struct_in(struct txr_ffi_type *tft, int copy, mem_t *src, for (i = 0; i < nmemb; i++) { val slsym = memb[i].mname; struct txr_ffi_type *mtft = memb[i].mtft; - ucnum almask = mtft->align - 1; - offs = (offs + almask) & ~almask; + ucnum offs = memb[i].offs; if (slsym) { if (mtft->in != 0) { val slval = slot(strct, slsym); @@ -986,7 +985,6 @@ static val ffi_struct_in(struct txr_ffi_type *tft, int copy, mem_t *src, slotset(strct, slsym, slval); } } - offs += mtft->size; } return strct; @@ -997,18 +995,15 @@ static void ffi_struct_put(struct txr_ffi_type *tft, val strct, mem_t *dst, { cnum i, nmemb = tft->nelem; struct smemb *memb = tft->memb; - ucnum offs = 0; for (i = 0; i < nmemb; i++) { val slsym = memb[i].mname; struct txr_ffi_type *mtft = memb[i].mtft; - ucnum almask = mtft->align - 1; - offs = (offs + almask) & ~almask; + ucnum offs = memb[i].offs; if (slsym) { val slval = slot(strct, slsym); mtft->put(mtft, slval, dst + offs, self); } - offs += mtft->size; } } @@ -1017,13 +1012,11 @@ static void ffi_struct_out(struct txr_ffi_type *tft, int copy, val strct, { cnum i, nmemb = tft->nelem; struct smemb *memb = tft->memb; - ucnum offs = 0; for (i = 0; i < nmemb; i++) { val slsym = memb[i].mname; struct txr_ffi_type *mtft = memb[i].mtft; - ucnum almask = mtft->align - 1; - offs = (offs + almask) & ~almask; + ucnum offs = memb[i].offs; if (slsym) { if (mtft->out != 0) { val slval = slot(strct, slsym); @@ -1033,7 +1026,6 @@ static void ffi_struct_out(struct txr_ffi_type *tft, int copy, val strct, mtft->put(mtft, slval, dst + offs, self); } } - offs += mtft->size; } } @@ -1041,20 +1033,17 @@ static val ffi_struct_get(struct txr_ffi_type *tft, mem_t *src, val self) { cnum i, nmemb = tft->nelem; struct smemb *memb = tft->memb; - ucnum offs = 0; args_decl(args, 0); val strct = make_struct(tft->lt, nil, args); for (i = 0; i < nmemb; i++) { val slsym = memb[i].mname; struct txr_ffi_type *mtft = memb[i].mtft; - ucnum almask = mtft->align - 1; - offs = (offs + almask) & ~almask; + ucnum offs = memb[i].offs; if (slsym) { val slval = mtft->get(mtft, src + offs, self); slotset(strct, slsym, slval); } - offs += mtft->size; } return strct; @@ -1064,7 +1053,6 @@ static void ffi_struct_release(struct txr_ffi_type *tft, val strct, mem_t *dst) { cnum i, nmemb = tft->nelem; struct smemb *memb = tft->memb; - ucnum offs = 0; if (strct == nil) return; @@ -1072,15 +1060,13 @@ static void ffi_struct_release(struct txr_ffi_type *tft, val strct, mem_t *dst) for (i = 0; i < nmemb; i++) { val slsym = memb[i].mname; struct txr_ffi_type *mtft = memb[i].mtft; - ucnum almask = mtft->align - 1; - offs = (offs + almask) & ~almask; + ucnum offs = memb[i].offs; if (slsym) { if (mtft->release != 0) { val slval = slot(strct, slsym); mtft->release(mtft, slval, dst + offs); } } - offs += mtft->size; } } @@ -1530,8 +1516,8 @@ static val make_ffi_type_struct(val syntax, val lisp_type, struct smemb *memb = coerce(struct smemb *, chk_malloc(sizeof *memb * nmemb)); val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops); - cnum total_size = 0; - cnum most_align = 0; + ucnum offs = 0; + ucnum most_align = 0; int need_out_handler = 0; ft->type = FFI_TYPE_STRUCT; @@ -1554,18 +1540,22 @@ static val make_ffi_type_struct(val syntax, val lisp_type, struct txr_ffi_type *mtft = ffi_type_struct(type); cnum align = mtft->align; cnum size = mtft->size; + ucnum almask = align - 1; elements[i] = mtft->ft; memb[i].mtype = type; memb[i].mname = slot; memb[i].mtft = mtft; + memb[i].offs = offs; if (align > most_align) most_align = align; - total_size = (total_size + align - 1) / align * align + size; need_out_handler = need_out_handler || mtft->out != 0; + + offs += size; + offs = (offs + almask) & ~almask; } elements[i] = 0; @@ -1575,9 +1565,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type, ft->elements = elements; - total_size = (total_size + most_align - 1) / most_align * most_align; - - tft->size = total_size; + tft->size = (offs + most_align - 1) & ~(most_align - 1); tft->align = most_align; tft->memb = memb; |