Merge commit '73b80079143b1f4785af08a554c4c0715a398133' into 1.5

This commit is contained in:
Théophile Diot 2024-08-30 11:09:26 +02:00
commit 681f49a420
No known key found for this signature in database
GPG key ID: FA995104A0BA376A
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"