Lunatic: add option -Lopts=... from command line.

Permitting to enable various debugging options. See "eduke32 -debughelp"
for which ones those are: they were previously settable from defs_common.lua,
and a new option 'strict' has been added that makes accesses to void sprites
error. (That is, already "sprite[i]", not "sprite[i].some_member".)

git-svn-id: https://svn.eduke32.com/eduke32@4049 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-09-05 17:37:46 +00:00
parent d48383d2f7
commit 1328c66f9c
5 changed files with 114 additions and 36 deletions

View file

@ -8473,12 +8473,19 @@ static void G_ShowParameterHelp(void)
extern char forcegl; extern char forcegl;
#endif #endif
#ifdef LUNATIC
const char **g_argv;
#endif
static void G_CheckCommandLine(int32_t argc, const char **argv) static void G_CheckCommandLine(int32_t argc, const char **argv)
{ {
int32_t i = 1, j, maxlen=0, *lengths; int32_t i = 1, j, maxlen=0, *lengths;
const char *c, *k; const char *c, *k;
mapster32_fullpath = argv[0]; mapster32_fullpath = argv[0];
#ifdef LUNATIC
g_argv = argv;
#endif
#ifdef HAVE_CLIPSHAPE_FEATURE #ifdef HAVE_CLIPSHAPE_FEATURE
// pre-form the default 10 clipmaps // pre-form the default 10 clipmaps

View file

@ -9065,6 +9065,11 @@ static void G_ShowDebugHelp(void)
"-q#\t\tFake multiplayer with # (2-8) players\n" "-q#\t\tFake multiplayer with # (2-8) players\n"
"-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n" "-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n"
"-conversion YYYYMMDD\tSelects CON script version for compatibility with older mods\n" "-conversion YYYYMMDD\tSelects CON script version for compatibility with older mods\n"
#ifdef LUNATIC
"-Lopts=<opt1>,<opt2>,...\n"
" Pass options to Lunatic, valid ones are:\n"
" diag, nojit, traces, dump, strict\n"
#endif
; ;
#if defined RENDERTYPEWIN #if defined RENDERTYPEWIN
Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev); Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev);
@ -9983,9 +9988,13 @@ static void G_CheckCommandLine(int32_t argc, const char **argv)
G_AddPath(c); G_AddPath(c);
break; break;
case 'l': case 'l':
ud.warp_on = 1; // NOTE: Overlaid with -Lopts=... options for Lunatic, hence the check.
c++; if (Bisdigit(c[1]))
ud.m_level_number = ud.level_number = ((unsigned)(Batoi(c)-1))%MAXLEVELS; {
ud.warp_on = 1;
c++;
ud.m_level_number = ud.level_number = ((unsigned)(Batoi(c)-1))%MAXLEVELS;
}
break; break;
case 'm': case 'm':
if (*(c+1) != 'a' && *(c+1) != 'A') if (*(c+1) != 'a' && *(c+1) != 'A')

View file

@ -602,7 +602,6 @@ const char *g_sizes_of_what[];
int32_t g_sizes_of[]; int32_t g_sizes_of[];
int32_t g_elCallDepth; int32_t g_elCallDepth;
int32_t block_deletesprite; int32_t block_deletesprite;
const char **g_argv;
const char **g_elModules; const char **g_elModules;
char g_modDir[]; char g_modDir[];
actor_t actor[MAXSPRITES]; actor_t actor[MAXSPRITES];

View file

@ -11,21 +11,56 @@ local ffi = require("ffi")
local ffiC = ffi.C local ffiC = ffi.C
local bit = require("bit") local bit = require("bit")
-- Lunatic debugging (mostly bitfield): local bor = bit.bor
-- ~=0: print diagnostic information
-- 2: disable JIT compilation
-- 4: load LuaJIT's 'v' module, printing trace info
-- 8: load LuaJIT's 'dump' module, printing generated IR/machine code
ffi.cdef "enum { _DEBUG_LUNATIC=0 }"
if (bit.band(ffiC._DEBUG_LUNATIC, 2)~=0) then ffi.cdef "const char **g_argv;"
-- Lunatic debugging options (-Lopts=<opt1>,<opt2>,... from the command line):
-- diag: print diagnostic information
-- nojit: disable JIT compilation
-- traces: load LuaJIT's 'v' module, printing trace info
-- (env var: LUAJIT_VERBOSEFILE)
-- dump: load LuaJIT's 'dump' module, printing generated IR/machine code
-- (env var: LUAJIT_DUMPFILE)
-- strict: catch various conditions that may indicate an logical error
local debug_flags = {}
local IS_DEBUG_FLAG = {
diag=true, nojit=true, traces=true, dump=true,
strict=true,
}
-- Handle command-line argument. (Look for -Lopts=...)
local function handle_cmdline_arg(str)
local opts = str:match("^-Lopts=(.*)")
if (opts ~= nil) then
for opt in opts:gmatch("[^,]+") do
if (IS_DEBUG_FLAG[opt]) then
debug_flags[opt] = true
end
end
end
end
local i=0
while (ffiC.g_argv[i] ~= nil) do
handle_cmdline_arg(ffi.string(ffiC.g_argv[i]))
i = i+1
end
-- Print diagnostic information?
ffi.cdef("enum { _DEBUG_LUNATIC="..(debug_flags.diag and 1 or 0).." }")
-- Be strict?
ffi.cdef("enum { _LUNATIC_STRICT="..(debug_flags.strict and 1 or 0).." }")
if (debug_flags.nojit) then
require("jit").off() require("jit").off()
end end
if (not _LUNATIC_AUX) then if (not _LUNATIC_AUX) then
if (bit.band(ffiC._DEBUG_LUNATIC, 8)~=0) then if (debug_flags.dump) then
require("dump").on("+rs") require("dump").on("+rs")
elseif (bit.band(ffiC._DEBUG_LUNATIC, 4)~=0) then elseif (debug_flags.traces) then
require("v").on() require("v").on()
end end
end end
@ -964,11 +999,35 @@ function static_members.sprite.updatesect(spritenum, flags)
return newsect return newsect
end end
local strictp = debug_flags.strict
function GenStructMetatable(Structname, Boundname, StaticMembersTab) function GenStructMetatable(Structname, Boundname, StaticMembersTab)
StaticMembersTab = StaticMembersTab or static_members[Structname] StaticMembersTab = StaticMembersTab or static_members[Structname]
return { -- If we're running with the 'strict' option, disallow accesses to void
__index = function(tab, key) -- sprites.
local index_func = (strictp and Structname=="sprite") and
-- Mostly CODEDUP of lower function, ...
function(tab, key)
if (type(key)=="number") then
if (key >= 0 and key < ffiC[Boundname]) then
-- ... except this.
-- (Inlining into the other function did slow things down.)
if (ffiC.sprite[key].statnum == ffiC.MAXSTATUS) then
error("attempt to access void sprite with index "..key, 2)
end
return ffiC[Structname][key]
end
error("out-of-bounds "..Structname.."[] read access with index "..key, 2)
elseif (type(key)=="string") then
return StaticMembersTab[key]
end
end
or
function(tab, key)
if (type(key)=="number") then if (type(key)=="number") then
if (key >= 0 and key < ffiC[Boundname]) then if (key >= 0 and key < ffiC[Boundname]) then
return ffiC[Structname][key] return ffiC[Structname][key]
@ -977,8 +1036,10 @@ function GenStructMetatable(Structname, Boundname, StaticMembersTab)
elseif (type(key)=="string") then elseif (type(key)=="string") then
return StaticMembersTab[key] return StaticMembersTab[key]
end end
end, end
return {
__index = index_func,
__newindex = function() error("cannot write directly to "..Structname.."[]", 2) end, __newindex = function() error("cannot write directly to "..Structname.."[]", 2) end,
} }
end end

View file

@ -353,28 +353,30 @@ gameevent
proj.drop = 0 proj.drop = 0
proj:set_trail(D.SMALLSMOKE) proj:set_trail(D.SMALLSMOKE)
t = gv.gethiticks() if (gv._LUNATIC_STRICT == 0) then
local N=1 t = gv.gethiticks()
for n=1,N do local N=1
for i=0,gv.MAXSPRITES-1 do for n=1,N do
sprite[i].filler = 1 for i=0,gv.MAXSPRITES-1 do
end sprite[i].filler = 1
for i=gv.MAXSPRITES-1,0,-1 do end
sprite[i].shade = 1 for i=gv.MAXSPRITES-1,0,-1 do
end sprite[i].shade = 1
for i=0,gv.MAXSPRITES-1 do end
sprite[i].xoffset = 0 for i=0,gv.MAXSPRITES-1 do
end sprite[i].xoffset = 0
for i=gv.MAXSPRITES-1,0,-1 do end
sprite[i].yoffset = 1 for i=gv.MAXSPRITES-1,0,-1 do
sprite[i].yoffset = 1
end
end end
t = gv.gethiticks()-t
printf("%d x four 0..MAXSPRITES-1 iterations took %.03f us per outer iteration", N, (1000*t)/N)
-- Results on x86:
-- N=1: 480-1000 us (too large variance)
-- N=10: 190-210 us * 10 = 1.9-2.1 ms
-- N=100: about 160 us * 100 = about 16 ms
end end
t = gv.gethiticks()-t
printf("%d x four 0..MAXSPRITES-1 iterations took %.03f us per outer iteration", N, (1000*t)/N)
-- Results on x86:
-- N=1: 480-1000 us (too large variance)
-- N=10: 190-210 us * 10 = 1.9-2.1 ms
-- N=100: about 160 us * 100 = about 16 ms
-- Make the DUKECAR in E1L1 into a zombie actor (temporarily) -- Make the DUKECAR in E1L1 into a zombie actor (temporarily)
-- NOTE: Use static value (not the one from 'D'). -- NOTE: Use static value (not the one from 'D').