aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/script/common/c_internal.cpp24
-rw-r--r--src/script/common/c_internal.h6
-rw-r--r--src/script/cpp_api/s_base.cpp7
3 files changed, 28 insertions, 9 deletions
diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp
index ddd2d184c..79063141d 100644
--- a/src/script/common/c_internal.cpp
+++ b/src/script/common/c_internal.cpp
@@ -27,10 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
std::string script_get_backtrace(lua_State *L)
{
- lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE);
+ lua_getglobal(L, "debug");
+ lua_getfield(L, -1, "traceback");
lua_call(L, 0, 1);
std::string result = luaL_checkstring(L, -1);
- lua_pop(L, 1);
+ lua_pop(L, 2);
return result;
}
@@ -46,6 +47,25 @@ int script_exception_wrapper(lua_State *L, lua_CFunction f)
return lua_error(L); // Rethrow as a Lua error.
}
+int script_error_handler(lua_State *L)
+{
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "error_handler");
+ if (!lua_isnil(L, -1)) {
+ lua_pushvalue(L, 1);
+ } else {
+ // No Lua error handler available. Call debug.traceback(tostring(#1), level).
+ lua_getglobal(L, "debug");
+ lua_getfield(L, -1, "traceback");
+ lua_getglobal(L, "tostring");
+ lua_pushvalue(L, 1);
+ lua_call(L, 1, 1);
+ }
+ lua_pushinteger(L, 2); // Stack level
+ lua_call(L, 2, 1);
+ return 1;
+}
+
/*
* Note that we can't get tracebacks for LUA_ERRMEM or LUA_ERRERR (without
* hacking Lua internals). For LUA_ERRMEM, this is because memory errors will
diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h
index 5cbcbb7db..c8bce099c 100644
--- a/src/script/common/c_internal.h
+++ b/src/script/common/c_internal.h
@@ -54,7 +54,7 @@ enum {
CUSTOM_RIDX_SCRIPTAPI,
CUSTOM_RIDX_GLOBALS_BACKUP,
CUSTOM_RIDX_CURRENT_MOD_NAME,
- CUSTOM_RIDX_BACKTRACE,
+ CUSTOM_RIDX_ERROR_HANDLER,
CUSTOM_RIDX_HTTP_API_LUA,
CUSTOM_RIDX_METATABLE_MAP,
@@ -78,7 +78,7 @@ enum {
// Pushes the error handler onto the stack and returns its index
#define PUSH_ERROR_HANDLER(L) \
- (lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE), lua_gettop((L)))
+ (lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER), lua_gettop((L)))
#define PCALL_RESL(L, RES) { \
int result_ = (RES); \
@@ -121,6 +121,8 @@ enum RunCallbacksMode
std::string script_get_backtrace(lua_State *L);
// Wrapper for CFunction calls that converts C++ exceptions to Lua errors
int script_exception_wrapper(lua_State *L, lua_CFunction f);
+// Acts as the error handler for lua_pcall
+int script_error_handler(lua_State *L);
// Takes an error from lua_pcall and throws it as a LuaError
void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index e8d973de1..b91f59613 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -103,11 +103,8 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
#endif
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
- // Add and save an error handler
- lua_getglobal(m_luastack, "debug");
- lua_getfield(m_luastack, -1, "traceback");
- lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE);
- lua_pop(m_luastack, 1); // pop debug
+ lua_pushcfunction(m_luastack, script_error_handler);
+ lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
// Add a C++ wrapper function to catch exceptions thrown in Lua -> C++ calls
#if USE_LUAJIT