diff options
author | Mike Pall <mike> | 2025-04-10 22:06:47 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2025-04-10 22:06:47 +0200 |
commit | c262976486e1e007b56380b6a36bfbea5f51d470 (patch) | |
tree | c4bd4bc2d8e3acea5ce5a15ab24da533d68f11ca /src/lj_ccall.c | |
parent | e0a7ea8a924d8137e6950b97c3e36f17264f6c79 (diff) | |
download | luajit-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.c | 18 |
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 | } |