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 55DB0173D4C8; Thu, 19 Mar 2026 16:43:14 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 55DB0173D4C8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1773927794; bh=Q7VSILxSm4v776QWjo7O9cx5XXs+GmNXeEu+dptLerE=; 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=I3+OvZdBxbWglGD7VPeDrGKKf8TqOOl34pIpMmHx4sUaobW4vTW7J8Lg6eDV8pOSf W5SkLUSbGxodM0LGj9EYbVifVZDotjXFc4IkBE9hTDXyXiNH4Urj/dPo/h4ZHTp5Bn y82Lx8zHvXX6hkIWRXqTWnyzdYp3d3hVEcikdQxg= Received: from send173.i.mail.ru (send173.i.mail.ru [95.163.59.12]) (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 88C9D39BE3F for ; Thu, 19 Mar 2026 16:43:11 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 88C9D39BE3F Received: by exim-smtp-57656fb979-tbx9c with esmtpa (envelope-from ) id 1w3DeY-00000000IO3-1VXi; Thu, 19 Mar 2026 16:43:10 +0300 Content-Type: multipart/alternative; boundary="------------0o3HZcTyKFznTKFS1ONNLInT" Message-ID: Date: Thu, 19 Mar 2026 16:43:09 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org References: <20260316104853.23901-1-skaplun@tarantool.org> In-Reply-To: <20260316104853.23901-1-skaplun@tarantool.org> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: EEAE043A70213CC8 X-77F55803: 4F1203BC0FB41BD9AF0607DA755D77AF9C8271079F4D450FF2E2EAC0E03D93BC1313CFAB8367EF908E2BE116634AD74D0702AE37701FC9C0C7D0F6C13AE9921318735CDED626604017C7265658D3DAFB6412C2FA36F3267F X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE72FFC9A718DD021A9EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB55337566BA8F050A3F94F1EE8DAB124236A17E2F6068A147E39D4D226A5175A1E71DDECA389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0D9442B0B5983000E8941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B636DA1BED736F9328CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE75B51C8FB0C3E748C731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5C8B72FED5871EB935002B1117B3ED6964323D2F8D8EE0C69B2920F75BA9A967F823CB91A9FED034534781492E4B8EEADAE4FDBF11360AC9BBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D6598783BA420502DFAB4194B39306BEC349F205CB5521213E28A435F4C52A200F45EFFBE08C2A8C99E9B8341EE9D5BE9A0A7874EF7BBE5FB43D2FB17C791312C8C0C7D562A62032F3CA8CD93680B12512CF4C41F94D744909CE2512F26BEC029E55448553D2254B8D95CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVdbVVJCphTR/nTH3ISHJNWw= X-DA7885C5: FE6F55FC55AB8CBAF255D290C0D534F9DCF603BDC1C8AD6B2D4824E8822D9734D74A96F6E768DDA65B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE22E2ED90F21EC41F43AFBB9033C3103360C428547F3667A71EF86D5F70DA33880E41E8EF7A07863ECB274557F927329BE2DDF8182D28ACDB545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit] FFI: Fix constructor index resolution in JIT compiler. 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. --------------0o3HZcTyKFznTKFS1ONNLInT Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi, Sergey, thanks for the patch! LGTM Sergey On 3/16/26 13:48, Sergey Kaplun wrote: > From: Mike Pall > > Reported by Vladimir Davydov and Sergey Kaplun. > > (cherry picked from commit 02e29995581cb568a784a9b996cd5e9139cd0737) > > This patch is a follow-up for the commit > 6cee1333ef2b340e1b23e3051b9f433fc803d2ff ("FFI: Resolve metamethods for > constructors, too."). It allows the use of metamethods of the objects to > be called on their constructors. Unfortunately, the JIT part isn't > updated and may cause inconsistencies since it is indexing the field of > the structure referenced by the given CType. > > This patch makes the semantics of JIT the same as for the VM. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#12134 > --- > > Branch:https://github.com/tarantool/luajit/tree/skaplun/lj-1441-record-constructor-metamethod > Related issues: > *https://github.com/LuaJIT/LuaJIT/issues/1441 > *https://github.com/tarantool/tarantool/issues/12134 > > src/lj_crecord.c | 2 + > ...441-record-constructor-metamethod.test.lua | 79 +++++++++++++++++++ > 2 files changed, 81 insertions(+) > create mode 100644 test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua > > diff --git a/src/lj_crecord.c b/src/lj_crecord.c > index b016eaec..d486ee85 100644 > --- a/src/lj_crecord.c > +++ b/src/lj_crecord.c > @@ -881,6 +881,8 @@ again: > } > J->base[0] = lj_ir_kint(J, (int32_t)fct->size); > return; /* Interpreter will throw for newindex. */ > + } else if (cd && cd->ctypeid == CTID_CTYPEID) { > + /* Only resolve constants and metamethods for constructors. */ > } else if (ctype_isbitfield(fct->info)) { > if (ofs) > ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs)); > diff --git a/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua b/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua > new file mode 100644 > index 00000000..370e49e0 > --- /dev/null > +++ b/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua > @@ -0,0 +1,79 @@ > +local tap = require('tap') > + > +-- The test file to demonstrate LuaJIT's incorrect recording of > +-- the __index metamethod invocation on the cdata's constructor. > +-- See also:https://github.com/LuaJIT/LuaJIT/issues/1441. > + > +local test = tap.test('lj-1441-record-constructor-metamethod'):skipcond({ > + ['Test requires JIT enabled'] = not jit.status(), > +}) > + > +test:plan(3) > + > +local ffi = require('ffi') > + > +ffi.cdef[[ > + struct test_recursive {int a;}; > + struct test_finite {int a;}; > +]] > + > +local recursive_t = ffi.typeof('struct test_recursive') > +local finite_t = ffi.typeof('struct test_finite') > + > +local MAGIC = 42 > + > +local function new_recursive() > + return ffi.new(recursive_t, 0) > +end > + > +local function new_finite() > + return ffi.new(finite_t, 0) > +end > + > +local function index_func_recursive(v) > + -- Should raise an error (stack overflow). > + return ffi.typeof(v).a > +end > + > +-- Special object to invoke metamethod on the cdata. > +local one_more_step = new_finite() > + > +local function index_func_finite(v) > + if v == one_more_step then > + -- XXX: Avoid tail-calls. > + local x = ffi.typeof(v).a > + return x > + else > + return MAGIC > + end > +end > + > +ffi.metatype(recursive_t, { > + __index = index_func_recursive, > +}) > + > +ffi.metatype(finite_t, { > + __index = index_func_finite, > +}) > + > +jit.opt.start('hotloop=1') > + > +-- Test the recursive call. Expect the stack overflow error. > +local o_rec = new_recursive() > +local result, errmsg > +for _ = 1, 4 do > + result, errmsg = pcall(index_func_recursive, o_rec) > +end > + > +test:ok(not result, 'correct status for recursive call') > +test:like(errmsg, 'stack overflow', 'correct error message for recursive call') > + > +-- Test the finite call. Expect the specific value. > +local got > +for _ = 1, 4 do > + got = index_func_finite(one_more_step) > +end > + > +test:is(got, MAGIC, 'correct result value on trace for finite call') > + > +test:done(true) --------------0o3HZcTyKFznTKFS1ONNLInT Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit

Hi, Sergey,

thanks for the patch! LGTM

Sergey

On 3/16/26 13:48, Sergey Kaplun wrote:
From: Mike Pall <mike>

Reported by Vladimir Davydov and Sergey Kaplun.

(cherry picked from commit 02e29995581cb568a784a9b996cd5e9139cd0737)

This patch is a follow-up for the commit
6cee1333ef2b340e1b23e3051b9f433fc803d2ff ("FFI: Resolve metamethods for
constructors, too."). It allows the use of metamethods of the objects to
be called on their constructors. Unfortunately, the JIT part isn't
updated and may cause inconsistencies since it is indexing the field of
the structure referenced by the given CType.

This patch makes the semantics of JIT the same as for the VM.

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

Part of tarantool/tarantool#12134
---

Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1441-record-constructor-metamethod
Related issues:
* https://github.com/LuaJIT/LuaJIT/issues/1441
* https://github.com/tarantool/tarantool/issues/12134

 src/lj_crecord.c                              |  2 +
 ...441-record-constructor-metamethod.test.lua | 79 +++++++++++++++++++
 2 files changed, 81 insertions(+)
 create mode 100644 test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua

diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index b016eaec..d486ee85 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -881,6 +881,8 @@ again:
 	  }
 	  J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
 	  return;  /* Interpreter will throw for newindex. */
+	} else if (cd && cd->ctypeid == CTID_CTYPEID) {
+	  /* Only resolve constants and metamethods for constructors. */
 	} else if (ctype_isbitfield(fct->info)) {
 	  if (ofs)
 	    ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
diff --git a/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua b/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua
new file mode 100644
index 00000000..370e49e0
--- /dev/null
+++ b/test/tarantool-tests/lj-1441-record-constructor-metamethod.test.lua
@@ -0,0 +1,79 @@
+local tap = require('tap')
+
+-- The test file to demonstrate LuaJIT's incorrect recording of
+-- the __index metamethod invocation on the cdata's constructor.
+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1441.
+
+local test = tap.test('lj-1441-record-constructor-metamethod'):skipcond({
+  ['Test requires JIT enabled'] = not jit.status(),
+})
+
+test:plan(3)
+
+local ffi = require('ffi')
+
+ffi.cdef[[
+  struct test_recursive {int a;};
+  struct test_finite {int a;};
+]]
+
+local recursive_t = ffi.typeof('struct test_recursive')
+local finite_t = ffi.typeof('struct test_finite')
+
+local MAGIC = 42
+
+local function new_recursive()
+  return ffi.new(recursive_t, 0)
+end
+
+local function new_finite()
+  return ffi.new(finite_t, 0)
+end
+
+local function index_func_recursive(v)
+  -- Should raise an error (stack overflow).
+  return ffi.typeof(v).a
+end
+
+-- Special object to invoke metamethod on the cdata<ctypeid>.
+local one_more_step = new_finite()
+
+local function index_func_finite(v)
+  if v == one_more_step then
+    -- XXX: Avoid tail-calls.
+    local x = ffi.typeof(v).a
+    return x
+  else
+    return MAGIC
+  end
+end
+
+ffi.metatype(recursive_t, {
+  __index = index_func_recursive,
+})
+
+ffi.metatype(finite_t, {
+  __index = index_func_finite,
+})
+
+jit.opt.start('hotloop=1')
+
+-- Test the recursive call. Expect the stack overflow error.
+local o_rec = new_recursive()
+local result, errmsg
+for _ = 1, 4 do
+  result, errmsg = pcall(index_func_recursive, o_rec)
+end
+
+test:ok(not result, 'correct status for recursive call')
+test:like(errmsg, 'stack overflow', 'correct error message for recursive call')
+
+-- Test the finite call. Expect the specific value.
+local got
+for _ = 1, 4 do
+  got = index_func_finite(one_more_step)
+end
+
+test:is(got, MAGIC, 'correct result value on trace for finite call')
+
+test:done(true)
--------------0o3HZcTyKFznTKFS1ONNLInT--