diff options
| author | Mike Pall <mike> | 2013-05-16 14:47:20 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2013-05-16 14:47:20 +0200 |
| commit | 1c7650f782c4e6482cf496699af9136c89fe22b2 (patch) | |
| tree | d8de8fcd9c14e0caef0af4becf6392d64aebce48 | |
| parent | 5dabdb2e70799bdd9973495e0e00946e4495eece (diff) | |
| download | luajit-1c7650f782c4e6482cf496699af9136c89fe22b2.tar.gz luajit-1c7650f782c4e6482cf496699af9136c89fe22b2.tar.bz2 luajit-1c7650f782c4e6482cf496699af9136c89fe22b2.zip | |
FFI: Fix calling conventions for ARM hard-float EABI.
Properly classify nested (non-transparent) structs.
| -rw-r--r-- | src/lj_ccall.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 29909891..eb73604f 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c | |||
| @@ -584,22 +584,26 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct, CType *ctf) | |||
| 584 | unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); | 584 | unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); |
| 585 | if ((ctf->info & CTF_VARARG)) goto noth; | 585 | if ((ctf->info & CTF_VARARG)) goto noth; |
| 586 | while (ct->sib) { | 586 | while (ct->sib) { |
| 587 | CType *sct; | ||
| 587 | ct = ctype_get(cts, ct->sib); | 588 | ct = ctype_get(cts, ct->sib); |
| 588 | if (ctype_isfield(ct->info)) { | 589 | if (ctype_isfield(ct->info)) { |
| 589 | CType *sct = ctype_rawchild(cts, ct); | 590 | sct = ctype_rawchild(cts, ct); |
| 590 | if (ctype_isfp(sct->info)) { | 591 | if (ctype_isfp(sct->info)) { |
| 591 | r |= sct->size; | 592 | r |= sct->size; |
| 592 | if (!isu) n++; else if (n == 0) n = 1; | 593 | if (!isu) n++; else if (n == 0) n = 1; |
| 593 | } else if (ctype_iscomplex(sct->info)) { | 594 | } else if (ctype_iscomplex(sct->info)) { |
| 594 | r |= (sct->size >> 1); | 595 | r |= (sct->size >> 1); |
| 595 | if (!isu) n += 2; else if (n < 2) n = 2; | 596 | if (!isu) n += 2; else if (n < 2) n = 2; |
| 597 | } else if (ctype_isstruct(sct->info)) { | ||
| 598 | goto substruct; | ||
| 596 | } else { | 599 | } else { |
| 597 | goto noth; | 600 | goto noth; |
| 598 | } | 601 | } |
| 599 | } else if (ctype_isbitfield(ct->info)) { | 602 | } else if (ctype_isbitfield(ct->info)) { |
| 600 | goto noth; | 603 | goto noth; |
| 601 | } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) { | 604 | } else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) { |
| 602 | CType *sct = ctype_rawchild(cts, ct); | 605 | sct = ctype_rawchild(cts, ct); |
| 606 | substruct: | ||
| 603 | if (sct->size > 0) { | 607 | if (sct->size > 0) { |
| 604 | unsigned int s = ccall_classify_struct(cts, sct, ctf); | 608 | unsigned int s = ccall_classify_struct(cts, sct, ctf); |
| 605 | if (s <= 1) goto noth; | 609 | if (s <= 1) goto noth; |
