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 7794B6F152; Wed, 1 Jul 2026 18:48:43 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 7794B6F152 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1782920923; bh=2jOf3Kevm/ZArK37WEUiwiSBsVMPlkbo2nrszogFbUc=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=N02nNv/ONHJ88H0ECdSXfY2axClruvm6itIQGDbkoIEVCx1Ct4CduDopJ8LQKHZnl cxJRQ1pq4d4Xyd2zoZBZbpgjUm7JL0PkZJXIC4ind2h1IvUnz3yNgvh14On9FXgdXu Ngh8chX+I5OC/eGVAHSKqTImMG78vubvd/+3rY0A= Received: from send128.i.mail.ru (send128.i.mail.ru [89.221.237.223]) (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 348216F152 for ; Wed, 1 Jul 2026 18:48:42 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 348216F152 Received: by exim-smtp-86dd7df456-6k7xg with esmtpa (envelope-from ) id 1wexB2-00000000XYB-3rbT; Wed, 01 Jul 2026 18:48:41 +0300 Content-Type: multipart/alternative; boundary="------------BrS1wroY06bWOxzqj5bHmPml" Message-ID: <96623550-cfbb-4beb-97b5-aa2b9ea0cfca@tarantool.org> Date: Wed, 1 Jul 2026 18:48:39 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Evgeniy Temirgaleev Cc: tarantool-patches@dev.tarantool.org References: <20260629131914.791223-1-skaplun@tarantool.org> In-Reply-To: <20260629131914.791223-1-skaplun@tarantool.org> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9FB99764E620CE828229529086C0268BC15695A558A375E9600894C459B0CD1B961E50DB6B664B3D17A388D641E84891F590A772BA360F98CC69B0652430D8537B92CE970A8DCB349 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7B356E3E4D202B32AEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB553375667C07923B88CEC0EDA2E7397CC34792CF279B52D68D8FDFCA63BCA72C53CCF932389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0A29E2F051442AF778941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6F459A8243F1D1D44CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE7BEE702378D8A34C7731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A50268305C0DA4C62C5002B1117B3ED696943DFC668283A19A484B8D70797403F6823CB91A9FED034534781492E4B8EEADAE4FDBF11360AC9BBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D65961E8884041826BD0A7A1C6F97DCA183FF389CD2B13C393E827B2BFB1F879670F59AB908D0A6E2E69B8341EE9D5BE9A0AF5D97207E935806F5466F93A497603649FBA776F99E916506536EB022892E5344C41F94D744909CE2512F26BEC029E55448553D2254B8D95CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVRSZSJkMhZtMYheeS87Q2Xk= X-DA7885C5: 74CC1C2DCD9B9D24F255D290C0D534F9655777A594FC66721842945ECEA0B3689BA7B67181801DC25B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE2D101686D520BA521097B88574669611BFDD4F8C5B1FCFE84EF86D5F70DA33880E41E8EF7A07863ECB274557F927329BE2DDF8182D28ACDB545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit] FFI/MacOS: Fix calling convention for on-stack varargs. 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 Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This is a multi-part message in MIME format. --------------BrS1wroY06bWOxzqj5bHmPml Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Sergey, thanks for the patch! LGTM Sergey On 6/29/26 16:19, Sergey Kaplun wrote: > From: Mike Pall > > Thanks to Sergey Kaplun. > > (cherry picked from commit a2bde60819d83e6f75130ac2c93ee4b3c7615800) > > This commit fixes the regression introduced by the commit > 82ca6844234901366c043cd103f6eae345af753c ("FFI/MacOS: Fix calling > convention for enums."). The `isva` flag is set to 0 even for vararg > functions. Thus, arguments on the stack may be aligned incorrectly, > leading to the crash. > > This patch fixes the behaviour by adjusting the flag value instead of > resetting it. In addition to the original test, various tests have been > added to cover the behaviour of the vararg FFI calls. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#12480 > --- > > Branch:https://github.com/tarantool/luajit/tree/skaplun/lj-1455-macos-arm64-vararg-regression > Related issues: > *https://github.com/LuaJIT/LuaJIT/issues/1455 > *https://github.com/neovim/neovim/pull/39994 > *https://github.com/tarantool/tarantool/issues/12480 > > src/lj_ccall.c | 2 +- > ...455-macos-arm64-vararg-regression.test.lua | 112 ++++++++++++++++++ > 2 files changed, 113 insertions(+), 1 deletion(-) > create mode 100644 test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua > > diff --git a/src/lj_ccall.c b/src/lj_ccall.c > index 7c3ec1e5..ed692318 100644 > --- a/src/lj_ccall.c > +++ b/src/lj_ccall.c > @@ -1082,7 +1082,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, > if (CCALL_ALIGN_STACKARG) { /* Align argument on stack. */ > MSize align = (1u << ctype_align(ccall_struct_align(cts, d))) - 1; > #if LJ_TARGET_ARM64 && LJ_TARGET_OSX > - isva = ctype_isstruct(d->info); > + isva |= ctype_isstruct(d->info); > #endif > if (rp || (CCALL_PACK_STACKARG && isva && align < CTSIZE_PTR-1)) > align = CTSIZE_PTR-1; > diff --git a/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua b/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua > new file mode 100644 > index 00000000..a6670cce > --- /dev/null > +++ b/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua > @@ -0,0 +1,112 @@ > +local ffi = require('ffi') > +local tap = require('tap') > + > +-- The test file to test various FFI C vararg calls. > +-- luacheck: push no max_comment_line_length > +-- Originated from:https://github.com/neovim/neovim/blob/a5aa62e37b82214a1d4d1e0a54d193b155fb340c/test/unit/strings_spec.lua > +-- luacheck: pop > +-- See also:https://github.com/LuaJIT/LuaJIT/issues/1455. > + > +local test = tap.test('lj-1455-macos-arm64-vararg-regression') > + > +test:plan(45) > + > +ffi.cdef('int sprintf(char *str, const char *format, ...);') > + > +local buf = ffi.new('char[64]') > + > +local function t(expected, fmt, ...) > + local args = {...} > + local ctx = string.format('sprintf(buf, "%s"', fmt) > + for _, x in ipairs(args) do > + ctx = ctx .. ', ' .. tostring(x) > + end > + ctx = ctx .. string.format(') = %s', expected) > + > +test:test(ctx, function(subtest, ...) > +subtest:plan(2) > +subtest:is(ffi.C.sprintf(buf, fmt, ...), #expected, > + ctx .. ' - return status') > +subtest:is(ffi.string(buf), expected, ctx .. ' - result string') > + end, ...) > +end > + > +local function i(n) > + return ffi.cast('int', n) > +end > + > +local function l(n) > + return ffi.cast('long', n) > +end > + > +local function ll(n) > + return ffi.cast('long long', n) > +end > + > +local function z(n) > + return ffi.cast('ptrdiff_t', n) > +end > + > +local function u(n) > + return ffi.cast('unsigned', n) > +end > + > +local function ul(n) > + return ffi.cast('unsigned long', n) > +end > + > +local function ull(n) > + return ffi.cast('unsigned long long', n) > +end > + > +local function uz(n) > + return ffi.cast('size_t', n) > +end > + > +t('1234567', '%d', i(1234567)) > +t('1234567', '%ld', l(1234567)) > +t(' 1234567', '%9ld', l(1234567)) > +t('1234567 ', '%-9ld', l(1234567)) > +t('deadbeef', '%x', u(0xdeadbeef)) > +t('one two', '%s %s', 'one', 'two') > +t('1.234000', '%f', 1.234) > +t('1.234000e+00', '%e', 1.234) > +t('inf', '%f', 1.0 / 0.0) > +t('-inf', '%f', -1.0 / 0.0) > +t('-0.000000', '%f', tonumber('-0.0')) > +t('%%%', '%%%%%%') > +t('0x87654321', '%p', ffi.cast('char *', 0x87654321)) > +t('0x0087654321', '%012p', ffi.cast('char *', 0x87654321)) > +t('1234567 ', '%1$*2$ld', l(1234567), i(-9)) > +t('1234567 ', '%1$*2$.*3$ld', l(1234567), i(-9), i(5)) > +t('1234567 ', '%1$*3$.*2$ld', l(1234567), i(5), i(-9)) > +t('1234567 ', '%3$*1$.*2$ld', i(-9), i(5), l(1234567)) > +t('1234567', '%1$ld', l(1234567)) > +t(' 1234567', '%1$*2$ld', l(1234567), i(9)) > +t('9 12345 7654321', '%2$ld %1$d %3$lu', i(12345), l(9), ul(7654321)) > +t('9 1234567 7654321', '%2$d %1$ld %3$lu', l(1234567), i(9), ul(7654321)) > +t('9 1234567 7654321', '%2$d %1$lld %3$lu', ll(1234567), i(9), ul(7654321)) > +t('9 12345 7654321', '%2$ld %1$u %3$lu', u(12345), l(9), ul(7654321)) > +t('9 1234567 7654321', '%2$d %1$lu %3$lu', ul(1234567), i(9), ul(7654321)) > +t('9 1234567 7654321', '%2$d %1$llu %3$lu', ull(1234567), i(9), ul(7654321)) > +t('9 deadbeef 7654321', '%2$d %1$x %3$lu', u(0xdeadbeef), i(9), ul(7654321)) > +t('9 c 7654321', '%2$ld %1$c %3$lu', i(('c'):byte()), l(9), ul(7654321)) > +t('9 hi 7654321', '%2$ld %1$s %3$lu', 'hi', l(9), ul(7654321)) > +t('9 0.000000e+00 7654321', '%2$ld %1$e %3$lu', 0.0, l(9), ul(7654321)) > +t('two one two', '%2$s %1$s %2$s', 'one', 'two', 'three') > +t('three one two', '%3$s %1$s %2$s', 'one', 'two', 'three') > +t('1234567', '%1$d', i(1234567)) > +t('deadbeef', '%1$x', u(0xdeadbeef)) > +t('one two', '%1$s %2$s', 'one', 'two') > +t('two one', '%2$s %1$s', 'one', 'two') > +t('1.234000', '%1$f', 1.234) > +t('1.234000e+00', '%1$e', 1.234) > +t('inf', '%1$f', 1.0 / 0.0) > +t('-inf', '%1$f', -1.0 / 0.0) > +t('-0.000000', '%1$f', tonumber('-0.0')) > +t('-1234567 -7654321', '%zd %zd', z(-1234567), z(-7654321)) > +t('-7654321 -1234567', '%2$zd %1$zd', z(-1234567), z(-7654321)) > +t('1234567 7654321', '%zu %zu', uz(1234567), uz(7654321)) > +t('7654321 1234567', '%2$zu %1$zu', uz(1234567), uz(7654321)) > + > +test:done(true) --------------BrS1wroY06bWOxzqj5bHmPml Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit

Sergey,

thanks for the patch! LGTM

Sergey

On 6/29/26 16:19, Sergey Kaplun wrote:
From: Mike Pall <mike>

Thanks to Sergey Kaplun.

(cherry picked from commit a2bde60819d83e6f75130ac2c93ee4b3c7615800)

This commit fixes the regression introduced by the commit
82ca6844234901366c043cd103f6eae345af753c ("FFI/MacOS: Fix calling
convention for enums."). The `isva` flag is set to 0 even for vararg
functions. Thus, arguments on the stack may be aligned incorrectly,
leading to the crash.

This patch fixes the behaviour by adjusting the flag value instead of
resetting it. In addition to the original test, various tests have been
added to cover the behaviour of the vararg FFI calls.

Sergey Kaplun:
* added the description and the test for the problem

Part of tarantool/tarantool#12480
---

Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1455-macos-arm64-vararg-regression
Related issues:
* https://github.com/LuaJIT/LuaJIT/issues/1455
* https://github.com/neovim/neovim/pull/39994
* https://github.com/tarantool/tarantool/issues/12480

 src/lj_ccall.c                                |   2 +-
 ...455-macos-arm64-vararg-regression.test.lua | 112 ++++++++++++++++++
 2 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua

diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 7c3ec1e5..ed692318 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -1082,7 +1082,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
     if (CCALL_ALIGN_STACKARG) {  /* Align argument on stack. */
       MSize align = (1u << ctype_align(ccall_struct_align(cts, d))) - 1;
 #if LJ_TARGET_ARM64 && LJ_TARGET_OSX
-      isva = ctype_isstruct(d->info);
+      isva |= ctype_isstruct(d->info);
 #endif
       if (rp || (CCALL_PACK_STACKARG && isva && align < CTSIZE_PTR-1))
 	align = CTSIZE_PTR-1;
diff --git a/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua b/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua
new file mode 100644
index 00000000..a6670cce
--- /dev/null
+++ b/test/tarantool-tests/lj-1455-macos-arm64-vararg-regression.test.lua
@@ -0,0 +1,112 @@
+local ffi = require('ffi')
+local tap = require('tap')
+
+-- The test file to test various FFI C vararg calls.
+-- luacheck: push no max_comment_line_length
+-- Originated from: https://github.com/neovim/neovim/blob/a5aa62e37b82214a1d4d1e0a54d193b155fb340c/test/unit/strings_spec.lua
+-- luacheck: pop
+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1455.
+
+local test = tap.test('lj-1455-macos-arm64-vararg-regression')
+
+test:plan(45)
+
+ffi.cdef('int sprintf(char *str, const char *format, ...);')
+
+local buf = ffi.new('char[64]')
+
+local function t(expected, fmt, ...)
+  local args = {...}
+  local ctx = string.format('sprintf(buf, "%s"', fmt)
+  for _, x in ipairs(args) do
+    ctx = ctx .. ', ' .. tostring(x)
+  end
+  ctx = ctx .. string.format(') = %s', expected)
+
+  test:test(ctx, function(subtest, ...)
+    subtest:plan(2)
+    subtest:is(ffi.C.sprintf(buf, fmt, ...), #expected,
+               ctx .. ' - return status')
+    subtest:is(ffi.string(buf), expected, ctx .. ' - result string')
+  end, ...)
+end
+
+local function i(n)
+  return ffi.cast('int', n)
+end
+
+local function l(n)
+  return ffi.cast('long', n)
+end
+
+local function ll(n)
+  return ffi.cast('long long', n)
+end
+
+local function z(n)
+  return ffi.cast('ptrdiff_t', n)
+end
+
+local function u(n)
+  return ffi.cast('unsigned', n)
+end
+
+local function ul(n)
+  return ffi.cast('unsigned long', n)
+end
+
+local function ull(n)
+  return ffi.cast('unsigned long long', n)
+end
+
+local function uz(n)
+  return ffi.cast('size_t', n)
+end
+
+t('1234567', '%d', i(1234567))
+t('1234567', '%ld', l(1234567))
+t('  1234567', '%9ld', l(1234567))
+t('1234567  ', '%-9ld', l(1234567))
+t('deadbeef', '%x', u(0xdeadbeef))
+t('one two', '%s %s', 'one', 'two')
+t('1.234000', '%f', 1.234)
+t('1.234000e+00', '%e', 1.234)
+t('inf', '%f', 1.0 / 0.0)
+t('-inf', '%f', -1.0 / 0.0)
+t('-0.000000', '%f', tonumber('-0.0'))
+t('%%%', '%%%%%%')
+t('0x87654321', '%p', ffi.cast('char *', 0x87654321))
+t('0x0087654321', '%012p', ffi.cast('char *', 0x87654321))
+t('1234567  ', '%1$*2$ld', l(1234567), i(-9))
+t('1234567  ', '%1$*2$.*3$ld', l(1234567), i(-9), i(5))
+t('1234567  ', '%1$*3$.*2$ld', l(1234567), i(5), i(-9))
+t('1234567  ', '%3$*1$.*2$ld', i(-9), i(5), l(1234567))
+t('1234567', '%1$ld', l(1234567))
+t('  1234567', '%1$*2$ld', l(1234567), i(9))
+t('9 12345 7654321', '%2$ld %1$d %3$lu', i(12345), l(9), ul(7654321))
+t('9 1234567 7654321', '%2$d %1$ld %3$lu', l(1234567), i(9), ul(7654321))
+t('9 1234567 7654321', '%2$d %1$lld %3$lu', ll(1234567), i(9), ul(7654321))
+t('9 12345 7654321', '%2$ld %1$u %3$lu', u(12345), l(9), ul(7654321))
+t('9 1234567 7654321', '%2$d %1$lu %3$lu', ul(1234567), i(9), ul(7654321))
+t('9 1234567 7654321', '%2$d %1$llu %3$lu', ull(1234567), i(9), ul(7654321))
+t('9 deadbeef 7654321', '%2$d %1$x %3$lu', u(0xdeadbeef), i(9), ul(7654321))
+t('9 c 7654321', '%2$ld %1$c %3$lu', i(('c'):byte()), l(9), ul(7654321))
+t('9 hi 7654321', '%2$ld %1$s %3$lu', 'hi', l(9), ul(7654321))
+t('9 0.000000e+00 7654321', '%2$ld %1$e %3$lu', 0.0, l(9), ul(7654321))
+t('two one two', '%2$s %1$s %2$s', 'one', 'two', 'three')
+t('three one two', '%3$s %1$s %2$s', 'one', 'two', 'three')
+t('1234567', '%1$d', i(1234567))
+t('deadbeef', '%1$x', u(0xdeadbeef))
+t('one two', '%1$s %2$s', 'one', 'two')
+t('two one', '%2$s %1$s', 'one', 'two')
+t('1.234000', '%1$f', 1.234)
+t('1.234000e+00', '%1$e', 1.234)
+t('inf', '%1$f', 1.0 / 0.0)
+t('-inf', '%1$f', -1.0 / 0.0)
+t('-0.000000', '%1$f', tonumber('-0.0'))
+t('-1234567 -7654321', '%zd %zd', z(-1234567), z(-7654321))
+t('-7654321 -1234567', '%2$zd %1$zd', z(-1234567), z(-7654321))
+t('1234567 7654321', '%zu %zu', uz(1234567), uz(7654321))
+t('7654321 1234567', '%2$zu %1$zu', uz(1234567), uz(7654321))
+
+test:done(true)
--------------BrS1wroY06bWOxzqj5bHmPml--