aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2013-02-03 11:51:19 +0100
committerMike Pall <mike>2013-02-03 11:51:19 +0100
commitfe9934feea0a8d580de19389f1a54d6cd4563d6b (patch)
treedf5f18a64130edfac961b7e12586f008b62dc640 /src
parent4eb4b8ab8471233d63ae9644cdf304b847b3bbdc (diff)
downloadluajit-fe9934feea0a8d580de19389f1a54d6cd4563d6b.tar.gz
luajit-fe9934feea0a8d580de19389f1a54d6cd4563d6b.tar.bz2
luajit-fe9934feea0a8d580de19389f1a54d6cd4563d6b.zip
FFI: Fix handling of qualified transparent structs/unions.
Diffstat (limited to 'src')
-rw-r--r--src/lj_ccall.c4
-rw-r--r--src/lj_cconv.c6
-rw-r--r--src/lj_cdata.c2
-rw-r--r--src/lj_ctype.c12
-rw-r--r--src/lj_ctype.h6
5 files changed, 21 insertions, 9 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 392012ff..5a905ca7 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -457,7 +457,7 @@ static int ccall_classify_struct(CTState *cts, CType *ct, int *rcl, CTSize ofs)
457 else if (ctype_isbitfield(ct->info)) 457 else if (ctype_isbitfield(ct->info))
458 rcl[(fofs >= 8)] |= CCALL_RCL_INT; /* NYI: unaligned bitfields? */ 458 rcl[(fofs >= 8)] |= CCALL_RCL_INT; /* NYI: unaligned bitfields? */
459 else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) 459 else if (ctype_isxattrib(ct->info, CTA_SUBTYPE))
460 ccall_classify_struct(cts, ctype_child(cts, ct), rcl, fofs); 460 ccall_classify_struct(cts, ctype_rawchild(cts, ct), rcl, fofs);
461 } 461 }
462 return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM); /* Memory class? */ 462 return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM); /* Memory class? */
463} 463}
@@ -541,7 +541,7 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct, CType *ctf)
541 } else if (ctype_isbitfield(ct->info)) { 541 } else if (ctype_isbitfield(ct->info)) {
542 goto noth; 542 goto noth;
543 } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) { 543 } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
544 CType *sct = ctype_child(cts, ct); 544 CType *sct = ctype_rawchild(cts, ct);
545 if (sct->size > 0) { 545 if (sct->size > 0) {
546 unsigned int s = ccall_classify_struct(cts, sct, ctf); 546 unsigned int s = ccall_classify_struct(cts, sct, ctf);
547 if (s <= 1) goto noth; 547 if (s <= 1) goto noth;
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
index 7b32e35d..c39da333 100644
--- a/src/lj_cconv.c
+++ b/src/lj_cconv.c
@@ -515,7 +515,8 @@ static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
515 lj_cconv_bf_tv(cts, df, dp+df->size, tv); 515 lj_cconv_bf_tv(cts, df, dp+df->size, tv);
516 if ((d->info & CTF_UNION)) break; 516 if ((d->info & CTF_UNION)) break;
517 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) { 517 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
518 cconv_substruct_tab(cts, ctype_child(cts, df), dp+df->size, t, ip, flags); 518 cconv_substruct_tab(cts, ctype_rawchild(cts, df),
519 dp+df->size, t, ip, flags);
519 } /* Ignore all other entries in the chain. */ 520 } /* Ignore all other entries in the chain. */
520 } 521 }
521} 522}
@@ -699,7 +700,8 @@ static void cconv_substruct_init(CTState *cts, CType *d, uint8_t *dp,
699 lj_cconv_bf_tv(cts, df, dp+df->size, o + i); 700 lj_cconv_bf_tv(cts, df, dp+df->size, o + i);
700 if ((d->info & CTF_UNION)) break; 701 if ((d->info & CTF_UNION)) break;
701 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) { 702 } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
702 cconv_substruct_init(cts, ctype_child(cts, df), dp+df->size, o, len, ip); 703 cconv_substruct_init(cts, ctype_rawchild(cts, df),
704 dp+df->size, o, len, ip);
703 } /* Ignore all other entries in the chain. */ 705 } /* Ignore all other entries in the chain. */
704 } 706 }
705} 707}
diff --git a/src/lj_cdata.c b/src/lj_cdata.c
index 896781bd..dac03873 100644
--- a/src/lj_cdata.c
+++ b/src/lj_cdata.c
@@ -151,7 +151,7 @@ collect_attrib:
151 GCstr *name = strV(key); 151 GCstr *name = strV(key);
152 if (ctype_isstruct(ct->info)) { 152 if (ctype_isstruct(ct->info)) {
153 CTSize ofs; 153 CTSize ofs;
154 CType *fct = lj_ctype_getfield(cts, ct, name, &ofs); 154 CType *fct = lj_ctype_getfieldq(cts, ct, name, &ofs, qual);
155 if (fct) { 155 if (fct) {
156 *pp = p + ofs; 156 *pp = p + ofs;
157 return fct; 157 return fct;
diff --git a/src/lj_ctype.c b/src/lj_ctype.c
index 666a5daf..14893cc2 100644
--- a/src/lj_ctype.c
+++ b/src/lj_ctype.c
@@ -234,7 +234,8 @@ CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, uint32_t tmask)
234} 234}
235 235
236/* Get a struct/union/enum/function field by name. */ 236/* Get a struct/union/enum/function field by name. */
237CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs) 237CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name, CTSize *ofs,
238 CTInfo *qual)
238{ 239{
239 while (ct->sib) { 240 while (ct->sib) {
240 ct = ctype_get(cts, ct->sib); 241 ct = ctype_get(cts, ct->sib);
@@ -243,8 +244,15 @@ CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs)
243 return ct; 244 return ct;
244 } 245 }
245 if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) { 246 if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
246 CType *fct = lj_ctype_getfield(cts, ctype_child(cts, ct), name, ofs); 247 CType *fct, *cct = ctype_child(cts, ct);
248 CTInfo q = 0;
249 while (ctype_isattrib(cct->info)) {
250 if (ctype_attrib(cct->info) == CTA_QUAL) q |= cct->size;
251 cct = ctype_child(cts, cct);
252 }
253 fct = lj_ctype_getfieldq(cts, cct, name, ofs, qual);
247 if (fct) { 254 if (fct) {
255 if (qual) *qual |= q;
248 *ofs += ct->size; 256 *ofs += ct->size;
249 return fct; 257 return fct;
250 } 258 }
diff --git a/src/lj_ctype.h b/src/lj_ctype.h
index 7c3b667c..e2c09121 100644
--- a/src/lj_ctype.h
+++ b/src/lj_ctype.h
@@ -441,8 +441,10 @@ LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
441LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id); 441LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
442LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, 442LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
443 uint32_t tmask); 443 uint32_t tmask);
444LJ_FUNC CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, 444LJ_FUNC CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name,
445 CTSize *ofs); 445 CTSize *ofs, CTInfo *qual);
446#define lj_ctype_getfield(cts, ct, name, ofs) \
447 lj_ctype_getfieldq((cts), (ct), (name), (ofs), NULL)
446LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id); 448LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
447LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id); 449LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
448LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem); 450LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);