Compare commits

...
Author SHA1 Message Date
GenericHeroGuy 744dc87c16 In rehashtab, do counthash before adding asize
Thanks alug!
2025-01-29 22:25:24 +01:00
GenericHeroGuy b400655f3c Add cleanjit target
Recompiling the whole game after changing a single flag is pretty tiring
2025-01-06 00:02:11 +01:00
GenericHeroGuy 314ab9e9f0 Fix some functions leaking doubles in INTONLY 2025-01-05 23:48:40 +01:00
GenericHeroGuy 0fbc448013 Use references instead of upvalues for original I/O functions
No more unrestricted I/O through debug.getupvalue
2025-01-03 22:16:11 +01:00
GenericHeroGuy eb9d1982fa Update to BLUAJIT 449b76f 2025-01-03 20:12:26 +01:00
15 changed files with 86 additions and 47 deletions

No files matched your search

+4
View File
@@ -632,6 +632,10 @@ clean:
$(REMOVE) $(OBJDIR)/*.o $(REMOVE) $(OBJDIR)/*.o
ifndef NOBLUAJIT ifndef NOBLUAJIT
$(REMOVE) $(OBJDIR)/buildvm* $(OBJDIR)/minilua* $(OBJDIR)/lj_vm* $(ALL_HDRGEN) $(REMOVE) $(OBJDIR)/buildvm* $(OBJDIR)/minilua* $(OBJDIR)/lj_vm* $(ALL_HDRGEN)
cleanjit:
$(REMOVE) $(LJVMCORE_O) $(ALL_GEN)
$(REMOVE) $(OBJDIR)/buildvm* $(OBJDIR)/minilua* $(OBJDIR)/lj_vm* $(ALL_HDRGEN)
endif endif
ifdef MINGW ifdef MINGW
+1 -3
View File
@@ -227,9 +227,7 @@ local function prof_finish()
local samples = prof_samples local samples = prof_samples
if samples == 0 then if samples == 0 then
if prof_raw ~= true then out:write("[No samples collected]\n") end if prof_raw ~= true then out:write("[No samples collected]\n") end
return elseif prof_ann then
end
if prof_ann then
prof_annotate(prof_count1, samples) prof_annotate(prof_count1, samples)
else else
prof_top(prof_count1, prof_count2, samples, "") prof_top(prof_count1, prof_count2, samples, "")
+4
View File
@@ -470,7 +470,11 @@ LJLIB_CF(collectgarbage)
"\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning"); "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning");
int32_t data = lj_lib_optint(L, 2, 0); int32_t data = lj_lib_optint(L, 2, 0);
if (opt == LUA_GCCOUNT) { if (opt == LUA_GCCOUNT) {
#if LJ_INTONLY
setintV(L->top, G(L)->gc.total/1024);
#else
setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0); setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
#endif
} else { } else {
int res = lua_gc(L, opt, data); int res = lua_gc(L, opt, data);
if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING) if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING)
+1 -1
View File
@@ -98,7 +98,7 @@ LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift); x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
return bit_result64(L, id, x); return bit_result64(L, id, x);
} }
if (id2) setintV(L->base+1, sh); setintV(L->base+1, sh);
return FFH_RETRY; return FFH_RETRY;
#else #else
lj_lib_checknumber(L, 1); lj_lib_checknumber(L, 1);
+4
View File
@@ -72,7 +72,11 @@ LJLIB_CF(table_maxn)
lua_Number n = numberVnum(&node[i].key); lua_Number n = numberVnum(&node[i].key);
if (n > m) m = n; if (n > m) m = n;
} }
#if LJ_INTONLY
setintV(L->top-1, lj_num2int(m));
#else
setnumV(L->top-1, m); setnumV(L->top-1, m);
#endif
return 1; return 1;
} }
+2 -2
View File
@@ -949,11 +949,11 @@ static int asm_sunk_store(ASMState *as, IRIns *ira, IRIns *irs)
static void asm_snap_alloc1(ASMState *as, IRRef ref) static void asm_snap_alloc1(ASMState *as, IRRef ref)
{ {
IRIns *ir = IR(ref); IRIns *ir = IR(ref);
if (!irref_isk(ref) && ir->r != RID_SUNK) { if (!irref_isk(ref)) {
bloomset(as->snapfilt1, ref); bloomset(as->snapfilt1, ref);
bloomset(as->snapfilt2, hashrot(ref, ref + HASH_BIAS)); bloomset(as->snapfilt2, hashrot(ref, ref + HASH_BIAS));
if (ra_used(ir)) return; if (ra_used(ir)) return;
if (ir->r == RID_SINK) { if (ir->r == RID_SINK || ir->r == RID_SUNK) {
ir->r = RID_SUNK; ir->r = RID_SUNK;
#if LJ_HASFFI #if LJ_HASFFI
if (ir->o == IR_CNEWI) { /* Allocate CNEWI value. */ if (ir->o == IR_CNEWI) { /* Allocate CNEWI value. */
+1 -1
View File
@@ -408,7 +408,7 @@ static int bcread_header(LexState *ls)
#endif #endif
} }
if ((flags & BCDUMP_F_STRIP)) { if ((flags & BCDUMP_F_STRIP)) {
ls->chunkname = lj_str_newz(ls->L, ls->chunkarg); ls->chunkname = lj_str_newz(ls->L, *ls->chunkarg == BCDUMP_HEAD1 ? "=?" : ls->chunkarg);
} else { } else {
MSize len = bcread_uleb128(ls); MSize len = bcread_uleb128(ls);
bcread_need(ls, len); bcread_need(ls, len);
+5 -4
View File
@@ -2970,10 +2970,11 @@ static int parse_stmt(LexState *ls)
case TK_break: case TK_break:
lj_lex_next(ls); lj_lex_next(ls);
#if BLUAJIT_MULTILEVEL_BREAK #if BLUAJIT_MULTILEVEL_BREAK
int levels = numberVint(&ls->tokval); if (ls->tok == TK_number) {
if (lex_opt(ls, TK_number)) int levels = numberVint(&ls->tokval);
parse_break(ls, levels); lj_lex_next(ls);
else parse_break(ls, levels);
} else
#endif #endif
parse_break(ls, 1); parse_break(ls, 1);
return !LJ_52; /* Must be last in Lua 5.1. */ return !LJ_52; /* Must be last in Lua 5.1. */
+33 -18
View File
@@ -2084,25 +2084,19 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
typedef struct RecCatDataCP { typedef struct RecCatDataCP {
jit_State *J; jit_State *J;
RecordIndex *ix; BCReg baseslot, topslot;
TRef tr;
} RecCatDataCP; } RecCatDataCP;
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud) static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
{ {
RecCatDataCP *rcd = (RecCatDataCP *)ud; RecCatDataCP *rcd = (RecCatDataCP *)ud;
UNUSED(L); UNUSED(dummy); jit_State *J = rcd->J;
rec_mm_arith(rcd->J, rcd->ix, MM_concat); /* Call __concat metamethod. */ BCReg baseslot = rcd->baseslot, topslot = rcd->topslot;
return NULL;
}
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];
BCReg s; BCReg s;
RecordIndex ix; RecordIndex ix;
RecCatDataCP rcd; UNUSED(L); UNUSED(dummy);
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. */
@@ -2124,7 +2118,10 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
} while (trp <= top); } while (trp <= top);
tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr); tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr);
J->maxslot = (BCReg)(xbase - J->base); J->maxslot = (BCReg)(xbase - J->base);
if (xbase == base) return tr; /* Return simple concatenation result. */ if (xbase == base) {
rcd->tr = tr; /* Return simple concatenation result. */
return NULL;
}
/* Pass partial result. */ /* Pass partial result. */
topslot = J->maxslot--; topslot = J->maxslot--;
*xbase = tr; *xbase = tr;
@@ -2137,13 +2134,31 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]); copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
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. */ rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
rcd->tr = 0; /* No result yet. */
return NULL;
}
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
{
lua_State *L = J->L;
ptrdiff_t delta = L->top - L->base;
TValue savetv[5+LJ_FR2], errobj;
RecCatDataCP rcd;
int errcode;
rcd.J = J; rcd.J = J;
rcd.ix = &ix; rcd.baseslot = baseslot;
errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp); rcd.topslot = topslot;
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */ memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
if (errcode) return (TRef)(-errcode); errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
return 0; /* No result yet. */ if (errcode) copyTV(L, &errobj, L->top-1);
memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
if (errcode) {
L->top = L->base + delta;
copyTV(L, L->top++, &errobj);
return (TRef)(-errcode);
}
return rcd.tr;
} }
/* -- Record bytecode ops ------------------------------------------------- */ /* -- Record bytecode ops ------------------------------------------------- */
+7 -1
View File
@@ -359,8 +359,14 @@ static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
uint32_t total, asize, na, i; uint32_t total, asize, na, i;
for (i = 0; i < LJ_MAX_ABITS; i++) bins[i] = 0; for (i = 0; i < LJ_MAX_ABITS; i++) bins[i] = 0;
asize = countarray(t, bins); asize = countarray(t, bins);
#if 0
total = 1 + asize; total = 1 + asize;
total += counthash(t, bins, &asize); total += counthash(t, bins, &asize);
#else
/* more closely matches vanilla lua when abusing undefined behavior (frictionfix.....) */
total = counthash(t, bins, &asize);
total += 1 + asize;
#endif
asize += countint(ek, bins); asize += countint(ek, bins);
na = bestasize(bins, &asize); na = bestasize(bins, &asize);
total -= na; total -= na;
@@ -635,7 +641,7 @@ LJ_NOINLINE static MSize tab_len_slow(GCtab *t, size_t hi)
while ((tv = lj_tab_getint(t, (int32_t)hi)) && !tvisnil(tv)) { while ((tv = lj_tab_getint(t, (int32_t)hi)) && !tvisnil(tv)) {
lo = hi; lo = hi;
hi += hi; hi += hi;
if (hi > (size_t)(INT_MAX-2)) { /* Punt and do a linear search. */ if (hi > (size_t)(0x7fffffff - 2)) { /* Punt and do a linear search. */
lo = 1; lo = 1;
while ((tv = lj_tab_getint(t, (int32_t)lo)) && !tvisnil(tv)) lo++; while ((tv = lj_tab_getint(t, (int32_t)lo)) && !tvisnil(tv)) lo++;
return (MSize)(lo - 1); return (MSize)(lo - 1);
+1 -1
View File
@@ -78,7 +78,7 @@ int32_t lj_vm_foldarith_int(int32_t x, int32_t y, int op)
case IR_MOD - IR_ADD: return x%y; break; case IR_MOD - IR_ADD: return x%y; break;
case IR_POW - IR_ADD: return pow(x, y); break; case IR_POW - IR_ADD: return pow(x, y); break;
case IR_NEG - IR_ADD: return -x; break; case IR_NEG - IR_ADD: return -x; break;
case IR_ABS - IR_ADD: return fabs(x); break; case IR_ABS - IR_ADD: return abs(x); break;
#if LJ_HASJIT #if LJ_HASJIT
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break; case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
case IR_MIN - IR_ADD: return x < y ? x : y; break; case IR_MIN - IR_ADD: return x < y ? x : y; break;
-1
View File
@@ -9,7 +9,6 @@
#ifndef WINVER #ifndef WINVER
#define WINVER 0x0501 #define WINVER 0x0501
#endif #endif
#include <limits.h>
#include <stddef.h> #include <stddef.h>
/* Default path for loading Lua and C modules with require(). */ /* Default path for loading Lua and C modules with require(). */
+3 -2
View File
@@ -1420,9 +1420,10 @@ static void build_subroutines(BuildCtx *ctx)
| sltu AT, TMP1, TMP2 | sltu AT, TMP1, TMP2
| bnez AT, ->fff_fallback | bnez AT, ->fff_fallback
|. lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) |. lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
| daddiu NARGS8:RC, NARGS8:RC, -8 | daddiu NARGS8:TMP0, NARGS8:RC, -8
| bltz NARGS8:RC, ->fff_fallback | bltz NARGS8:TMP0, ->fff_fallback
|. move TMP2, BASE |. move TMP2, BASE
| move NARGS8:RC, NARGS8:TMP0
| daddiu BASE, BASE, 16 | daddiu BASE, BASE, 16
| // Remember active hook before pcall. | // Remember active hook before pcall.
| srl TMP3, TMP3, HOOK_ACTIVE_SHIFT | srl TMP3, TMP3, HOOK_ACTIVE_SHIFT
+14 -11
View File
@@ -40,6 +40,8 @@ boolean luaL_checkboolean(lua_State *L, int narg) {
return lua_toboolean(L, narg); return lua_toboolean(L, narg);
} }
static int ref_open, ref_iowrite, ref_fwrite; // original versions of io functions
#define FILELIMIT 1024*1024 // Size limit for reading/writing files #define FILELIMIT 1024*1024 // Size limit for reading/writing files
static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder
@@ -102,7 +104,7 @@ static int lib_open(lua_State *L)
lua_pushstring(L, destFilename); lua_pushstring(L, destFilename);
lua_replace(L, 1); lua_replace(L, 1);
// now call the real io.open // now call the real io.open
lua_pushvalue(L, lua_upvalueindex(1)); lua_rawgeti(L, LUA_REGISTRYINDEX, ref_open);
lua_insert(L, 1); lua_insert(L, 1);
lua_call(L, lua_gettop(L)-1, LUA_MULTRET); lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
return lua_gettop(L); return lua_gettop(L);
@@ -114,8 +116,10 @@ static int lib_write(lua_State *L, int arg)
int top = lua_gettop(L); int top = lua_gettop(L);
boolean error = true; boolean error = true;
size_t len, size = 0; size_t len, size = 0;
int ogref = ref_iowrite;
if (arg != 1) { if (arg != 1) {
ogref = ref_fwrite;
FILE *fp = *(FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE); FILE *fp = *(FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
if (fp == NULL) goto call; // real file:write will throw if (fp == NULL) goto call; // real file:write will throw
size = ftell(fp); size = ftell(fp);
@@ -134,7 +138,7 @@ static int lib_write(lua_State *L, int arg)
error = false; error = false;
call: call:
lua_pushvalue(L, lua_upvalueindex(1)); lua_rawgeti(L, LUA_REGISTRYINDEX, ogref);
lua_insert(L, 1); lua_insert(L, 1);
lua_call(L, lua_gettop(L)-1, LUA_MULTRET); lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
@@ -3449,25 +3453,24 @@ int LUA_BaseLib(lua_State *L)
lua_pop(L, 2); // pop metatable and dummy string lua_pop(L, 2); // pop metatable and dummy string
// replaces an existing function with another, // replaces an existing function with another,
// saving the original as an upvalue // saving the original as a reference
#define REPLACE(name, func) \ #define REPLACE(name, func, ref) \
lua_pushliteral(L, name); \ lua_pushliteral(L, name); \
lua_rawget(L, -2); \ lua_rawget(L, -2); \
lua_pushcclosure(L, &func, 1); \ ref = luaL_ref(L, LUA_REGISTRYINDEX); \
lua_pushliteral(L, name); \ lua_pushliteral(L, name); \
lua_pushvalue(L, -2); \ lua_pushcclosure(L, &func, 0); \
lua_rawset(L, -4); \ lua_rawset(L, -3);
lua_pop(L, 1);
// replace io.open // replace io.open
lua_getglobal(L, "io"); lua_getglobal(L, "io");
REPLACE("open", lib_open) REPLACE("open", lib_open, ref_open)
REPLACE("write", lib_write_io) REPLACE("write", lib_write_io, ref_iowrite)
lua_pop(L, 1); lua_pop(L, 1);
// replace file:write // replace file:write
luaL_getmetatable(L, LUA_FILEHANDLE); luaL_getmetatable(L, LUA_FILEHANDLE);
REPLACE("write", lib_write_f) REPLACE("write", lib_write_f, ref_fwrite)
lua_pop(L, 1); lua_pop(L, 1);
#undef REPLACE #undef REPLACE
+6 -2
View File
@@ -329,6 +329,7 @@ static int lib_cvRegisterVar(lua_State *L)
const char* category = NULL; const char* category = NULL;
const char* menu_name = NULL; const char* menu_name = NULL;
boolean hasfunc = false; boolean hasfunc = false;
int funcref = 0;
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
@@ -429,7 +430,9 @@ static int lib_cvRegisterVar(lua_State *L)
} else if (i == 5 || (k && fasticmp(k, "func"))) { } else if (i == 5 || (k && fasticmp(k, "func"))) {
if (!lua_isfunction(L, 4)) if (!lua_isfunction(L, 4))
TYPEERROR("func", LUA_TFUNCTION) TYPEERROR("func", LUA_TFUNCTION)
lua_setfield(L, LUA_REGISTRYINDEX, "CVFUNC"); if (hasfunc)
luaL_unref(L, LUA_REGISTRYINDEX, funcref); // real clever, huh?
funcref = luaL_ref(L, LUA_REGISTRYINDEX);
hasfunc = true; hasfunc = true;
continue; continue;
} }
@@ -450,10 +453,11 @@ static int lib_cvRegisterVar(lua_State *L)
if (hasfunc) { if (hasfunc) {
lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange"); lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
I_Assert(lua_istable(L, 3)); I_Assert(lua_istable(L, 3));
lua_getfield(L, LUA_REGISTRYINDEX, "CVFUNC"); lua_rawgeti(L, LUA_REGISTRYINDEX, funcref);
lua_setfield(L, 3, cvar->name); lua_setfield(L, 3, cvar->name);
lua_pop(L, 1); lua_pop(L, 1);
cvar->func = Lua_OnChange; cvar->func = Lua_OnChange;
luaL_unref(L, LUA_REGISTRYINDEX, funcref);
} }
lua_getfield(L, LUA_REGISTRYINDEX, "CV_Vars"); lua_getfield(L, LUA_REGISTRYINDEX, "CV_Vars");