mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-20 05:53:26 +00:00
Merge branch 'LuaJIT:v2.1' into dontstarve
This commit is contained in:
commit
876ca620b8
1
Makefile
1
Makefile
@ -114,6 +114,7 @@ ifeq (Darwin,$(TARGET_SYS))
|
|||||||
INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1)
|
INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1)
|
||||||
INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2)
|
INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2)
|
||||||
LDCONFIG= :
|
LDCONFIG= :
|
||||||
|
SED_PC+= -e "s| -Wl,-E||"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
@ -265,7 +265,7 @@ and let the GC do its work.
|
|||||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||||
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
|
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
|
||||||
the PRNG results is much superior compared to the standard Lua
|
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>
|
||||||
<p>
|
<p>
|
||||||
The PRNG generates the same sequences from the same seeds on all
|
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 [,m])</tt> to
|
|||||||
preserve uniformity.
|
preserve uniformity.
|
||||||
</p>
|
</p>
|
||||||
<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
|
Important: Neither this nor any other PRNG based on the simplistic
|
||||||
<tt>math.random()</tt> API is suitable for cryptographic use.
|
<tt>math.random()</tt> API is suitable for cryptographic use.
|
||||||
</p>
|
</p>
|
||||||
|
@ -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_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
|
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 \
|
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 \
|
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_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
|
||||||
lj_libdef.h
|
lj_libdef.h
|
||||||
|
@ -511,7 +511,7 @@ typedef struct {
|
|||||||
o.sym_entry.strx = 1
|
o.sym_entry.strx = 1
|
||||||
ffi.copy(o.space+1, symname)
|
ffi.copy(o.space+1, symname)
|
||||||
|
|
||||||
-- Write Macho-O object file.
|
-- Write Mach-O object file.
|
||||||
local fp = savefile(output, "wb")
|
local fp = savefile(output, "wb")
|
||||||
fp:write(ffi.string(o, mach_size))
|
fp:write(ffi.string(o, mach_size))
|
||||||
bcsave_tail(fp, output, s)
|
bcsave_tail(fp, output, s)
|
||||||
|
@ -305,7 +305,7 @@ LJLIB_CF(ffi_meta___tostring)
|
|||||||
p = *(void **)p;
|
p = *(void **)p;
|
||||||
} else if (ctype_isenum(ct->info)) {
|
} else if (ctype_isenum(ct->info)) {
|
||||||
msg = "cdata<%s>: %d";
|
msg = "cdata<%s>: %d";
|
||||||
p = (void *)(uintptr_t)*(uint32_t **)p;
|
p = (void *)(uintptr_t)*(uint32_t *)p;
|
||||||
} else {
|
} else {
|
||||||
if (ctype_isptr(ct->info)) {
|
if (ctype_isptr(ct->info)) {
|
||||||
p = cdata_getptr(p, ct->size);
|
p = cdata_getptr(p, ct->size);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
|
|
||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
|
#include "lj_err.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
#include "lj_vm.h"
|
#include "lj_vm.h"
|
||||||
#include "lj_prng.h"
|
#include "lj_prng.h"
|
||||||
@ -183,7 +184,10 @@ LJLIB_PUSH(top-2) /* Upvalue holds userdata with PRNGState. */
|
|||||||
LJLIB_CF(math_randomseed)
|
LJLIB_CF(math_randomseed)
|
||||||
{
|
{
|
||||||
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
|
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
|
||||||
|
if (L->base != L->top)
|
||||||
random_seed(rs, lj_lib_checknum(L, 1));
|
random_seed(rs, lj_lib_checknum(L, 1));
|
||||||
|
else if (!lj_prng_seed_secure(rs))
|
||||||
|
lj_err_caller(L, LJ_ERR_PRNGSD);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +92,8 @@ void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
|
|||||||
char *b = sb->b;
|
char *b = sb->b;
|
||||||
MSize osz = (MSize)(sb->e - b);
|
MSize osz = (MSize)(sb->e - b);
|
||||||
if (osz > 2*LJ_MIN_SBUF) {
|
if (osz > 2*LJ_MIN_SBUF) {
|
||||||
MSize n = (MSize)(sb->w - b);
|
|
||||||
b = lj_mem_realloc(L, b, osz, (osz >> 1));
|
b = lj_mem_realloc(L, b, osz, (osz >> 1));
|
||||||
sb->b = b;
|
sb->w = sb->b = b; /* Not supposed to keep data across shrinks. */
|
||||||
sb->w = b + n;
|
|
||||||
sb->e = b + (osz >> 1);
|
sb->e = b + (osz >> 1);
|
||||||
}
|
}
|
||||||
lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");
|
lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");
|
||||||
|
@ -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)
|
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];
|
TRef sp[2];
|
||||||
CType *s[2];
|
CType *s[2];
|
||||||
MSize i;
|
MSize i;
|
||||||
@ -1548,6 +1549,8 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tref_isnil(tr)) {
|
} 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);
|
tr = lj_ir_kptr(J, NULL);
|
||||||
ct = ctype_get(cts, CTID_P_VOID);
|
ct = ctype_get(cts, CTID_P_VOID);
|
||||||
} else if (tref_isinteger(tr)) {
|
} 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);
|
ct = ctype_child(cts, cct);
|
||||||
tr = lj_ir_kint(J, (int32_t)ofs);
|
tr = lj_ir_kint(J, (int32_t)ofs);
|
||||||
} else { /* Interpreter will throw or return false. */
|
} 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)) {
|
} else if (ctype_isptr(ct->info)) {
|
||||||
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
|
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
|
||||||
} else {
|
} else {
|
||||||
ct = ctype_get(cts, CTID_P_VOID);
|
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||||
}
|
}
|
||||||
} else if (!tref_isnum(tr)) {
|
} else if (!tref_isnum(tr)) {
|
||||||
tr = 0;
|
tr = 0;
|
||||||
@ -1583,7 +1586,6 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
TRef tr;
|
TRef tr;
|
||||||
MMS mm = (MMS)rd->data;
|
|
||||||
if ((mm == MM_len || mm == MM_concat ||
|
if ((mm == MM_len || mm == MM_concat ||
|
||||||
(!(tr = crec_arith_int64(J, sp, s, mm)) &&
|
(!(tr = crec_arith_int64(J, sp, s, mm)) &&
|
||||||
!(tr = crec_arith_ptr(J, sp, s, mm)))) &&
|
!(tr = crec_arith_ptr(J, sp, s, mm)))) &&
|
||||||
|
@ -79,6 +79,7 @@ ERRDEF(SETFENV, LUA_QL("setfenv") " cannot change environment of given object")
|
|||||||
ERRDEF(CORUN, "cannot resume running coroutine")
|
ERRDEF(CORUN, "cannot resume running coroutine")
|
||||||
ERRDEF(CODEAD, "cannot resume dead coroutine")
|
ERRDEF(CODEAD, "cannot resume dead coroutine")
|
||||||
ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
|
ERRDEF(COSUSP, "cannot resume non-suspended coroutine")
|
||||||
|
ERRDEF(PRNGSD, "PRNG seeding failed")
|
||||||
ERRDEF(TABINS, "wrong number of arguments to " LUA_QL("insert"))
|
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(TABCAT, "invalid value (%s) at index %d in table for " LUA_QL("concat"))
|
||||||
ERRDEF(TABSORT, "invalid order function for sorting")
|
ERRDEF(TABSORT, "invalid order function for sorting")
|
||||||
|
@ -2384,11 +2384,15 @@ static void parse_return(LexState *ls)
|
|||||||
BCReg nret = expr_list(ls, &e);
|
BCReg nret = expr_list(ls, &e);
|
||||||
if (nret == 1) { /* Return one result. */
|
if (nret == 1) { /* Return one result. */
|
||||||
if (e.k == VCALL) { /* Check for tail call. */
|
if (e.k == VCALL) { /* Check for tail call. */
|
||||||
|
#ifdef LUAJIT_DISABLE_TAILCALL
|
||||||
|
goto notailcall;
|
||||||
|
#else
|
||||||
BCIns *ip = bcptr(fs, &e);
|
BCIns *ip = bcptr(fs, &e);
|
||||||
/* It doesn't pay off to add BC_VARGT just for 'return ...'. */
|
/* It doesn't pay off to add BC_VARGT just for 'return ...'. */
|
||||||
if (bc_op(*ip) == BC_VARG) goto notailcall;
|
if (bc_op(*ip) == BC_VARG) goto notailcall;
|
||||||
fs->pc--;
|
fs->pc--;
|
||||||
ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
|
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. */
|
} else { /* Can return the result from any register. */
|
||||||
ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
|
ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
|
||||||
}
|
}
|
||||||
@ -2562,11 +2566,9 @@ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
|
|||||||
*/
|
*/
|
||||||
static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
|
static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
|
||||||
{
|
{
|
||||||
BCIns ins;
|
BCIns ins = fs->bcbase[pc].ins;
|
||||||
GCstr *name;
|
GCstr *name;
|
||||||
cTValue *o;
|
cTValue *o;
|
||||||
if (pc >= fs->bclim) return 0;
|
|
||||||
ins = fs->bcbase[pc].ins;
|
|
||||||
switch (bc_op(ins)) {
|
switch (bc_op(ins)) {
|
||||||
case BC_MOV:
|
case BC_MOV:
|
||||||
if (bc_d(ins) >= fs->nactvar) return 0;
|
if (bc_d(ins) >= fs->nactvar) return 0;
|
||||||
@ -2615,7 +2617,7 @@ static void parse_for_iter(LexState *ls, GCstr *indexname)
|
|||||||
assign_adjust(ls, 3, expr_list(ls, &e), &e);
|
assign_adjust(ls, 3, expr_list(ls, &e), &e);
|
||||||
/* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
|
/* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
|
||||||
bcreg_bump(fs, 3+ls->fr2);
|
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. */
|
var_add(ls, 3); /* Hidden control variables. */
|
||||||
lex_check(ls, TK_do);
|
lex_check(ls, TK_do);
|
||||||
loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
|
loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
|
||||||
|
@ -1025,7 +1025,9 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
|
|||||||
J->L->base = b + baseadj;
|
J->L->base = b + baseadj;
|
||||||
copyTV(J->L, b-(2<<LJ_FR2), &save);
|
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));
|
BCReg dst = bc_a(*(frame_contpc(frame)-1));
|
||||||
J->base[dst] = tr;
|
J->base[dst] = tr;
|
||||||
if (dst >= J->maxslot) {
|
if (dst >= J->maxslot) {
|
||||||
@ -2075,12 +2077,27 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
|||||||
|
|
||||||
/* -- Concatenation ------------------------------------------------------- */
|
/* -- 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)
|
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
||||||
{
|
{
|
||||||
TRef *top = &J->base[topslot];
|
TRef *top = &J->base[topslot];
|
||||||
TValue savetv[5+LJ_FR2];
|
TValue savetv[5+LJ_FR2];
|
||||||
BCReg s;
|
BCReg s;
|
||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
|
RecCatDataCP rcd;
|
||||||
|
int errcode;
|
||||||
lj_assertJ(baseslot < topslot, "bad CAT arg");
|
lj_assertJ(baseslot < topslot, "bad CAT arg");
|
||||||
for (s = baseslot; s <= topslot; s++)
|
for (s = baseslot; s <= topslot; s++)
|
||||||
(void)getslot(J, s); /* Ensure all arguments have a reference. */
|
(void)getslot(J, s); /* Ensure all arguments have a reference. */
|
||||||
@ -2116,8 +2133,11 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|||||||
ix.tab = top[-1];
|
ix.tab = top[-1];
|
||||||
ix.key = top[0];
|
ix.key = top[0];
|
||||||
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
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. */
|
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
||||||
|
if (errcode) return (TRef)(-errcode);
|
||||||
return 0; /* No result yet. */
|
return 0; /* No result yet. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2440,6 +2460,8 @@ void lj_record_ins(jit_State *J)
|
|||||||
|
|
||||||
case BC_CAT:
|
case BC_CAT:
|
||||||
rc = rec_cat(J, rb, rc);
|
rc = rec_cat(J, rb, rc);
|
||||||
|
if (rc >= 0xffffff00)
|
||||||
|
lj_err_throw(J->L, -(int32_t)rc); /* Propagate errors. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -- Constant and move ops --------------------------------------------- */
|
/* -- Constant and move ops --------------------------------------------- */
|
||||||
|
@ -905,8 +905,10 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
|||||||
exd.J = J;
|
exd.J = J;
|
||||||
exd.exptr = exptr;
|
exd.exptr = exptr;
|
||||||
errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
|
errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
|
||||||
if (errcode)
|
if (errcode) {
|
||||||
|
setcframe_pc(cframe_raw(L->cframe), L); /* Point to any valid memory. */
|
||||||
return -errcode; /* Return negated error code. */
|
return -errcode; /* Return negated error code. */
|
||||||
|
}
|
||||||
|
|
||||||
if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
|
if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user