/* Compute argument size for fastcall/stdcall functions. */ static CTSize clib_func_argsize(CTState *cts, CType *ct) { CTSize n = 0; while (ct->sib) { CType *d; ct = ctype_get(cts, ct->sib); lua_assert(ctype_isfield(ct->info)); d = ctype_rawchild(cts, ct); n += ((d->size + 3) & ~3); } return n; }
/* Recursively classify a struct based on its fields. */ static int ccall_classify_struct(CTState *cts, CType *ct, int *rcl, CTSize ofs) { if (ct->size > 16) return CCALL_RCL_MEM; /* Too big, gets memory class. */ while (ct->sib) { CTSize fofs; ct = ctype_get(cts, ct->sib); fofs = ofs+ct->size; if (ctype_isfield(ct->info)) ccall_classify_ct(cts, ctype_rawchild(cts, ct), rcl, fofs); else if (ctype_isbitfield(ct->info)) rcl[(fofs >= 8)] |= CCALL_RCL_INT; /* NYI: unaligned bitfields? */ else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) ccall_classify_struct(cts, ctype_rawchild(cts, ct), rcl, fofs); } return ((rcl[0]|rcl[1]) & CCALL_RCL_MEM); /* Memory class? */ }
/* Classify a struct based on its fields. */ static unsigned int ccall_classify_struct(CTState *cts, CType *ct, CType *ctf) { CTSize sz = ct->size; unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); if ((ctf->info & CTF_VARARG)) goto noth; while (ct->sib) { ct = ctype_get(cts, ct->sib); if (ctype_isfield(ct->info)) { CType *sct = ctype_rawchild(cts, ct); if (ctype_isfp(sct->info)) { r |= sct->size; if (!isu) n++; else if (n == 0) n = 1; } else if (ctype_iscomplex(sct->info)) { r |= (sct->size >> 1); if (!isu) n += 2; else if (n < 2) n = 2; } else { goto noth;
/* Check for struct with single FP field. */ static int ccall_classify_struct(CTState *cts, CType *ct) { CTSize sz = ct->size; if (!(sz == sizeof(float) || sz == sizeof(double))) return 0; if ((ct->info & CTF_UNION)) return 0; while (ct->sib) { ct = ctype_get(cts, ct->sib); if (ctype_isfield(ct->info)) { CType *sct = ctype_rawchild(cts, ct); if (ctype_isfp(sct->info)) { if (sct->size == sz) return (sz >> 2); /* Return 1 for float or 2 for double. */ } else if (ctype_isstruct(sct->info)) { if (sct->size) return ccall_classify_struct(cts, sct); } else { break; } } else if (ctype_isbitfield(ct->info)) {