Merge branch 'hardcode-assist' into 'master'

Lua info string assist

See merge request KartKrew/Kart!1127
This commit is contained in:
toaster 2023-04-06 19:01:00 +00:00
commit 6b2558c43e
5 changed files with 113 additions and 12 deletions

View file

@ -31,6 +31,9 @@
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
#ifdef DEVELOP
static const char *getcanonicalfuncname (Closure *f, const char **name);
#endif
static int currentpc (lua_State *L, CallInfo *ci) {
@ -212,7 +215,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break;
}
case 'n': {
#ifdef DEVELOP
ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : getcanonicalfuncname(f, &ar->name);
#else
ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
#endif
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
@ -555,6 +562,19 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
}
#ifdef DEVELOP
static const char *getcanonicalfuncname (Closure *cl, const char **name) {
if (!cl->c.isC && cl->l.p->canonicalname)
{
*name = cl->l.p->canonicalname;
return "global";
}
else
return NULL;
}
#endif
/* only ANSI way to check whether a pointer points to an array */
static int isinstack (CallInfo *ci, const TValue *o) {
StkId p;

View file

@ -134,6 +134,9 @@ Proto *luaF_newproto (lua_State *L) {
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
#ifdef DEVELOP
f->canonicalname = NULL;
#endif
return f;
}

View file

@ -237,6 +237,9 @@ typedef struct Proto {
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
#ifdef DEVELOP
const char *canonicalname; /* function name, only for globals right now */
#endif
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;

View file

@ -246,8 +246,7 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
}
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
static void singlevar (LexState *ls, expdesc *var, TString *varname) {
FuncState *fs = ls->fs;
if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
@ -603,11 +602,16 @@ static void body_noparms (LexState *ls, expdesc *e, int line) {
close_func(ls);
pushclosure(ls, &new_fs, e);
}
static void body (LexState *ls, expdesc *e, int needself, int line) {
static void body (LexState *ls, expdesc *e, int needself, int line, const char *name) {
/* body -> `(' parlist `)' chunk END */
FuncState new_fs;
open_func(ls, &new_fs);
new_fs.f->linedefined = line;
#ifdef DEVELOP
new_fs.f->canonicalname = name;
#else
(void)name;
#endif
checknext(ls, '(');
if (needself) {
new_localvarliteral(ls, "self", 0);
@ -706,7 +710,7 @@ static void prefixexp (LexState *ls, expdesc *v) {
return;
}
case TK_NAME: {
singlevar(ls, v);
singlevar(ls, v, str_checkname(ls));
return;
}
case '$': {
@ -826,7 +830,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
}
case TK_FUNCTION: {
luaX_next(ls);
body(ls, v, 0, ls->linenumber);
body(ls, v, 0, ls->linenumber, NULL);
return;
}
default: {
@ -1315,11 +1319,12 @@ static void ifstat (LexState *ls, int line) {
static void localfunc (LexState *ls) {
expdesc v, b;
FuncState *fs = ls->fs;
new_localvar(ls, str_checkname(ls), 0);
TString *name = str_checkname(ls);
new_localvar(ls, name, 0);
init_exp(&v, VLOCAL, fs->freereg);
luaK_reserveregs(fs, 1);
adjustlocalvars(ls, 1);
body(ls, &b, 0, ls->linenumber);
body(ls, &b, 0, ls->linenumber, NULL);
luaK_storevar(fs, &v, &b);
/* debug information will only see the variable after this point! */
getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
@ -1345,10 +1350,10 @@ static void localstat (LexState *ls) {
}
static int funcname (LexState *ls, expdesc *v) {
static int funcname (LexState *ls, expdesc *v, TString *varname) {
/* funcname -> NAME {field} [`:' NAME] */
int needself = 0;
singlevar(ls, v);
singlevar(ls, v, varname);
while (ls->t.token == '.')
field(ls, v);
if (ls->t.token == ':') {
@ -1363,9 +1368,16 @@ static void funcstat (LexState *ls, int line) {
/* funcstat -> FUNCTION funcname body */
int needself;
expdesc v, b;
TString *name;
luaX_next(ls); /* skip FUNCTION */
needself = funcname(ls, &v);
body(ls, &b, needself, line);
name = str_checkname(ls);
needself = funcname(ls, &v, name);
#ifdef DEVELOP
/* just strdup this because I couldn't figure out gc */
body(ls, &b, needself, line, name ? strdup(getstr(name)) : NULL);
#else
body(ls, &b, needself, line, NULL);
#endif
luaK_storevar(ls->fs, &v, &b);
luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
}

View file

@ -43,7 +43,8 @@ enum sfxinfo_read {
sfxinfor_flags, // "pitch"
sfxinfor_volume,
sfxinfor_caption,
sfxinfor_skinsound
sfxinfor_skinsound,
sfxinfor_string,
};
const char *const sfxinfo_ropt[] = {
"name",
@ -53,6 +54,7 @@ const char *const sfxinfo_ropt[] = {
"volume",
"caption",
"skinsound",
"string",
NULL};
enum sfxinfo_write {
@ -942,12 +944,52 @@ static int state_get(lua_State *L)
// because the metatable will trigger.
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a META_ACTION userdata if not.
return 1; // return just the function
#ifdef DEVELOP
} else if (fastcmp(field,"actionname")) {
if (!st->action.acp1) { // Action is NULL.
lua_pushstring(L, "NULL");
} else if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
lua_Debug ar;
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
I_Assert(lua_istable(L, -1));
lua_pushlightuserdata(L, st); // Push the state pointer and
lua_rawget(L, -2); // use it to get the actual Lua function.
lua_remove(L, -2); // pop LREG_STATEACTION
// This normally doesn't get a function's name because the same Lua function can have many names.
// It only works because of a hack called 'canonicalname' in blua/lparser.c, which records the
// name a GLOBAL function was defined with. This does not work for local functions! (Lua actions
// are almost always global functions though.)
lua_getinfo(L, ">n", &ar);
lua_pushstring(L, ar.name);
} else {
lua_pushstring(L, LUA_GetActionName(&st->action)); // find a hardcoded function name
}
return 1;
#endif
} else if (fastcmp(field,"var1"))
number = st->var1;
else if (fastcmp(field,"var2"))
number = st->var2;
else if (fastcmp(field,"nextstate"))
number = st->nextstate;
else if (fastcmp(field,"string"))
{
statenum_t id = st-states;
if (id < S_FIRSTFREESLOT)
{
lua_pushstring(L, STATE_LIST[id]+2);
return 1;
}
id -= S_FIRSTFREESLOT;
if (id < NUMSTATEFREESLOTS && FREE_STATES[id])
{
lua_pushstring(L, FREE_STATES[id]);
return 1;
}
return 0;
}
else if (devparm)
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
else
@ -1213,6 +1255,23 @@ static int mobjinfo_get(lua_State *L)
lua_pushinteger(L, info->flags);
else if (fastcmp(field,"raisestate"))
lua_pushinteger(L, info->raisestate);
else if (fastcmp(field,"string")) {
mobjtype_t id = info-mobjinfo;
if (id < MT_FIRSTFREESLOT)
{
lua_pushstring(L, MOBJTYPE_LIST[id]+3);
return 1;
}
id -= MT_FIRSTFREESLOT;
if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id])
{
lua_pushstring(L, FREE_MOBJS[id]);
return 1;
}
return 0;
}
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
@ -1436,6 +1495,10 @@ static int sfxinfo_get(lua_State *L)
case sfxinfor_skinsound:
lua_pushinteger(L, sfx->skinsound);
return 1;
case sfxinfor_string: {
lua_pushstring(L, sfx->name);
return 1;
}
default:
return luaL_error(L, "Field does not exist in sfxinfo_t");
}