aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-08-12 17:01:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-08-12 17:01:44 -0300
commit0b65cb74cdf4ef6e6a33da6724610e506407df1a (patch)
treed2fba4506b0650cec94aeba62c719a255651ea21
parentea46b750dceec7f6ddd3ae48ace391d5a1fd705e (diff)
downloadlua-0b65cb74cdf4ef6e6a33da6724610e506407df1a.tar.gz
lua-0b65cb74cdf4ef6e6a33da6724610e506407df1a.tar.bz2
lua-0b65cb74cdf4ef6e6a33da6724610e506407df1a.zip
new implementation for 'getobjname': first search for relevant
instruction (new function 'findsetreg') and then try to build a meaningful name
-rw-r--r--ldebug.c172
1 files changed, 87 insertions, 85 deletions
diff --git a/ldebug.c b/ldebug.c
index e57beff6..1dfac128 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.82 2011/06/02 19:31:40 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.83 2011/08/09 20:58:29 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -232,7 +232,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
232 break; 232 break;
233 } 233 }
234 case 'n': { 234 case 'n': {
235 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; 235 /* calling function is a known Lua function? */
236 if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
237 ar->namewhat = getfuncname(L, ci->previous, &ar->name);
238 else
239 ar->namewhat = NULL;
236 if (ar->namewhat == NULL) { 240 if (ar->namewhat == NULL) {
237 ar->namewhat = ""; /* not found */ 241 ar->namewhat = ""; /* not found */
238 ar->name = NULL; 242 ar->name = NULL;
@@ -286,17 +290,16 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
286** ======================================================= 290** =======================================================
287*/ 291*/
288 292
289static const char *getobjname (lua_State *L, CallInfo *ci, int reg, 293static const char *getobjname (Proto *p, int lastpc, int reg,
290 const char **name); 294 const char **name);
291 295
292 296
293/* 297/*
294** find a "name" for the RK value 'c' 298** find a "name" for the RK value 'c'
295*/ 299*/
296static void kname (lua_State *L, CallInfo *ci, int c, int oreg, 300static void kname (Proto *p, int pc, int c, const char **name) {
297 const char *what, const char **name) {
298 if (ISK(c)) { /* is 'c' a constant? */ 301 if (ISK(c)) { /* is 'c' a constant? */
299 TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)]; 302 TValue *kvalue = &p->k[INDEXK(c)];
300 if (ttisstring(kvalue)) { /* literal constant? */ 303 if (ttisstring(kvalue)) { /* literal constant? */
301 *name = svalue(kvalue); /* it is its own name */ 304 *name = svalue(kvalue); /* it is its own name */
302 return; 305 return;
@@ -304,8 +307,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
304 /* else no reasonable name found */ 307 /* else no reasonable name found */
305 } 308 }
306 else { /* 'c' is a register */ 309 else { /* 'c' is a register */
307 if (c != oreg) /* not the original register? */ 310 const char *what = getobjname(p, pc, c, name); /* search for 'c' */
308 what = getobjname(L, ci, c, name); /* search for 'c' */
309 if (what && *what == 'c') { /* found a constant name? */ 311 if (what && *what == 'c') { /* found a constant name? */
310 return; /* 'name' already filled */ 312 return; /* 'name' already filled */
311 } 313 }
@@ -315,85 +317,30 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
315} 317}
316 318
317 319
318static const char *getobjname (lua_State *L, CallInfo *ci, int reg, 320/*
319 const char **name) { 321** try to find last instruction before 'lastpc' that modified register 'reg'
320 Proto *p = ci_func(ci)->p; 322*/
321 const char *what = NULL; 323static int findsetreg (Proto *p, int lastpc, int reg) {
322 int lastpc = currentpc(ci);
323 int pc; 324 int pc;
324 *name = luaF_getlocalname(p, reg + 1, lastpc); 325 int setreg = -1; /* keep last instruction that changed 'reg' */
325 if (*name) /* is a local? */
326 return "local";
327 /* else try symbolic execution */
328 for (pc = 0; pc < lastpc; pc++) { 326 for (pc = 0; pc < lastpc; pc++) {
329 Instruction i = p->code[pc]; 327 Instruction i = p->code[pc];
330 OpCode op = GET_OPCODE(i); 328 OpCode op = GET_OPCODE(i);
331 int a = GETARG_A(i); 329 int a = GETARG_A(i);
332 switch (op) { 330 switch (op) {
333 case OP_MOVE: {
334 if (reg == a) {
335 int b = GETARG_B(i); /* move from 'b' to 'a' */
336 if (b < a)
337 what = getobjname(L, ci, b, name); /* get name for 'b' */
338 else what = NULL;
339 }
340 break;
341 }
342 case OP_GETTABUP:
343 case OP_GETTABLE: {
344 if (reg == a) {
345 int k = GETARG_C(i); /* key index */
346 int t = GETARG_B(i);
347 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
348 ? luaF_getlocalname(p, t + 1, pc)
349 : getstr(p->upvalues[t].name);
350 kname(L, ci, k, a, what, name);
351 what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
352 }
353 break;
354 }
355 case OP_GETUPVAL: {
356 if (reg == a) {
357 int u = GETARG_B(i); /* upvalue index */
358 TString *tn = p->upvalues[u].name;
359 *name = tn ? getstr(tn) : "?";
360 what = "upvalue";
361 }
362 break;
363 }
364 case OP_LOADK:
365 case OP_LOADKX: {
366 if (reg == a) {
367 int b = (op == OP_LOADK) ? GETARG_Bx(i)
368 : GETARG_Ax(p->code[pc + 1]);
369 if (ttisstring(&p->k[b])) {
370 what = "constant";
371 *name = svalue(&p->k[b]);
372 }
373 }
374 break;
375 }
376 case OP_LOADNIL: { 331 case OP_LOADNIL: {
377 int b = GETARG_B(i); 332 int b = GETARG_B(i);
378 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ 333 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
379 what = NULL; 334 setreg = pc;
380 break;
381 }
382 case OP_SELF: {
383 if (reg == a) {
384 int k = GETARG_C(i); /* key index */
385 kname(L, ci, k, a, what, name);
386 what = "method";
387 }
388 break; 335 break;
389 } 336 }
390 case OP_TFORCALL: { 337 case OP_TFORCALL: {
391 if (reg >= a + 2) what = NULL; /* affect all regs above its base */ 338 if (reg >= a + 2) setreg = pc; /* affect all regs above its base */
392 break; 339 break;
393 } 340 }
394 case OP_CALL: 341 case OP_CALL:
395 case OP_TAILCALL: { 342 case OP_TAILCALL: {
396 if (reg >= a) what = NULL; /* affect all registers above base */ 343 if (reg >= a) setreg = pc; /* affect all registers above base */
397 break; 344 break;
398 } 345 }
399 case OP_JMP: { 346 case OP_JMP: {
@@ -405,35 +352,89 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
405 break; 352 break;
406 } 353 }
407 case OP_TEST: { 354 case OP_TEST: {
408 if (reg == a) what = NULL; /* jumped code can change 'a' */ 355 if (reg == a) setreg = pc; /* jumped code can change 'a' */
409 break; 356 break;
410 } 357 }
411 default: 358 default:
412 if (testAMode(op) && reg == a) what = NULL; 359 if (testAMode(op) && reg == a) /* any instruction that set A */
360 setreg = pc;
413 break; 361 break;
414 } 362 }
415 } 363 }
416 return what; 364 return setreg;
365}
366
367
368static const char *getobjname (Proto *p, int lastpc, int reg,
369 const char **name) {
370 int pc;
371 *name = luaF_getlocalname(p, reg + 1, lastpc);
372 if (*name) /* is a local? */
373 return "local";
374 /* else try symbolic execution */
375 pc = findsetreg(p, lastpc, reg);
376 if (pc != -1) { /* could find instruction? */
377 Instruction i = p->code[pc];
378 OpCode op = GET_OPCODE(i);
379 int a = GETARG_A(i);
380 switch (op) {
381 case OP_MOVE: {
382 int b = GETARG_B(i); /* move from 'b' to 'a' */
383 lua_assert(reg == a);
384 if (b < a)
385 return getobjname(p, pc, b, name); /* get name for 'b' */
386 }
387 case OP_GETTABUP:
388 case OP_GETTABLE: {
389 int k = GETARG_C(i); /* key index */
390 int t = GETARG_B(i);
391 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
392 ? luaF_getlocalname(p, t + 1, pc)
393 : getstr(p->upvalues[t].name);
394 kname(p, pc, k, name);
395 return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
396 }
397 case OP_GETUPVAL: {
398 int u = GETARG_B(i); /* upvalue index */
399 TString *tn = p->upvalues[u].name;
400 *name = tn ? getstr(tn) : "?";
401 return "upvalue";
402 }
403 case OP_LOADK:
404 case OP_LOADKX: {
405 int b = (op == OP_LOADK) ? GETARG_Bx(i)
406 : GETARG_Ax(p->code[pc + 1]);
407 if (ttisstring(&p->k[b])) {
408 *name = svalue(&p->k[b]);
409 return "constant";
410 }
411 }
412 case OP_SELF: {
413 int k = GETARG_C(i); /* key index */
414 kname(p, pc, k, name);
415 return "method";
416 }
417 default: break; /* go through to return NULL */
418 }
419 }
420 return NULL; /* could not find reasonable name */
417} 421}
418 422
419 423
420static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 424static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
421 TMS tm; 425 TMS tm;
422 Instruction i; 426 Proto *p = ci_func(ci)->p; /* calling function */
423 if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) 427 int pc = currentpc(ci); /* calling instruction index */
424 return NULL; /* calling function is not Lua (or is unknown) */ 428 Instruction i = p->code[pc]; /* calling instruction */
425 ci = ci->previous; /* calling function */
426 i = ci_func(ci)->p->code[currentpc(ci)];
427 if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
428 i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
429 switch (GET_OPCODE(i)) { 429 switch (GET_OPCODE(i)) {
430 case OP_CALL: 430 case OP_CALL:
431 case OP_TAILCALL: 431 case OP_TAILCALL: /* get function name */
432 return getobjname(L, ci, GETARG_A(i), name); 432 return getobjname(p, pc, GETARG_A(i), name);
433 case OP_TFORCALL: { 433 case OP_TFORCALL: { /* for iterator */
434 *name = "for iterator"; 434 *name = "for iterator";
435 return "for iterator"; 435 return "for iterator";
436 } 436 }
437 /* all other instructions can call only through metamethods */
437 case OP_SELF: 438 case OP_SELF:
438 case OP_GETTABUP: 439 case OP_GETTABUP:
439 case OP_GETTABLE: tm = TM_INDEX; break; 440 case OP_GETTABLE: tm = TM_INDEX; break;
@@ -496,7 +497,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
496 if (isLua(ci)) { 497 if (isLua(ci)) {
497 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ 498 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
498 if (!kind && isinstack(ci, o)) /* no? try a register */ 499 if (!kind && isinstack(ci, o)) /* no? try a register */
499 kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); 500 kind = getobjname(ci_func(ci)->p, currentpc(ci),
501 cast_int(o - ci->u.l.base), &name);
500 } 502 }
501 if (kind) 503 if (kind)
502 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", 504 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",