mirror of https://github.com/rusefi/lua.git
'symbexec' merged with 'getobjname' (as only use for symbolic execution
now is to find a "good" name for an object)
This commit is contained in:
parent
0cc3add9f8
commit
e67dc3a227
195
ldebug.c
195
ldebug.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.48 2009/04/27 18:58:31 roberto Exp roberto $
|
** $Id: ldebug.c,v 2.49 2009/04/30 17:42:21 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -269,85 +269,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
|
||||||
int pc;
|
|
||||||
int last; /* stores position of last instruction that changed `reg' */
|
|
||||||
last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
|
|
||||||
for (pc = 0; pc < lastpc; pc++) {
|
|
||||||
Instruction i = pt->code[pc];
|
|
||||||
OpCode op = GET_OPCODE(i);
|
|
||||||
int a = GETARG_A(i);
|
|
||||||
int b = 0;
|
|
||||||
int c = 0;
|
|
||||||
switch (getOpMode(op)) {
|
|
||||||
case iABC: {
|
|
||||||
b = GETARG_B(i);
|
|
||||||
c = GETARG_C(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case iABx: {
|
|
||||||
b = GETARG_Bx(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case iAsBx: {
|
|
||||||
b = GETARG_sBx(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case iAx: break;
|
|
||||||
}
|
|
||||||
if (testAMode(op)) {
|
|
||||||
if (a == reg) last = pc; /* change register `a' */
|
|
||||||
}
|
|
||||||
switch (op) {
|
|
||||||
case OP_LOADNIL: {
|
|
||||||
if (a <= reg && reg <= b)
|
|
||||||
last = pc; /* set registers from `a' to `b' */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_SELF: {
|
|
||||||
if (reg == a+1) last = pc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_TFORCALL: {
|
|
||||||
if (reg >= a+2) last = pc; /* affect all regs above its base */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_TFORLOOP:
|
|
||||||
case OP_FORLOOP:
|
|
||||||
case OP_FORPREP:
|
|
||||||
case OP_JMP: {
|
|
||||||
int dest = pc+1+b;
|
|
||||||
/* not full check and jump is forward and do not skip `lastpc'? */
|
|
||||||
if (reg != NO_REG && pc < dest && dest <= lastpc)
|
|
||||||
pc += b; /* do the jump */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_CALL:
|
|
||||||
case OP_TAILCALL: {
|
|
||||||
if (reg >= a) last = pc; /* affect all registers above base */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_CLOSURE: {
|
|
||||||
int nup = pt->p[b]->nups;
|
|
||||||
pc += nup; /* do not 'execute' pseudo-instructions */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_VARARG: {
|
|
||||||
b--; /* ??? */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pt->code[last];
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef check
|
|
||||||
#undef checkreg
|
|
||||||
|
|
||||||
/* }====================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
static const char *kname (Proto *p, int c) {
|
static const char *kname (Proto *p, int c) {
|
||||||
if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
|
if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
|
||||||
return svalue(&p->k[INDEXK(c)]);
|
return svalue(&p->k[INDEXK(c)]);
|
||||||
|
@ -356,50 +277,101 @@ static const char *kname (Proto *p, int c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
|
static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
|
||||||
const char **name) {
|
const char **name) {
|
||||||
if (isLua(ci)) { /* a Lua function? */
|
Proto *p;
|
||||||
Proto *p = ci_func(ci)->l.p;
|
int lastpc, pc;
|
||||||
int pc = currentpc(ci);
|
const char *what = NULL;
|
||||||
Instruction i;
|
if (!isLua(ci)) /* is not a Lua function? */
|
||||||
*name = luaF_getlocalname(p, stackpos+1, pc);
|
return NULL; /* cannot find name for it */
|
||||||
if (*name) /* is a local? */
|
p = ci_func(ci)->l.p;
|
||||||
return "local";
|
lastpc = currentpc(ci);
|
||||||
i = symbexec(p, pc, stackpos); /* try symbolic execution */
|
*name = luaF_getlocalname(p, reg + 1, lastpc);
|
||||||
lua_assert(pc != -1);
|
if (*name) /* is a local? */
|
||||||
switch (GET_OPCODE(i)) {
|
return "local";
|
||||||
|
/* else try symbolic execution */
|
||||||
|
for (pc = 0; pc < lastpc; pc++) {
|
||||||
|
Instruction i = p->code[pc];
|
||||||
|
OpCode op = GET_OPCODE(i);
|
||||||
|
int a = GETARG_A(i);
|
||||||
|
switch (op) {
|
||||||
case OP_GETGLOBAL: {
|
case OP_GETGLOBAL: {
|
||||||
int g = GETARG_Bx(i); /* global index */
|
if (reg == a) {
|
||||||
lua_assert(ttisstring(&p->k[g]));
|
int g = GETARG_Bx(i); /* global index */
|
||||||
*name = svalue(&p->k[g]);
|
lua_assert(ttisstring(&p->k[g]));
|
||||||
return "global";
|
*name = svalue(&p->k[g]);
|
||||||
|
what = "global";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case OP_MOVE: {
|
case OP_MOVE: {
|
||||||
int a = GETARG_A(i);
|
if (reg == a) {
|
||||||
int b = GETARG_B(i); /* move from `b' to `a' */
|
int b = GETARG_B(i); /* move from 'b' to 'a' */
|
||||||
if (b < a)
|
if (b < a)
|
||||||
return getobjname(L, ci, b, name); /* get name for `b' */
|
what = getobjname(L, ci, b, name); /* get name for 'b' */
|
||||||
|
else what = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_GETTABLE: {
|
case OP_GETTABLE: {
|
||||||
int k = GETARG_C(i); /* key index */
|
if (reg == a) {
|
||||||
*name = kname(p, k);
|
int k = GETARG_C(i); /* key index */
|
||||||
return "field";
|
*name = kname(p, k);
|
||||||
|
what = "field";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case OP_GETUPVAL: {
|
case OP_GETUPVAL: {
|
||||||
int u = GETARG_B(i); /* upvalue index */
|
if (reg == a) {
|
||||||
*name = p->upvalues ? getstr(p->upvalues[u]) : "?";
|
int u = GETARG_B(i); /* upvalue index */
|
||||||
return "upvalue";
|
*name = p->upvalues ? getstr(p->upvalues[u]) : "?";
|
||||||
|
what = "upvalue";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_LOADNIL: {
|
||||||
|
int b = GETARG_B(i); /* move from 'b' to 'a' */
|
||||||
|
if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */
|
||||||
|
what = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case OP_SELF: {
|
case OP_SELF: {
|
||||||
int k = GETARG_C(i); /* key index */
|
if (reg == a) {
|
||||||
*name = kname(p, k);
|
int k = GETARG_C(i); /* key index */
|
||||||
return "method";
|
*name = kname(p, k);
|
||||||
|
what = "method";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
case OP_TFORCALL: {
|
||||||
|
if (reg >= a + 2) what = NULL; /* affect all regs above its base */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_CALL:
|
||||||
|
case OP_TAILCALL: {
|
||||||
|
if (reg >= a) what = NULL; /* affect all registers above base */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JMP: {
|
||||||
|
int b = GETARG_sBx(i);
|
||||||
|
int dest = pc + 1 + b;
|
||||||
|
/* jump is forward and do not skip `lastpc'? */
|
||||||
|
if (pc < dest && dest <= lastpc)
|
||||||
|
pc += b; /* do the jump */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_CLOSURE: {
|
||||||
|
int nup = p->p[GETARG_Bx(i)]->nups;
|
||||||
|
pc += nup; /* do not 'execute' pseudo-instructions */
|
||||||
|
lua_assert(pc <= lastpc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (testAMode(op) && reg == a) what = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL; /* no useful name found */
|
return what;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -439,6 +411,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||||
return "metamethod";
|
return "metamethod";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* only ANSI way to check whether a pointer points to an array */
|
/* only ANSI way to check whether a pointer points to an array */
|
||||||
static int isinstack (CallInfo *ci, const TValue *o) {
|
static int isinstack (CallInfo *ci, const TValue *o) {
|
||||||
|
|
Loading…
Reference in New Issue