From e67dc3a22722837a968122a77d9e0398d103378d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 4 May 2009 15:26:21 -0300 Subject: 'symbexec' merged with 'getobjname' (as only use for symbolic execution now is to find a "good" name for an object) --- ldebug.c | 181 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 78 insertions(+), 103 deletions(-) (limited to 'ldebug.c') diff --git a/ldebug.c b/ldebug.c index 5e93bdd8..fd3beec4 100644 --- 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) { -- cgit v1.2.3-55-g6feb