Hardcode assist, part J (jartha)

- Add read-only `actionname` field to Lua states.
    - Resolves to function name definition of global Lua functions.
    - Resolves to all-uppercase name for C actions.
    - Resolves to "NULL" string if nil.
This commit is contained in:
James R 2023-04-01 05:44:59 -07:00
parent 0d2f598c3e
commit faccea6207
5 changed files with 71 additions and 11 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

@ -944,6 +944,28 @@ 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"))