Squashed 'src/deps/src/luajit/' changes from dc397b66e6..33d6b04681

33d6b04681 Merge branch 'v2.1' into v2.1-agentzh
ae4735f621 Reflect override of INSTALL_LJLIBD in package.path.
6f834087d0 ARM64: Use movi to materialize FP constants.
2d54213e7c Add more FOLD rules for integer conversions.
833600390c Merge branch 'master' into v2.1
86e7123bb1 Different fix for partial snapshot restore due to stack overflow.
7369eff67d Fix IR_ABC hoisting.
3bdc6498c4 Limit CSE for IR_CARG to fix loop optimizations.
a07ece864e Merge branch 'v2.1' into v2.1-agentzh
04dca7911e Call math.randomseed() without arguments to seed from system entropy.
7421a1b33c Restore state when recording __concat metamethod throws an error.
510f88d468 Add build flag LUAJIT_DISABLE_TAILCALL to disable tailcall generation.
444c8ff19a Clarify that lj_buf_shrink() does not keep any buffer data.
747fc02eb9 OSX: Fix installed luajit.pc.
8038430110 Merge branch 'master' into v2.1
7a608e4425 FFI: Fix various issues in recff_cdata_arith.
f602f0154b Fix predict_next() in parser (for real now).
f2a1cd4328 FFI: Fix __tostring metamethod access to enum cdata value.
0f8b878e2f Fix typo.
6885efb73e Merge branch 'master' into v2.1
811c5322c8 Handle partial snapshot restore due to stack overflow.

git-subtree-dir: src/deps/src/luajit
git-subtree-split: 33d6b04681d2f079a6d013988a426a841c52e29e
This commit is contained in:
Théophile Diot 2024-08-30 11:09:26 +02:00
parent f159ed96b9
commit 73b8007914
18 changed files with 121 additions and 30 deletions

View file

@ -41,7 +41,7 @@ INSTALL_SHARE= $(DPREFIX)/share
INSTALL_DEFINC= $(DPREFIX)/include/luajit-$(MMVERSION)
INSTALL_INC= $(INSTALL_DEFINC)
INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(MMVERSION)
export INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(MMVERSION)
INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit
INSTALL_LMODD= $(INSTALL_SHARE)/lua
INSTALL_LMOD= $(INSTALL_LMODD)/$(ABIVER)
@ -114,6 +114,7 @@ ifeq (Darwin,$(TARGET_SYS))
INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1)
INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2)
LDCONFIG= :
SED_PC+= -e "s| -Wl,-E||"
endif
##############################################################################

View file

@ -265,7 +265,7 @@ and let the GC do its work.
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
the PRNG results is much superior compared to the standard Lua
implementation, which uses the platform-specific ANSI rand().
implementation, which uses the platform-specific ANSI <tt>rand()</tt>.
</p>
<p>
The PRNG generates the same sequences from the same seeds on all
@ -276,6 +276,10 @@ It's correctly scaled up and rounded for <tt>math.random(n&nbsp;[,m])</tt> to
preserve uniformity.
</p>
<p>
Call <tt>math.randomseed()</tt> without any arguments to seed it from
system entropy.
</p>
<p>
Important: Neither this nor any other PRNG based on the simplistic
<tt>math.random()</tt> API is suitable for cryptographic use.
</p>

View file

@ -303,6 +303,9 @@ endif
ifneq (,$(LMULTILIB))
TARGET_XCFLAGS+= -DLUA_LMULTILIB=\"$(LMULTILIB)\"
endif
ifneq (,$(INSTALL_LJLIBD))
TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\"
endif
##############################################################################
# Target system detection.

View file

@ -32,7 +32,8 @@ lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_prng.h lj_libdef.h
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_vm.h lj_prng.h \
lj_libdef.h
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
lj_libdef.h

View file

@ -513,7 +513,7 @@ typedef struct {
o.sym_entry.strx = 1
ffi.copy(o.space+1, symname)
-- Write Macho-O object file.
-- Write Mach-O object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, mach_size))
bcsave_tail(fp, output, s)

View file

@ -658,6 +658,10 @@ local map_datafp = { -- Data processing, SIMD and FP.
}
}
}
},
{ -- 010
shift = 0, mask = 0x81f8fc00,
[0x100e400] = "moviDdG"
}
}
@ -832,6 +836,20 @@ local function parse_fpimm8(op)
return sign * frac * 2^exp
end
local function decode_fpmovi(op)
local lo = rshift(op, 5)
local hi = rshift(op, 9)
lo = bor(band(lo, 1) * 0xff, band(lo, 2) * 0x7f80, band(lo, 4) * 0x3fc000,
band(lo, 8) * 0x1fe00000)
hi = bor(band(hi, 1) * 0xff, band(hi, 0x80) * 0x1fe,
band(hi, 0x100) * 0xff00, band(hi, 0x200) * 0x7f8000)
if hi ~= 0 then
return fmt_hex32(hi)..tohex(lo)
else
return fmt_hex32(lo)
end
end
local function prefer_bfx(sf, uns, imms, immr)
if imms < immr or imms == 31 or imms == 63 then
return false
@ -1131,6 +1149,8 @@ local function disass_ins(ctx)
x = 0
elseif p == "F" then
x = parse_fpimm8(op)
elseif p == "G" then
x = "#0x"..decode_fpmovi(op)
elseif p == "g" or p == "f" or p == "x" or p == "w" or
p == "d" or p == "s" then
-- These are handled in D/N/M/A.

View file

@ -305,7 +305,7 @@ LJLIB_CF(ffi_meta___tostring)
p = *(void **)p;
} else if (ctype_isenum(ct->info)) {
msg = "cdata<%s>: %d";
p = (void *)(uintptr_t)*(uint32_t **)p;
p = (void *)(uintptr_t)*(uint32_t *)p;
} else {
if (ctype_isptr(ct->info)) {
p = cdata_getptr(p, ct->size);

View file

@ -13,6 +13,7 @@
#include "lualib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_lib.h"
#include "lj_vm.h"
#include "lj_prng.h"
@ -183,7 +184,10 @@ LJLIB_PUSH(top-2) /* Upvalue holds userdata with PRNGState. */
LJLIB_CF(math_randomseed)
{
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
random_seed(rs, lj_lib_checknum(L, 1));
if (L->base != L->top)
random_seed(rs, lj_lib_checknum(L, 1));
else if (!lj_prng_seed_secure(rs))
lj_err_caller(L, LJ_ERR_PRNGSD);
return 0;
}

View file

@ -92,10 +92,8 @@ void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
char *b = sb->b;
MSize osz = (MSize)(sb->e - b);
if (osz > 2*LJ_MIN_SBUF) {
MSize n = (MSize)(sb->w - b);
b = lj_mem_realloc(L, b, osz, (osz >> 1));
sb->b = b;
sb->w = b + n;
sb->w = sb->b = b; /* Not supposed to keep data across shrinks. */
sb->e = b + (osz >> 1);
}
lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");

View file

@ -1498,7 +1498,8 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
{
CTState *cts = ctype_ctsG(J2G(J));
CTState *cts = ctype_cts(J->L);
MMS mm = (MMS)rd->data;
TRef sp[2];
CType *s[2];
MSize i;
@ -1548,6 +1549,8 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
}
}
} else if (tref_isnil(tr)) {
if (!(mm == MM_len || mm == MM_eq || mm == MM_lt || mm == MM_le))
lj_trace_err(J, LJ_TRERR_BADTYPE);
tr = lj_ir_kptr(J, NULL);
ct = ctype_get(cts, CTID_P_VOID);
} else if (tref_isinteger(tr)) {
@ -1566,12 +1569,12 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
ct = ctype_child(cts, cct);
tr = lj_ir_kint(J, (int32_t)ofs);
} else { /* Interpreter will throw or return false. */
ct = ctype_get(cts, CTID_P_VOID);
lj_trace_err(J, LJ_TRERR_BADTYPE);
}
} else if (ctype_isptr(ct->info)) {
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
} else {
ct = ctype_get(cts, CTID_P_VOID);
lj_trace_err(J, LJ_TRERR_BADTYPE);
}
} else if (!tref_isnum(tr)) {
tr = 0;
@ -1583,7 +1586,6 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
}
{
TRef tr;
MMS mm = (MMS)rd->data;
if ((mm == MM_len || mm == MM_concat ||
(!(tr = crec_arith_int64(J, sp, s, mm)) &&
!(tr = crec_arith_ptr(J, sp, s, mm)))) &&

View file

@ -66,6 +66,17 @@ static uint32_t emit_isfpk64(uint64_t n)
return ~0u;
}
static uint32_t emit_isfpmovi(uint64_t n)
{
/* Is every byte either 0x00 or 0xff? */
if ((n & U64x(01010101,01010101)) * 0xff != n) return 0;
/* Form 8-bit value by taking one bit from each byte. */
n &= U64x(80402010,08040201);
n = (n * U64x(01010101,01010101)) >> 56;
/* Split into the format expected by movi. */
return ((n & 0xe0) << 6) | 0x700 | (n & 0x1f);
}
/* -- Emit basic instructions --------------------------------------------- */
static void emit_dnma(ASMState *as, A64Ins ai, Reg rd, Reg rn, Reg rm, Reg ra)
@ -300,6 +311,9 @@ static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
if (fpk != ~0u) {
emit_d(as, A64I_FMOV_DI | A64F_FP8(fpk), (r & 31));
return;
} else if ((fpk = emit_isfpmovi(*k))) {
emit_d(as, A64I_MOVI_DI | (fpk << 5), (r & 31));
return;
}
}
ofs = glofs(as, k);

View file

@ -79,6 +79,7 @@ ERRDEF(SETFENV, LUA_QL("setfenv") " cannot change environment of given object")
ERRDEF(CORUN, "cannot resume running coroutine")
ERRDEF(CODEAD, "cannot resume dead coroutine")
ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
ERRDEF(PRNGSD, "PRNG seeding failed")
ERRDEF(TABINS, "wrong number of arguments to " LUA_QL("insert"))
ERRDEF(TABCAT, "invalid value (%s) at index %d in table for " LUA_QL("concat"))
ERRDEF(TABSORT, "invalid order function for sorting")

View file

@ -1135,7 +1135,7 @@ LJFOLDF(shortcut_conv_num_int)
}
LJFOLD(CONV CONV IRCONV_INT_NUM) /* _INT */
LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32*/
LJFOLD(CONV CONV IRCONV_U32_NUM) /* _U32 */
LJFOLDF(simplify_conv_int_num)
{
/* Fold even across PHI to avoid expensive num->int conversions in loop. */
@ -1170,8 +1170,10 @@ LJFOLDF(simplify_conv_i64_num)
LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT or _U32 */
LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT or _U32 */
LJFOLD(CONV CONV IRCONV_INT_U32) /* _INT or _U32 */
LJFOLD(CONV CONV IRCONV_U32_I64) /* _INT or _U32 */
LJFOLD(CONV CONV IRCONV_U32_U64) /* _INT or _U32 */
LJFOLD(CONV CONV IRCONV_U32_INT) /* _INT or _U32 */
LJFOLDF(simplify_conv_int_i64)
{
int src;
@ -1216,14 +1218,13 @@ LJFOLDF(simplify_tobit_conv)
return NEXTFOLD;
}
/* Shortcut floor/ceil/round + IRT_NUM <- IRT_INT/IRT_U32 conversion. */
/* Shortcut floor/ceil/trunc + IRT_NUM <- integer conversion. */
LJFOLD(FPMATH CONV IRFPM_FLOOR)
LJFOLD(FPMATH CONV IRFPM_CEIL)
LJFOLD(FPMATH CONV IRFPM_TRUNC)
LJFOLDF(simplify_floor_conv)
{
if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT ||
(fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
if ((uint32_t)(fleft->op2 & IRCONV_SRCMASK) - (uint32_t)IRT_I8 <= (uint32_t)(IRT_U64 - IRT_U8))
return LEFTFOLD;
return NEXTFOLD;
}
@ -1935,9 +1936,10 @@ LJFOLDF(abc_k)
LJFOLD(ABC any any)
LJFOLDF(abc_invar)
{
/* Invariant ABC marked as PTR. Drop if op1 is invariant, too. */
/* Invariant ABC marked as P32 or U32. Drop if op1 is invariant too. */
if (!irt_isint(fins->t) && fins->op1 < J->chain[IR_LOOP] &&
!irt_isphi(IR(fins->op1)->t))
(irt_isu32(fins->t) ||
(!irref_isk(fins->op1) && !irt_isphi(IR(fins->op1)->t))))
return DROPFOLD;
return NEXTFOLD;
}
@ -2485,6 +2487,17 @@ LJFOLD(CNEW any any)
LJFOLD(XSNEW any any)
LJFOLDX(lj_ir_emit)
/* -- Miscellaneous ------------------------------------------------------- */
LJFOLD(CARG any any)
LJFOLDF(cse_carg)
{
TRef tr = lj_opt_cse(J);
if (tref_ref(tr) < J->chain[IR_LOOP]) /* CSE across loop? */
return EMITFOLD; /* Raw emit. Assumes fins is left intact by CSE. */
return tr;
}
/* ------------------------------------------------------------------------ */
/* Every entry in the generated hash table is a 32 bit pattern:

View file

@ -2340,11 +2340,15 @@ static void parse_return(LexState *ls)
BCReg nret = expr_list(ls, &e);
if (nret == 1) { /* Return one result. */
if (e.k == VCALL) { /* Check for tail call. */
#ifdef LUAJIT_DISABLE_TAILCALL
goto notailcall;
#else
BCIns *ip = bcptr(fs, &e);
/* It doesn't pay off to add BC_VARGT just for 'return ...'. */
if (bc_op(*ip) == BC_VARG) goto notailcall;
fs->pc--;
ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
#endif
} else { /* Can return the result from any register. */
ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
}
@ -2518,11 +2522,9 @@ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
*/
static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
{
BCIns ins;
BCIns ins = fs->bcbase[pc].ins;
GCstr *name;
cTValue *o;
if (pc >= fs->bclim) return 0;
ins = fs->bcbase[pc].ins;
switch (bc_op(ins)) {
case BC_MOV:
if (bc_d(ins) >= fs->nactvar) return 0;
@ -2571,7 +2573,7 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
assign_adjust(ls, 3, expr_list(ls, &e), &e);
/* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
bcreg_bump(fs, 3+ls->fr2);
isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
isnext = (nvars <= 5 && fs->pc > exprpc && predict_next(ls, fs, exprpc));
var_add(ls, 3); /* Hidden control variables. */
lex_check(ls, TK_do);
loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);

View file

@ -1025,7 +1025,9 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
J->L->base = b + baseadj;
copyTV(J->L, b-(2<<LJ_FR2), &save);
}
if (tr) { /* Store final result. */
if (tr >= 0xffffff00) {
lj_err_throw(J->L, -(int32_t)tr); /* Propagate errors. */
} else if (tr) { /* Store final result. */
BCReg dst = bc_a(*(frame_contpc(frame)-1));
J->base[dst] = tr;
if (dst >= J->maxslot) {
@ -1393,12 +1395,13 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
/* Runtime value for stop of loop is within bounds? */
if ((uint64_t)stop + ofs < (uint64_t)asize) {
/* Emit invariant bounds check for stop. */
emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop :
uint32_t abc = IRTG(IR_ABC, tref_isk(asizeref) ? IRT_U32 : IRT_P32);
emitir(abc, asizeref, ofs == 0 ? J->scev.stop :
emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
/* Emit invariant bounds check for start, if not const or negative. */
if (!(J->scev.dir && J->scev.start &&
(int64_t)IR(J->scev.start)->i + ofs >= 0))
emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey);
emitir(abc, asizeref, ikey);
return;
}
}
@ -2075,12 +2078,27 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
/* -- Concatenation ------------------------------------------------------- */
typedef struct RecCatDataCP {
jit_State *J;
RecordIndex *ix;
} RecCatDataCP;
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
{
RecCatDataCP *rcd = (RecCatDataCP *)ud;
UNUSED(L); UNUSED(dummy);
rec_mm_arith(rcd->J, rcd->ix, MM_concat); /* Call __concat metamethod. */
return NULL;
}
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
{
TRef *top = &J->base[topslot];
TValue savetv[5+LJ_FR2];
BCReg s;
RecordIndex ix;
RecCatDataCP rcd;
int errcode;
lj_assertJ(baseslot < topslot, "bad CAT arg");
for (s = baseslot; s <= topslot; s++)
(void)getslot(J, s); /* Ensure all arguments have a reference. */
@ -2116,8 +2134,11 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
ix.tab = top[-1];
ix.key = top[0];
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
rcd.J = J;
rcd.ix = &ix;
errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp);
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
if (errcode) return (TRef)(-errcode);
return 0; /* No result yet. */
}
@ -2440,6 +2461,8 @@ void lj_record_ins(jit_State *J)
case BC_CAT:
rc = rec_cat(J, rb, rc);
if (rc >= 0xffffff00)
lj_err_throw(J->L, -(int32_t)rc); /* Propagate errors. */
break;
/* -- Constant and move ops --------------------------------------------- */

View file

@ -957,7 +957,8 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
lua_State *L = J->L;
/* Set interpreter PC to the next PC to get correct error messages. */
setcframe_pc(cframe_raw(L->cframe), pc+1);
setcframe_pc(L->cframe, pc+1);
setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
/* Make sure the stack is big enough for the slots from the snapshot. */
if (LJ_UNLIKELY(L->base + snap->topslot >= tvref(L->maxstack))) {

View file

@ -320,6 +320,7 @@ typedef enum A64Ins {
A64I_FMOV_R_D = 0x9e660000,
A64I_FMOV_D_R = 0x9e670000,
A64I_FMOV_DI = 0x1e601000,
A64I_MOVI_DI = 0x2f000400,
} A64Ins;
#define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR)

View file

@ -37,7 +37,6 @@
#endif
#define LUA_LROOT "/usr/local"
#define LUA_LUADIR "/lua/5.1/"
#define LUA_LJDIR "/luajit-2.1/"
#ifdef LUA_ROOT
#define LUA_JROOT LUA_ROOT
@ -51,7 +50,11 @@
#define LUA_RCPATH
#endif
#define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua"
#ifndef LUA_LJDIR
#define LUA_LJDIR LUA_JROOT "/share/luajit-2.1"
#endif
#define LUA_JPATH ";" LUA_LJDIR "/?.lua"
#define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR
#define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR
#define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua"