summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-10-19 10:32:10 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-10-19 10:32:10 -0200
commite2dc807c6e93dc8819d065ae8e3808c720928bbd (patch)
treef92d70870b66523e297c98f47ebcaacfa1adffb1
parent138d00176ca3330b0ad18eb4006605746b68df94 (diff)
downloadlua-e2dc807c6e93dc8819d065ae8e3808c720928bbd.tar.gz
lua-e2dc807c6e93dc8819d065ae8e3808c720928bbd.tar.bz2
lua-e2dc807c6e93dc8819d065ae8e3808c720928bbd.zip
check whether function is finalizer when finding a name for it +
comments + some instructions can call functions in unespected ways (e.g., finalizers)
-rw-r--r--ldebug.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/ldebug.c b/ldebug.c
index 1c438d6c..f1835890 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.119 2016/02/26 19:20:15 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 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*/
@@ -38,7 +38,8 @@
38#define ci_func(ci) (clLvalue((ci)->func)) 38#define ci_func(ci) (clLvalue((ci)->func))
39 39
40 40
41static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 41static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
42 const char **name);
42 43
43 44
44static int currentpc (CallInfo *ci) { 45static int currentpc (CallInfo *ci) {
@@ -244,6 +245,20 @@ static void collectvalidlines (lua_State *L, Closure *f) {
244} 245}
245 246
246 247
248static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
249 if (ci == NULL) /* no 'ci'? */
250 return NULL; /* no info */
251 else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
252 *name = "__gc";
253 return "metamethod"; /* report it as such */
254 }
255 /* calling function is a known Lua function? */
256 else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
257 return funcnamefromcode(L, ci->previous, name);
258 else return NULL; /* no way to find a name */
259}
260
261
247static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 262static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
248 Closure *f, CallInfo *ci) { 263 Closure *f, CallInfo *ci) {
249 int status = 1; 264 int status = 1;
@@ -274,11 +289,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
274 break; 289 break;
275 } 290 }
276 case 'n': { 291 case 'n': {
277 /* calling function is a known Lua function? */ 292 ar->namewhat = getfuncname(L, ci, &ar->name);
278 if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
279 ar->namewhat = getfuncname(L, ci->previous, &ar->name);
280 else
281 ar->namewhat = NULL;
282 if (ar->namewhat == NULL) { 293 if (ar->namewhat == NULL) {
283 ar->namewhat = ""; /* not found */ 294 ar->namewhat = ""; /* not found */
284 ar->name = NULL; 295 ar->name = NULL;
@@ -471,8 +482,15 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
471} 482}
472 483
473 484
474static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 485/*
475 TMS tm = (TMS)0; /* to avoid warnings */ 486** Try to find a name for a function based on the code that called it.
487** (Only works when function was called by a Lua function.)
488** Returns what the name is (e.g., "for iterator", "method",
489** "metamethod") and sets '*name' to point to the name.
490*/
491static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
492 const char **name) {
493 TMS tm = (TMS)0; /* (initial value avoids warnings) */
476 Proto *p = ci_func(ci)->p; /* calling function */ 494 Proto *p = ci_func(ci)->p; /* calling function */
477 int pc = currentpc(ci); /* calling instruction index */ 495 int pc = currentpc(ci); /* calling instruction index */
478 Instruction i = p->code[pc]; /* calling instruction */ 496 Instruction i = p->code[pc]; /* calling instruction */
@@ -482,13 +500,13 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
482 } 500 }
483 switch (GET_OPCODE(i)) { 501 switch (GET_OPCODE(i)) {
484 case OP_CALL: 502 case OP_CALL:
485 case OP_TAILCALL: /* get function name */ 503 case OP_TAILCALL:
486 return getobjname(p, pc, GETARG_A(i), name); 504 return getobjname(p, pc, GETARG_A(i), name); /* get function name */
487 case OP_TFORCALL: { /* for iterator */ 505 case OP_TFORCALL: { /* for iterator */
488 *name = "for iterator"; 506 *name = "for iterator";
489 return "for iterator"; 507 return "for iterator";
490 } 508 }
491 /* all other instructions can call only through metamethods */ 509 /* other instructions can do calls through metamethods */
492 case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: 510 case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
493 tm = TM_INDEX; 511 tm = TM_INDEX;
494 break; 512 break;
@@ -509,7 +527,8 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
509 case OP_EQ: tm = TM_EQ; break; 527 case OP_EQ: tm = TM_EQ; break;
510 case OP_LT: tm = TM_LT; break; 528 case OP_LT: tm = TM_LT; break;
511 case OP_LE: tm = TM_LE; break; 529 case OP_LE: tm = TM_LE; break;
512 default: lua_assert(0); /* other instructions cannot call a function */ 530 default:
531 return NULL; /* cannot find a reasonable name */
513 } 532 }
514 *name = getstr(G(L)->tmname[tm]); 533 *name = getstr(G(L)->tmname[tm]);
515 return "metamethod"; 534 return "metamethod";