diff options
author | Mike Pall <mike> | 2013-02-03 11:51:19 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2013-02-03 11:51:19 +0100 |
commit | fe9934feea0a8d580de19389f1a54d6cd4563d6b (patch) | |
tree | df5f18a64130edfac961b7e12586f008b62dc640 /src | |
parent | 4eb4b8ab8471233d63ae9644cdf304b847b3bbdc (diff) | |
download | luajit-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.c | 4 | ||||
-rw-r--r-- | src/lj_cconv.c | 6 | ||||
-rw-r--r-- | src/lj_cdata.c | 2 | ||||
-rw-r--r-- | src/lj_ctype.c | 12 | ||||
-rw-r--r-- | src/lj_ctype.h | 6 |
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. */ |
237 | CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs) | 237 | CType *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); | |||
441 | LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id); | 441 | LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id); |
442 | LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, | 442 | LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, |
443 | uint32_t tmask); | 443 | uint32_t tmask); |
444 | LJ_FUNC CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, | 444 | LJ_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) | ||
446 | LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id); | 448 | LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id); |
447 | LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id); | 449 | LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id); |
448 | LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem); | 450 | LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem); |