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 D7ED6F16FB6; Wed, 22 Jan 2025 14:58:53 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org D7ED6F16FB6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1737547133; bh=cfqIEW15J0Ezl8JJR7Pot03kGnPCFlri/EcvT5WHg/g=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=GvZ7TXFMaaNXJ6D/a7TgSW5AzY+1CA+9cML7aaUG//3QOgkIWtFLy7r/Y+aJXuz74 HtiHg+EZgcjdb04xlbY1t1fcH0M27gI418SKAhAWkiWdqEhUx9ERI+ChVRuyCZ/y8B Ej2YfgM1lMjLMw6tzFy4pW7bx0DGRXIMe41Sm+tA= Received: from send127.i.mail.ru (send127.i.mail.ru [89.221.237.222]) (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 EE446406BF8 for ; Wed, 22 Jan 2025 14:58:51 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org EE446406BF8 Received: by exim-smtp-6758d5575c-2pqjr with esmtpa (envelope-from ) id 1taZNh-00000000DzR-0Eq4; Wed, 22 Jan 2025 14:58:49 +0300 To: Sergey Bronnikov Date: Wed, 22 Jan 2025 14:58:10 +0300 Message-ID: <20250122115810.2160-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.47.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9F92BE5667526BA91771AC702472B402285C611E5AAF235A4182A05F5380850409D32067EF62D9D293DE06ABAFEAF6705D1BD4912E4BEE4038999F92BC62AE05D142D0AB2E9B78576 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE75C0AD7D016C066E3C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE73134AF198FC69682EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38BC08E230531AC9C90F40D6C6E7392E2401EE9674FABCCE366C8E0D4125F236A28A471835C12D1D9774AD6D5ED66289B5278DA827A17800CE764603B5C71CE8B8F9FA2833FD35BB23D2EF20D2F80756B5F868A13BD56FB6657A471835C12D1D977725E5C173C3A84C34C82C86BFC697D19117882F4460429728AD0CFFFB425014E868A13BD56FB6657E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F79006373BC478629CBEC79DEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-C1DE0DAB: 0D63561A33F958A5A784E9E8943BA6DB5002B1117B3ED6968813B81736A657C3E41E333F9D1358D5823CB91A9FED034534781492E4B8EEAD81B3E0F64AD3EF57C79554A2A72441328621D336A7BC284946AD531847A6065A17B107DEF921CE79BDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFDC79115DD296575FFB378169E90A8F23BD7125E2DD666B3AEF3DEC1576FAD26B68A36B291CE9B2EBB8737C0BE87C275EE8C970E21B9537F71045FF735CC35E1BC7BE70C7FC7E16545F4332CA8FE04980913E6812662D5F2A5EAB5682573093F7837F15F2B5E4A70B33F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojbL9S8ysBdXi8/clcm+NzuBpC19xm/6eX X-DA7885C5: 9DDB69283E515B36F255D290C0D534F92487C9CDF08F847108F8844099C9F00D3FC81DD774B46E745B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F739381B31377CF4CA2197E943EBCB941AFCFE3A2D9B8D2C0FCD0FE27E821F6AF95F6E49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: [Tarantool-patches] [PATCH v2 luajit] FFI: Add missing coercion when recording 64-bit bit.*(). 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 Thanks to Peter Cawley. (cherry picked from commit 304da39cc5ee43491f7b1f4e0c9c52d477ce0d98) Before the patch, with the missed coercion from string, there is the cast to `i64` from `p64`, where the last one is the string address. This leads to an incorrect result of the bit operation. This patch adds the missing coercion everywhere for bit operations recording. Only the `recff_bit64_nary()` is affected, since all other routines have the corresponding type check and cast emitting if necessary. However, for the consistency, all functions have the same checking routine `crec_bit64_arg()` now. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#10709 --- Changes in the v2: * Fixed several typos in the comments. * Added the clarification why the commit adds the test only for the bor (`recfh_bit64_nary()`) operation. Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1252-missing-bit64-coercion Related issues: * https://github.com/tarantool/tarantool/issues/10709 * https://github.com/LuaJIT/LuaJIT/issues/1252 src/Makefile.dep.original | 2 +- src/lj_crecord.c | 31 +++++++++++++------ .../lj-1252-missing-bit64-coercion.test.lua | 30 ++++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 test/tarantool-tests/lj-1252-missing-bit64-coercion.test.lua diff --git a/src/Makefile.dep.original b/src/Makefile.dep.original index 53426a7e..b96de1b9 100644 --- a/src/Makefile.dep.original +++ b/src/Makefile.dep.original @@ -96,7 +96,7 @@ lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_cdata.h lj_cparse.h lj_cconv.h lj_carith.h lj_clib.h lj_ccall.h \ lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \ - lj_crecord.h lj_strfmt.h + lj_crecord.h lj_strfmt.h lj_strscan.h lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \ lj_ccallback.h lj_buf.h diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 81ae6dfa..dcb90216 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -32,6 +32,7 @@ #include "lj_crecord.h" #include "lj_dispatch.h" #include "lj_strfmt.h" +#include "lj_strscan.h" /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) @@ -1782,11 +1783,21 @@ static CTypeID crec_bit64_type(CTState *cts, cTValue *tv) return 0; /* Use regular 32 bit ops. */ } +static TRef crec_bit64_arg(jit_State *J, CType *d, TRef sp, TValue *sval) +{ + if (LJ_UNLIKELY(tref_isstr(sp))) { + if (lj_strscan_num(strV(sval), sval)) { + sp = emitir(IRTG(IR_STRTO, IRT_NUM), sp, 0); + } /* else: interpreter will throw. */ + } + return crec_ct_tv(J, d, 0, sp, sval); +} + void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd) { CTState *cts = ctype_ctsG(J2G(J)); - TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, - J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), + J->base[0], &rd->argv[0]); if (!tref_isinteger(tr)) tr = emitconv(tr, IRT_INT, tref_type(tr), 0); J->base[0] = tr; @@ -1797,7 +1808,7 @@ int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd) CTState *cts = ctype_ctsG(J2G(J)); CTypeID id = crec_bit64_type(cts, &rd->argv[0]); if (id) { - TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0); J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); return 1; @@ -1817,9 +1828,9 @@ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd) if (id) { CType *ct = ctype_get(cts, id); uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64); - TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ct, J->base[0], &rd->argv[0]); for (i = 1; J->base[i] != 0; i++) { - TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]); + TRef tr2 = crec_bit64_arg(J, ct, J->base[i], &rd->argv[i]); tr = emitir(ot, tr, tr2); } J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); @@ -1834,15 +1845,15 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd) CTypeID id; TRef tsh = 0; if (J->base[0] && tref_iscdata(J->base[1])) { - tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, - J->base[1], &rd->argv[1]); + tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), + J->base[1], &rd->argv[1]); if (!tref_isinteger(tsh)) tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0); J->base[1] = tsh; } id = crec_bit64_type(cts, &rd->argv[0]); if (id) { - TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); uint32_t op = rd->data; if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]); if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && @@ -1872,7 +1883,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) CTypeID id2 = 0; n = (int32_t)lj_carith_check64(J->L, 2, &id2); if (id2) - trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]); + trsf = crec_bit64_arg(J, ctype_get(cts, CTID_INT32), trsf, &rd->argv[1]); else trsf = lj_opt_narrow_tobit(J, trsf); emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */ @@ -1883,7 +1894,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) if ((uint32_t)n > 254) n = 254; sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); if (id) { - tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); if (n < 16) tr = emitir(IRT(IR_BAND, IRT_U64), tr, lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1)); diff --git a/test/tarantool-tests/lj-1252-missing-bit64-coercion.test.lua b/test/tarantool-tests/lj-1252-missing-bit64-coercion.test.lua new file mode 100644 index 00000000..e193fa0c --- /dev/null +++ b/test/tarantool-tests/lj-1252-missing-bit64-coercion.test.lua @@ -0,0 +1,30 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT incorrect recording of +-- `bit` library with needed coercion from string. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1252. + +local test = tap.test('lj-1252-missing-bit64-coercion'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(1) + +-- Simplify the `jit.dump()` output. +local bor = bit.bor + +jit.opt.start('hotloop=1') + +-- Before the patch, with the missed coercion from string, there +-- is the cast to `i64` from `p64`, where the last one is the +-- string address. This leads to an incorrect result of the bit +-- operation. + +local results = {} +for i = 1, 4 do + results[i] = bor('0', 0LL) +end + +test:samevalues(results, 'correct recording of the bit operation with coercion') + +test:done(true) -- 2.47.1