aboutsummaryrefslogtreecommitdiff
path: root/src/lj_ccall.c
diff options
context:
space:
mode:
authorMike Pall <mike>2025-04-10 22:06:47 +0200
committerMike Pall <mike>2025-04-10 22:06:47 +0200
commitc262976486e1e007b56380b6a36bfbea5f51d470 (patch)
treec4bd4bc2d8e3acea5ce5a15ab24da533d68f11ca /src/lj_ccall.c
parente0a7ea8a924d8137e6950b97c3e36f17264f6c79 (diff)
downloadluajit-c262976486e1e007b56380b6a36bfbea5f51d470.tar.gz
luajit-c262976486e1e007b56380b6a36bfbea5f51d470.tar.bz2
luajit-c262976486e1e007b56380b6a36bfbea5f51d470.zip
ARM64: Fix pass-by-value struct calling conventions.
Reported by AnthonyK213. #1357
Diffstat (limited to '')
-rw-r--r--src/lj_ccall.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index ae69cd28..f003d756 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -781,17 +781,24 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct)
781{ 781{
782 CTSize sz = ct->size; 782 CTSize sz = ct->size;
783 unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); 783 unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION);
784 while (ct->sib) { 784 while (ct->sib && n <= 4) {
785 unsigned int m = 1;
785 CType *sct; 786 CType *sct;
786 ct = ctype_get(cts, ct->sib); 787 ct = ctype_get(cts, ct->sib);
787 if (ctype_isfield(ct->info)) { 788 if (ctype_isfield(ct->info)) {
788 sct = ctype_rawchild(cts, ct); 789 sct = ctype_rawchild(cts, ct);
790 if (ctype_isarray(sct->info)) {
791 CType *cct = ctype_rawchild(cts, sct);
792 if (!cct->size) continue;
793 m = sct->size / cct->size;
794 sct = cct;
795 }
789 if (ctype_isfp(sct->info)) { 796 if (ctype_isfp(sct->info)) {
790 r |= sct->size; 797 r |= sct->size;
791 if (!isu) n++; else if (n == 0) n = 1; 798 if (!isu) n += m; else if (n < m) n = m;
792 } else if (ctype_iscomplex(sct->info)) { 799 } else if (ctype_iscomplex(sct->info)) {
793 r |= (sct->size >> 1); 800 r |= (sct->size >> 1);
794 if (!isu) n += 2; else if (n < 2) n = 2; 801 if (!isu) n += 2*m; else if (n < 2*m) n = 2*m;
795 } else if (ctype_isstruct(sct->info)) { 802 } else if (ctype_isstruct(sct->info)) {
796 goto substruct; 803 goto substruct;
797 } else { 804 } else {
@@ -803,10 +810,11 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct)
803 sct = ctype_rawchild(cts, ct); 810 sct = ctype_rawchild(cts, ct);
804 substruct: 811 substruct:
805 if (sct->size > 0) { 812 if (sct->size > 0) {
806 unsigned int s = ccall_classify_struct(cts, sct); 813 unsigned int s = ccall_classify_struct(cts, sct), sn;
807 if (s <= 1) goto noth; 814 if (s <= 1) goto noth;
808 r |= (s & 255); 815 r |= (s & 255);
809 if (!isu) n += (s >> 8); else if (n < (s >>8)) n = (s >> 8); 816 sn = (s >> 8) * m;
817 if (!isu) n += sn; else if (n < sn) n = sn;
810 } 818 }
811 } 819 }
812 } 820 }