1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Pass a errfunc to lua_pcall to get a traceback

This commit is contained in:
ShadowNinja 2013-11-05 12:06:15 -05:00
parent 3f519eb729
commit 371b39a09a
19 changed files with 424 additions and 324 deletions

View file

@ -871,6 +871,8 @@ void read_groups(lua_State *L, int index,
/******************************************************************************/
void push_items(lua_State *L, const std::vector<ItemStack> &items)
{
lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
// Get the table insert function
lua_getglobal(L, "table");
lua_getfield(L, -1, "insert");
@ -883,11 +885,12 @@ void push_items(lua_State *L, const std::vector<ItemStack> &items)
lua_pushvalue(L, table_insert);
lua_pushvalue(L, table);
LuaItemStack::create(L, item);
if(lua_pcall(L, 2, 0, 0))
script_error(L, "error: %s", lua_tostring(L, -1));
if(lua_pcall(L, 2, 0, errorhandler))
script_error(L);
}
lua_remove(L, -2); // Remove table
lua_remove(L, -2); // Remove insert
lua_remove(L, -2); // Remove table
lua_remove(L, -2); // Remove error handler
}
/******************************************************************************/

View file

@ -23,32 +23,41 @@ with this program; if not, write to the Free Software Foundation, Inc.,
std::string script_get_backtrace(lua_State *L)
{
std::string s;
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
lua_getglobal(L, "debug");
if(lua_istable(L, -1)){
lua_getfield(L, -1, "traceback");
if(lua_isfunction(L, -1)){
if(lua_isfunction(L, -1)) {
lua_call(L, 0, 1);
if(lua_isstring(L, -1)){
s += lua_tostring(L, -1);
s = lua_tostring(L, -1);
}
lua_pop(L, 1);
}
else{
lua_pop(L, 1);
}
lua_pop(L, 1);
}
lua_pop(L, 1);
return s;
}
void script_error(lua_State *L, const char *fmt, ...)
int script_error_handler(lua_State *L) {
lua_getglobal(L, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1);
lua_pushinteger(L, 2);
lua_call(L, 2, 1);
return 1;
}
void script_error(lua_State *L)
{
va_list argp;
va_start(argp, fmt);
char buf[10000];
vsnprintf(buf, 10000, fmt, argp);
va_end(argp);
throw LuaError(L, buf);
throw LuaError(NULL, lua_tostring(L, -1));
}
// Push the list of callbacks (a lua table).
@ -61,13 +70,20 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
{
// Insert the return value into the lua stack, below the table
assert(lua_gettop(L) >= nargs + 1);
lua_pushnil(L);
lua_insert(L, -(nargs + 1) - 1);
// Stack now looks like this:
// ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
lua_pushnil(L);
int rv = lua_gettop(L) - nargs - 1;
int table = rv + 1;
lua_insert(L, rv);
// Insert error handler after return value
lua_pushcfunction(L, script_error_handler);
int errorhandler = rv + 1;
lua_insert(L, errorhandler);
// Stack now looks like this:
// ... <return value = nil> <error handler> <table> <arg#1> <arg#2> ... <arg#n>
int table = errorhandler + 1;
int arg = table + 1;
luaL_checktype(L, table, LUA_TTABLE);
@ -81,8 +97,8 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
// Call function
for(int i = 0; i < nargs; i++)
lua_pushvalue(L, arg+i);
if(lua_pcall(L, nargs, 1, 0))
script_error(L, "error: %s", lua_tostring(L, -1));
if(lua_pcall(L, nargs, 1, errorhandler))
script_error(L);
// Move return value to designated space in stack
// Or pop it

View file

@ -64,9 +64,10 @@ enum RunCallbacksMode
// are converted by lua_toboolean to true or false, respectively.
};
std::string script_get_backtrace (lua_State *L);
void script_error (lua_State *L, const char *fmt, ...);
void script_run_callbacks (lua_State *L, int nargs,
RunCallbacksMode mode);
std::string script_get_backtrace(lua_State *L);
int script_error_handler(lua_State *L);
void script_error(lua_State *L);
void script_run_callbacks(lua_State *L, int nargs,
RunCallbacksMode mode);
#endif /* C_INTERNAL_H_ */

View file

@ -25,9 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
LuaError::LuaError(lua_State *L, const std::string &s)
{
m_s = "LuaError: ";
m_s += s + "\n";
m_s += script_get_backtrace(L);
m_s = "LuaError: " + s;
if (L) m_s += '\n' + script_get_backtrace(L);
}
struct EnumString es_ItemType[] =