From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id CB9C56EC40; Sat, 30 May 2026 19:06:18 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CB9C56EC40 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1780157178; bh=X4oa2xRX+hcIlXUvOqkKJnanvwKML5vzpRh6H83ZD1w=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=IdFdpjc7YYqkqBxsw90SQcnzwNP0II6Y6dBiQBvy/2wulPuOpVv67fAHoRkprjGzf hVYBcbWTS+PhQEjUcgHWJjl89teivhEzqnt/jvaoqANgpVU0LksSttkJf8PB/45Bac zQMTU2hJW0SkMmsTggdQ47lmSXz1+Be7rlUb+bOw= Received: from send104.i.mail.ru (send104.i.mail.ru [89.221.237.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 799056EC40 for ; Sat, 30 May 2026 19:04:48 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 799056EC40 Received: by exim-smtp-5b85998476-w27zp with esmtpa (envelope-from ) id 1wTMB5-00000000NxS-1EIY; Sat, 30 May 2026 19:04:47 +0300 To: Sergey Bronnikov , Evgeniy Temirgaleev Date: Sat, 30 May 2026 19:04:07 +0300 Message-ID: <20260530160409.4043089-4-skaplun@tarantool.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260530160409.4043089-1-skaplun@tarantool.org> References: <20260530160409.4043089-1-skaplun@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9402BF17F4A9A44D662C07B246084A650DD50FF3C3D5AF68900894C459B0CD1B98FDF3026A5112CBF66FA44935DFD4124BA73C27A003C2FC48063F32B492FEB80B04C393452CF6677 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7BCC85671EC7A750CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB55337566A66E13412CE89A70B40EAF4E3DEA0CE383B4A56FFE45714BA89AAD2DD04B30FA389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0DCF4F0DC832992758941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6A50BD5087FBFCDAACC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE71F4E386938175FB9731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A58491F3BC293841825002B1117B3ED696D0468266AEA98E7FCCE9A60C8CB01D7C823CB91A9FED034534781492E4B8EEAD21D4E6D365FE45D1C79554A2A72441328621D336A7BC284946AD531847A6065A535571D14F44ED41 X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D6597D3CD9906860A668E2CC273CA03F74AEF80B986C1EA7487EEED4C0C0DA00CAA525F0C0D67166032BB8341EE9D5BE9A0AA230F82F4053B8124EEFE4E6A881BF003D19BFDF5F6A168BC7CEAA0681F5848F4C41F94D744909CECFA6C6B0C050A61A8CAF69B82BA93681CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVRI2994ruhLUK4Yr1jOJcUI= X-DA7885C5: 7B17793D18E86505F255D290C0D534F90A56ADF7C382C42FC378AE506CC8B4DE46C4FFCFD039B2675B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE2DDA6AEC6E36DF66E08715E8504D67BFA751A7CC32DD348C1E49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 3/5] ARM64: Fix pass-by-value struct calling conventions. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mike Pall Reported by AnthonyK213. (cherry picked from commit c262976486e1e007b56380b6a36bfbea5f51d470) The FFI call to the function with the pass-by-value structure containing the HFA arrays works incorrectly due to the `ccall_classify_struct()` lacking the handling of the array case. This patch adds the corresponding branch to check the single-dimentional array. However, the multidimensional arrays are not handled. This will be fixed in the next commit. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#12480 --- src/lj_ccall.c | 18 +++++++++++---- test/tarantool-tests/ffi-ccall/CMakeLists.txt | 1 + test/tarantool-tests/ffi-ccall/libfficcall.c | 12 ++++++++++ ...57-arm64-struct-array-pass-by-val.test.lua | 23 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/tarantool-tests/lj-1357-arm64-struct-array-pass-by-val.test.lua diff --git a/src/lj_ccall.c b/src/lj_ccall.c index b2705de5..104c9d34 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) { CTSize sz = ct->size; unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); - while (ct->sib) { + while (ct->sib && n <= 4) { + unsigned int m = 1; CType *sct; ct = ctype_get(cts, ct->sib); if (ctype_isfield(ct->info)) { sct = ctype_rawchild(cts, ct); + if (ctype_isarray(sct->info)) { + CType *cct = ctype_rawchild(cts, sct); + if (!cct->size) continue; + m = sct->size / cct->size; + sct = cct; + } if (ctype_isfp(sct->info)) { r |= sct->size; - if (!isu) n++; else if (n == 0) n = 1; + if (!isu) n += m; else if (n < m) n = m; } else if (ctype_iscomplex(sct->info)) { r |= (sct->size >> 1); - if (!isu) n += 2; else if (n < 2) n = 2; + if (!isu) n += 2*m; else if (n < 2*m) n = 2*m; } else if (ctype_isstruct(sct->info)) { goto substruct; } else { @@ -803,10 +810,11 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct) sct = ctype_rawchild(cts, ct); substruct: if (sct->size > 0) { - unsigned int s = ccall_classify_struct(cts, sct); + unsigned int s = ccall_classify_struct(cts, sct), sn; if (s <= 1) goto noth; r |= (s & 255); - if (!isu) n += (s >> 8); else if (n < (s >>8)) n = (s >> 8); + sn = (s >> 8) * m; + if (!isu) n += sn; else if (n < sn) n = sn; } } } diff --git a/test/tarantool-tests/ffi-ccall/CMakeLists.txt b/test/tarantool-tests/ffi-ccall/CMakeLists.txt index 27de07ac..1d004591 100644 --- a/test/tarantool-tests/ffi-ccall/CMakeLists.txt +++ b/test/tarantool-tests/ffi-ccall/CMakeLists.txt @@ -2,6 +2,7 @@ list(APPEND tests ffi-ccall-arm64-fp-convention.test.lua lj-205-arm64-osx-ffi-enum-arg.test.lua lj-205-arm64-osx-ffi-small-arg.test.lua + lj-1357-arm64-struct-array-pass-by-val.test.lua ) BuildTestCLib(libfficcall libfficcall.c "${tests}") diff --git a/test/tarantool-tests/ffi-ccall/libfficcall.c b/test/tarantool-tests/ffi-ccall/libfficcall.c index fd2d4711..ecb21752 100644 --- a/test/tarantool-tests/ffi-ccall/libfficcall.c +++ b/test/tarantool-tests/ffi-ccall/libfficcall.c @@ -77,3 +77,15 @@ float test_float_stack(float f1, float f2, float f3, float f4, float f5, return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11; } +/****************************************************************/ +/* Homogeneous Floating-Point Aggregate (HFA) argument. */ +/****************************************************************/ + +typedef struct hfa_float2 { + float v[2]; +} hfa_float2; + +float hfa_float2_sum(hfa_float2 h) +{ + return h.v[0] + h.v[1]; +} diff --git a/test/tarantool-tests/lj-1357-arm64-struct-array-pass-by-val.test.lua b/test/tarantool-tests/lj-1357-arm64-struct-array-pass-by-val.test.lua new file mode 100644 index 00000000..bb500de1 --- /dev/null +++ b/test/tarantool-tests/lj-1357-arm64-struct-array-pass-by-val.test.lua @@ -0,0 +1,23 @@ +local ffi = require('ffi') +local tap = require('tap') + +-- The test file to demonstrate incorrect FFI pass-by-value +-- structure with an array HFA member. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1357. +local test = tap.test('lj-1357-arm64-struct-array-pass-by-val') + +test:plan(1) + +local ffi_ccall = ffi.load('libfficcall') + +ffi.cdef[[ + typedef struct hfa_float2 { + float v[2]; + } hfa_float2; + + float hfa_float2_sum(hfa_float2 h); +]] + +test:is(ffi_ccall.hfa_float2_sum({{1, 2}}), 3, 'HFA float correct') + +test:done(true) -- 2.54.0