Fix Lua error backtrace in LuaCallback

Fix two bugs in error handling of LuaCallback::run:

1. It used the Lua function _TRACEBACK, which exists in Lua 5.0 but
   not in Lua 5.1.  In bos/stratagus SVN trunk r8495 on 2007-01-07,
   LuaCall was changed to use debug.trace instead.  Do the same to
   LuaCallback.

2. It passed the wrong Lua stack index to lua_pcall as the error
   handler function.  lua_gettop returns the index of the topmost
   value, not the index that the next pushed value will get.

Also, remove _TRACEBACK from the blacklist now that it is used neither
in Bos Wars nor in any version of Lua supported by Bos Wars.
This commit is contained in:
kon 2011-08-08 05:09:52 +00:00
parent 25d5eb732c
commit 7fd148d1fd
4 changed files with 12 additions and 5 deletions

View file

@ -36,9 +36,16 @@ struct lua_State;
class LuaCallback
{
lua_State *luastate;
// Integer key of the callback function in the Lua registry.
int luaref;
// Number of arguments pushed for the function.
int arguments;
// The top of the Lua stack before pushPreamble().
int base;
public:
LuaCallback(lua_State *lua, lua_Object luaref);
virtual ~LuaCallback();

View file

@ -112,6 +112,7 @@ extern const char *LuaToString(lua_State *l, int tableIndex, int stringIndex);
extern int LuaToNumber(lua_State *l, int index);
extern int LuaToNumber(lua_State *l, int tableIndex, int numberIndex);
extern bool LuaToBoolean(lua_State *l, int index);
extern int luatraceback(lua_State *L);
extern void CclGarbageCollect(int fast); /// Perform garbage collection
extern void InitCcl(void); /// Initialise ccl

View file

@ -58,8 +58,8 @@ LuaCallback::LuaCallback(lua_State *l, lua_Object f) :
void LuaCallback::pushPreamble()
{
base = lua_gettop(luastate);
lua_getglobal(luastate, "_TRACEBACK");
lua_rawgeti(luastate, LUA_REGISTRYINDEX, luaref);
lua_pushcfunction(Lua, luatraceback); // at base+1
lua_rawgeti(luastate, LUA_REGISTRYINDEX, luaref); // at base+2
arguments = 0;
}
@ -98,7 +98,7 @@ void LuaCallback::run()
int status;
//FIXME call error reporting function
status = lua_pcall(luastate, arguments, 0, base);
status = lua_pcall(luastate, arguments, 0, base + 1);
if (status) {
const char *msg;
msg = lua_tostring(luastate, -1);

View file

@ -142,7 +142,7 @@ static int report(int status, bool exitOnError)
return status;
}
static int luatraceback(lua_State *L)
int luatraceback(lua_State *L)
{
lua_pushliteral(L, "debug");
lua_gettable(L, LUA_GLOBALSINDEX);
@ -941,7 +941,6 @@ static bool IsBlacklistedGlobal(const char *key)
!strcmp(key, "ipairs") ||
!strcmp(key, "loadstring") ||
!strcmp(key, "dofile") ||
!strcmp(key, "_TRACEBACK") ||
!strcmp(key, "_VERSION") ||
!strcmp(key, "pairs") ||
!strcmp(key, "__pow") ||