lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Eduardo Ochs once stated:
> 2) Here is the idea; the question is below.
> 
>    The functions debug.getinfo, debug.getlocal and debug.setlocal are
>    usually called with an integer argument that the manual refers to
>    as "level", that is processed like this (I took the code from
>    db_getinfo, in ldblib.c) to set the variable "ar" to an "activation
>    record":

  To get this thread back on track (sorry about that), I've given this some
thought, and I think this is the best approach to what you want.  Somewhere,
you want to add:

	#define TYPE_LUA_DEBUG	"lua_Debug"

	luaL_newmetatable(L,TYPE_LUA_DEBUG);
	/* add metamethods as you see fit */

Then:

	static int mygetstack(lua_State *L)
	{
	  lua_Debug *par;
	  int        level = luaL_checkinteger(L,1);
	  
	  par = lua_newuserdata(L,sizeof(lua_Debug));
	  if (!lua_getstack(L,level,par))
	    return 0;
	  luaL_getmetatable(L,TYPE_LUA_DEBUG);
	  lua_setmetatable(L,-2);
	  return 1;
	}
	
  This returns a userdata of type lua_Debug.  Lua will track the memory for
you, so there's no leaking.  Then, in the appropriate locations where you
take a level number, or a function, you can instead check for a userdata of
type TYPE_LUA_DEBUG, and then pass that to the appropriate Lua API call:

	lua_Debug *par = luaL_checkudata(L,idx,TYPE_LUA_DEBUG);
	
  If you want a pretty representation to print out, add a __tostring
metamethod to the metatable---something like:

	static int myluadebug___tostring(lua_State *L)
	{
	  lua_pushfstring(L,"activation record: %p",lua_touserdata(L,1)); /* [1] */
	  return 1;
	}

That's really all you need I would think.

  -spc
  
[1]	Why not luaL_checkudata()?  The only way this can fail is
	intentional user intervention (as the only way to this function is
	via the metatable of the lua_Debug userdata we're using), but if
	that is a concern, then yes, use luaL_checkudata() here.