|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: ldblib.c,v 1.147 2014/12/08 15:47:25 roberto Exp roberto $ |
|
|
|
** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp roberto $ |
|
|
|
** Interface from Lua to its debug API |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -27,6 +27,17 @@ |
|
|
|
static const int HOOKKEY = 0; |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** If L1 != L, L1 can be in any state, and therefore there is no |
|
|
|
** garanties about its stack space; any push in L1 must be |
|
|
|
** checked. |
|
|
|
*/ |
|
|
|
static void checkstack (lua_State *L, lua_State *L1, int n) { |
|
|
|
if (L != L1 && !lua_checkstack(L1, n)) |
|
|
|
luaL_error(L, "stack overflow"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int db_getregistry (lua_State *L) { |
|
|
|
lua_pushvalue(L, LUA_REGISTRYINDEX); |
|
|
|
return 1; |
|
|
@ -127,12 +138,16 @@ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { |
|
|
|
|
|
|
|
/*
|
|
|
|
** Calls 'lua_getinfo' and collects all results in a new table. |
|
|
|
** L1 needs stack space for an optional input (function) plus |
|
|
|
** two optional outputs (function and line table) from function |
|
|
|
** 'lua_getinfo'. |
|
|
|
*/ |
|
|
|
static int db_getinfo (lua_State *L) { |
|
|
|
lua_Debug ar; |
|
|
|
int arg; |
|
|
|
lua_State *L1 = getthread(L, &arg); |
|
|
|
const char *options = luaL_optstring(L, arg+2, "flnStu"); |
|
|
|
checkstack(L, L1, 3); |
|
|
|
if (lua_isfunction(L, arg + 1)) { /* info about a function? */ |
|
|
|
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ |
|
|
|
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ |
|
|
@ -190,6 +205,7 @@ static int db_getlocal (lua_State *L) { |
|
|
|
int level = (int)luaL_checkinteger(L, arg + 1); |
|
|
|
if (!lua_getstack(L1, level, &ar)) /* out of range? */ |
|
|
|
return luaL_argerror(L, arg+1, "level out of range"); |
|
|
|
checkstack(L, L1, 1); |
|
|
|
name = lua_getlocal(L1, &ar, nvar); |
|
|
|
if (name) { |
|
|
|
lua_xmove(L1, L, 1); /* move local value */ |
|
|
@ -216,6 +232,7 @@ static int db_setlocal (lua_State *L) { |
|
|
|
return luaL_argerror(L, arg+1, "level out of range"); |
|
|
|
luaL_checkany(L, arg+3); |
|
|
|
lua_settop(L, arg+3); |
|
|
|
checkstack(L, L1, 1); |
|
|
|
lua_xmove(L, L1, 1); |
|
|
|
name = lua_setlocal(L1, &ar, nvar); |
|
|
|
if (name == NULL) |
|
|
@ -350,6 +367,7 @@ static int db_sethook (lua_State *L) { |
|
|
|
lua_pushvalue(L, -1); |
|
|
|
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ |
|
|
|
} |
|
|
|
checkstack(L, L1, 1); |
|
|
|
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ |
|
|
|
lua_pushvalue(L, arg + 1); /* value (hook function) */ |
|
|
|
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ |
|
|
@ -370,6 +388,7 @@ static int db_gethook (lua_State *L) { |
|
|
|
lua_pushliteral(L, "external hook"); |
|
|
|
else { /* hook table must exist */ |
|
|
|
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); |
|
|
|
checkstack(L, L1, 1); |
|
|
|
lua_pushthread(L1); lua_xmove(L1, L, 1); |
|
|
|
lua_rawget(L, -2); /* 1st result = hooktable[L1] */ |
|
|
|
lua_remove(L, -2); /* remove hook table */ |
|
|
|