commit e67dc3a22722837a968122a77d9e0398d103378d
parent 0cc3add9f80efa62722b085a281aa449e9a0112c
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 4 May 2009 15:25:57 -0300
'symbexec' merged with 'getobjname' (as only use for symbolic execution
now is to find a "good" name for an object)
Diffstat:
M | ldebug.c | | | 181 | ++++++++++++++++++++++++++++++++++--------------------------------------------- |
1 file changed, 78 insertions(+), 103 deletions(-)
diff --git a/ldebug.c b/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
** See Copyright Notice in lua.h
*/
@@ -269,137 +269,109 @@ 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) */
+static const char *kname (Proto *p, int c) {
+ if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
+ return svalue(&p->k[INDEXK(c)]);
+ else
+ return "?";
+}
+
+
+static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
+ const char **name) {
+ Proto *p;
+ int lastpc, pc;
+ const char *what = NULL;
+ if (!isLua(ci)) /* is not a Lua function? */
+ return NULL; /* cannot find name for it */
+ p = ci_func(ci)->l.p;
+ lastpc = currentpc(ci);
+ *name = luaF_getlocalname(p, reg + 1, lastpc);
+ if (*name) /* is a local? */
+ return "local";
+ /* else try symbolic execution */
for (pc = 0; pc < lastpc; pc++) {
- Instruction i = pt->code[pc];
+ Instruction i = p->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);
+ switch (op) {
+ case OP_GETGLOBAL: {
+ if (reg == a) {
+ int g = GETARG_Bx(i); /* global index */
+ lua_assert(ttisstring(&p->k[g]));
+ *name = svalue(&p->k[g]);
+ what = "global";
+ }
+ break;
+ }
+ case OP_MOVE: {
+ if (reg == a) {
+ int b = GETARG_B(i); /* move from 'b' to 'a' */
+ if (b < a)
+ what = getobjname(L, ci, b, name); /* get name for 'b' */
+ else what = NULL;
+ }
break;
}
- case iABx: {
- b = GETARG_Bx(i);
+ case OP_GETTABLE: {
+ if (reg == a) {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ what = "field";
+ }
break;
}
- case iAsBx: {
- b = GETARG_sBx(i);
+ case OP_GETUPVAL: {
+ if (reg == a) {
+ int u = GETARG_B(i); /* upvalue index */
+ *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
+ what = "upvalue";
+ }
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' */
+ 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: {
- if (reg == a+1) last = pc;
+ if (reg == a) {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ what = "method";
+ }
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 */
+ if (reg >= a + 2) what = NULL; /* affect all regs above its base */
break;
}
case OP_CALL:
case OP_TAILCALL: {
- if (reg >= a) last = pc; /* affect all registers above base */
+ if (reg >= a) what = NULL; /* affect all registers above base */
break;
}
- case OP_CLOSURE: {
- int nup = pt->p[b]->nups;
- pc += nup; /* do not 'execute' pseudo-instructions */
+ 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_VARARG: {
- b--; /* ??? */
+ case OP_CLOSURE: {
+ int nup = p->p[GETARG_Bx(i)]->nups;
+ pc += nup; /* do not 'execute' pseudo-instructions */
+ lua_assert(pc <= lastpc);
break;
}
- default: break;
- }
- }
- return pt->code[last];
-}
-
-#undef check
-#undef checkreg
-
-/* }====================================================== */
-
-
-static const char *kname (Proto *p, int c) {
- if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
- return svalue(&p->k[INDEXK(c)]);
- else
- return "?";
-}
-
-
-static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
- const char **name) {
- if (isLua(ci)) { /* a Lua function? */
- Proto *p = ci_func(ci)->l.p;
- int pc = currentpc(ci);
- Instruction i;
- *name = luaF_getlocalname(p, stackpos+1, pc);
- if (*name) /* is a local? */
- return "local";
- i = symbexec(p, pc, stackpos); /* try symbolic execution */
- lua_assert(pc != -1);
- switch (GET_OPCODE(i)) {
- case OP_GETGLOBAL: {
- int g = GETARG_Bx(i); /* global index */
- lua_assert(ttisstring(&p->k[g]));
- *name = svalue(&p->k[g]);
- return "global";
- }
- case OP_MOVE: {
- int a = GETARG_A(i);
- int b = GETARG_B(i); /* move from `b' to `a' */
- if (b < a)
- return getobjname(L, ci, b, name); /* get name for `b' */
+ default:
+ if (testAMode(op) && reg == a) what = NULL;
break;
- }
- case OP_GETTABLE: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "field";
- }
- case OP_GETUPVAL: {
- int u = GETARG_B(i); /* upvalue index */
- *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
- return "upvalue";
- }
- case OP_SELF: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "method";
- }
- default: 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";
}
+/* }====================================================== */
+
+
/* only ANSI way to check whether a pointer points to an array */
static int isinstack (CallInfo *ci, const TValue *o) {