Browse Source

FFI: Fix handling of qualified transparent structs/unions.

Mike Pall 12 years ago
parent
commit
fe9934feea
5 changed files with 21 additions and 9 deletions
  1. 2 2
      src/lj_ccall.c
  2. 4 2
      src/lj_cconv.c
  3. 1 1
      src/lj_cdata.c
  4. 10 2
      src/lj_ctype.c
  5. 4 2
      src/lj_ctype.h

+ 2 - 2
src/lj_ccall.c

@@ -457,7 +457,7 @@ static int ccall_classify_struct(CTState *cts, CType *ct, int *rcl, CTSize ofs)
     else if (ctype_isbitfield(ct->info))
     else if (ctype_isbitfield(ct->info))
       rcl[(fofs >= 8)] |= CCALL_RCL_INT;  /* NYI: unaligned bitfields? */
       rcl[(fofs >= 8)] |= CCALL_RCL_INT;  /* NYI: unaligned bitfields? */
     else if (ctype_isxattrib(ct->info, CTA_SUBTYPE))
     else if (ctype_isxattrib(ct->info, CTA_SUBTYPE))
-      ccall_classify_struct(cts, ctype_child(cts, ct), rcl, fofs);
+      ccall_classify_struct(cts, ctype_rawchild(cts, ct), rcl, fofs);
   }
   }
   return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM);  /* Memory class? */
   return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM);  /* Memory class? */
 }
 }
@@ -541,7 +541,7 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct, CType *ctf)
     } else if (ctype_isbitfield(ct->info)) {
     } else if (ctype_isbitfield(ct->info)) {
       goto noth;
       goto noth;
     } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
     } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
-      CType *sct = ctype_child(cts, ct);
+      CType *sct = ctype_rawchild(cts, ct);
       if (sct->size > 0) {
       if (sct->size > 0) {
 	unsigned int s = ccall_classify_struct(cts, sct, ctf);
 	unsigned int s = ccall_classify_struct(cts, sct, ctf);
 	if (s <= 1) goto noth;
 	if (s <= 1) goto noth;

+ 4 - 2
src/lj_cconv.c

@@ -515,7 +515,8 @@ static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
 	lj_cconv_bf_tv(cts, df, dp+df->size, tv);
 	lj_cconv_bf_tv(cts, df, dp+df->size, tv);
       if ((d->info & CTF_UNION)) break;
       if ((d->info & CTF_UNION)) break;
     } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
     } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
-      cconv_substruct_tab(cts, ctype_child(cts, df), dp+df->size, t, ip, flags);
+      cconv_substruct_tab(cts, ctype_rawchild(cts, df),
+			  dp+df->size, t, ip, flags);
     }  /* Ignore all other entries in the chain. */
     }  /* Ignore all other entries in the chain. */
   }
   }
 }
 }
@@ -699,7 +700,8 @@ static void cconv_substruct_init(CTState *cts, CType *d, uint8_t *dp,
 	lj_cconv_bf_tv(cts, df, dp+df->size, o + i);
 	lj_cconv_bf_tv(cts, df, dp+df->size, o + i);
       if ((d->info & CTF_UNION)) break;
       if ((d->info & CTF_UNION)) break;
     } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
     } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
-      cconv_substruct_init(cts, ctype_child(cts, df), dp+df->size, o, len, ip);
+      cconv_substruct_init(cts, ctype_rawchild(cts, df),
+			   dp+df->size, o, len, ip);
     }  /* Ignore all other entries in the chain. */
     }  /* Ignore all other entries in the chain. */
   }
   }
 }
 }

+ 1 - 1
src/lj_cdata.c

@@ -151,7 +151,7 @@ collect_attrib:
     GCstr *name = strV(key);
     GCstr *name = strV(key);
     if (ctype_isstruct(ct->info)) {
     if (ctype_isstruct(ct->info)) {
       CTSize ofs;
       CTSize ofs;
-      CType *fct = lj_ctype_getfield(cts, ct, name, &ofs);
+      CType *fct = lj_ctype_getfieldq(cts, ct, name, &ofs, qual);
       if (fct) {
       if (fct) {
 	*pp = p + ofs;
 	*pp = p + ofs;
 	return fct;
 	return fct;

+ 10 - 2
src/lj_ctype.c

@@ -234,7 +234,8 @@ CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name, uint32_t tmask)
 }
 }
 
 
 /* Get a struct/union/enum/function field by name. */
 /* Get a struct/union/enum/function field by name. */
-CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs)
+CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name, CTSize *ofs,
+			  CTInfo *qual)
 {
 {
   while (ct->sib) {
   while (ct->sib) {
     ct = ctype_get(cts, ct->sib);
     ct = ctype_get(cts, ct->sib);
@@ -243,8 +244,15 @@ CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name, CTSize *ofs)
       return ct;
       return ct;
     }
     }
     if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
     if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
-      CType *fct = lj_ctype_getfield(cts, ctype_child(cts, ct), name, ofs);
+      CType *fct, *cct = ctype_child(cts, ct);
+      CTInfo q = 0;
+      while (ctype_isattrib(cct->info)) {
+	if (ctype_attrib(cct->info) == CTA_QUAL) q |= cct->size;
+	cct = ctype_child(cts, cct);
+      }
+      fct = lj_ctype_getfieldq(cts, cct, name, ofs, qual);
       if (fct) {
       if (fct) {
+	if (qual) *qual |= q;
 	*ofs += ct->size;
 	*ofs += ct->size;
 	return fct;
 	return fct;
       }
       }

+ 4 - 2
src/lj_ctype.h

@@ -441,8 +441,10 @@ LJ_FUNC CTypeID lj_ctype_intern(CTState *cts, CTInfo info, CTSize size);
 LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
 LJ_FUNC void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id);
 LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
 LJ_FUNC CTypeID lj_ctype_getname(CTState *cts, CType **ctp, GCstr *name,
 				 uint32_t tmask);
 				 uint32_t tmask);
-LJ_FUNC CType *lj_ctype_getfield(CTState *cts, CType *ct, GCstr *name,
-				 CTSize *ofs);
+LJ_FUNC CType *lj_ctype_getfieldq(CTState *cts, CType *ct, GCstr *name,
+				  CTSize *ofs, CTInfo *qual);
+#define lj_ctype_getfield(cts, ct, name, ofs) \
+  lj_ctype_getfieldq((cts), (ct), (name), (ofs), NULL)
 LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
 LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
 LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
 LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
 LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);
 LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);