Browse Source

'getlocal' gets information about parameters of Lua functions

Roberto Ierusalimschy 15 years ago
parent
commit
ca3865cf1b
3 changed files with 37 additions and 20 deletions
  1. 20 12
      ldblib.c
  2. 15 6
      ldebug.c
  3. 2 2
      lparser.c

+ 20 - 12
ldblib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldblib.c,v 1.120 2010/02/18 19:18:41 roberto Exp roberto $
+** $Id: ldblib.c,v 1.121 2010/03/26 20:58:11 roberto Exp roberto $
 ** Interface from Lua to its debug API
 ** See Copyright Notice in lua.h
 */
@@ -157,19 +157,27 @@ static int db_getlocal (lua_State *L) {
   lua_State *L1 = getthread(L, &arg);
   lua_Debug ar;
   const char *name;
-  if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
-    return luaL_argerror(L, arg+1, "level out of range");
-  name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
-  if (name) {
-    lua_xmove(L1, L, 1);
-    lua_pushstring(L, name);
-    lua_pushvalue(L, -2);
-    return 2;
-  }
-  else {
-    lua_pushnil(L);
+  int nvar = luaL_checkint(L, arg+2);  /* local-variable index */
+  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
+    lua_pushvalue(L, arg + 1);  /* push function */
+    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
     return 1;
   }
+  else {  /* stack-level argument */
+    if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
+      return luaL_argerror(L, arg+1, "level out of range");
+    name = lua_getlocal(L1, &ar, nvar);
+    if (name) {
+      lua_xmove(L1, L, 1);  /* push local value */
+      lua_pushstring(L, name);  /* push name */
+      lua_pushvalue(L, -2);  /* re-order */
+      return 2;
+    }
+    else {
+      lua_pushnil(L);  /* no name (nor value) */
+      return 1;
+    }
+  }
 }
 
 

+ 15 - 6
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.70 2010/04/13 20:48:12 roberto Exp roberto $
+** $Id: ldebug.c,v 2.71 2010/06/16 13:44:36 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -119,12 +119,21 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
 
 
 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
-  StkId pos;
-  const char *name = findlocal(L, ar->i_ci, n, &pos);
+  const char *name;
   lua_lock(L);
-  if (name) {
-    setobj2s(L, L->top, pos);
-    api_incr_top(L);
+  if (ar == NULL) {  /* information about non-active function? */
+    if (!isLfunction(L->top - 1))  /* not a Lua function? */
+      name = NULL;
+    else  /* consider live variables at function start (parameters) */
+      name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0);
+  }
+  else {  /* active function; get information through 'ar' */
+    StkId pos;
+    name = findlocal(L, ar->i_ci, n, &pos);
+    if (name) {
+      setobj2s(L, L->top, pos);
+      api_incr_top(L);
+    }
   }
   lua_unlock(L);
   return name;

+ 2 - 2
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.86 2010/05/15 13:32:02 roberto Exp roberto $
+** $Id: lparser.c,v 2.87 2010/05/31 16:08:55 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -402,8 +402,8 @@ static void close_func (LexState *ls) {
   lua_State *L = ls->L;
   FuncState *fs = ls->fs;
   Proto *f = fs->f;
-  removevars(fs, 0);
   luaK_ret(fs, 0, 0);  /* final return */
+  removevars(fs, 0);
   luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
   f->sizecode = fs->pc;
   luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);