diff options
author | kwolekr <kwolekr@minetest.net> | 2015-08-05 00:49:35 -0400 |
---|---|---|
committer | kwolekr <kwolekr@minetest.net> | 2015-08-05 21:13:03 -0400 |
commit | bcf47bc67cf3e1c2f410a81e26ceab1bdab06b4a (patch) | |
tree | 11bd99b70ceb33175d7883cea4ab287cc5b09175 /src/script/common | |
parent | 3183d5a4038f16b5b4cbcfd0dac5f8d458bf8ba2 (diff) | |
download | minetest-bcf47bc67cf3e1c2f410a81e26ceab1bdab06b4a.tar.gz minetest-bcf47bc67cf3e1c2f410a81e26ceab1bdab06b4a.tar.bz2 minetest-bcf47bc67cf3e1c2f410a81e26ceab1bdab06b4a.zip |
Improve Script CPP API diagnostics
Diffstat (limited to 'src/script/common')
-rw-r--r-- | src/script/common/c_internal.cpp | 62 | ||||
-rw-r--r-- | src/script/common/c_internal.h | 17 |
2 files changed, 65 insertions, 14 deletions
diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 8cf39dc3a..bebf6ee69 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -69,11 +69,51 @@ int script_exception_wrapper(lua_State *L, lua_CFunction f) return lua_error(L); // Rethrow as a Lua error. } -void script_error(lua_State *L) +/* + * 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 + * not execute the the error handler, and by the time lua_pcall returns the + * execution stack will have already been unwound. For LUA_ERRERR, there was + * another error while trying to generate a backtrace from a LUA_ERRRUN. It is + * presumed there is an error with the internal Lua state and thus not possible + * to gather a coherent backtrace. Realistically, the best we can do here is + * print which C function performed the failing pcall. + */ +void script_error(lua_State *L, int pcall_result, const char *fxn) { - const char *s = lua_tostring(L, -1); - std::string str(s ? s : ""); - throw LuaError(str); + if (pcall_result == 0) + return; + + const char *err_type; + switch (pcall_result) { + case LUA_ERRRUN: + err_type = "Runtime"; + break; + case LUA_ERRMEM: + err_type = "OOM"; + break; + case LUA_ERRERR: + err_type = "Double fault"; + break; + default: + err_type = "Unknown"; + } + + const char *err_descr = lua_tostring(L, -1); + if (!err_descr) + err_descr = "<no description>"; + + std::string err_msg(err_type); + if (fxn) { + err_msg += " error in "; + err_msg += fxn; + err_msg += "(): "; + } else { + err_msg += " error: "; + } + err_msg += err_descr; + + throw LuaError(err_msg); } // Push the list of callbacks (a lua table). @@ -82,7 +122,8 @@ void script_error(lua_State *L) // - runs the callbacks // - replaces the table and arguments with the return value, // computed depending on mode -void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) +void script_run_callbacks_f(lua_State *L, int nargs, + RunCallbacksMode mode, const char *fxn) { FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments"); @@ -104,14 +145,12 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) // Stack now looks like this: // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n> - if (lua_pcall(L, nargs + 2, 1, errorhandler)) { - script_error(L); - } + script_error(L, lua_pcall(L, nargs + 2, 1, errorhandler), fxn); lua_remove(L, -2); // Remove error handler } -void log_deprecated(lua_State *L, std::string message) +void log_deprecated(lua_State *L, const std::string &message) { static bool configured = false; static bool dolog = false; @@ -131,9 +170,10 @@ void log_deprecated(lua_State *L, std::string message) if (doerror) { if (L != NULL) { - script_error(L); + script_error(L, LUA_ERRRUN, NULL); } else { - FATAL_ERROR("Can't do a scripterror for this deprecated message, so exit completely!"); + FATAL_ERROR("Can't do a scripterror for this deprecated message, " + "so exit completely!"); } } diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h index eb9181b09..54cdd7da7 100644 --- a/src/script/common/c_internal.h +++ b/src/script/common/c_internal.h @@ -34,6 +34,16 @@ extern "C" { #include "common/c_types.h" +#define PCALL_RESL(L, RES) do { \ + int result_ = (RES); \ + if (result_ != 0) { \ + script_error((L), result_, __FUNCTION__); \ + } \ +} while (0) + +#define script_run_callbacks(L, nargs, mode) \ + script_run_callbacks_f((L), (nargs), (mode), __FUNCTION__) + // What script_run_callbacks does with the return values of callbacks. // Regardless of the mode, if only one callback is defined, // its return value is the total return value. @@ -67,8 +77,9 @@ enum RunCallbacksMode std::string script_get_backtrace(lua_State *L); int script_error_handler(lua_State *L); int script_exception_wrapper(lua_State *L, lua_CFunction f); -void script_error(lua_State *L); -void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode); -void log_deprecated(lua_State *L, std::string message); +void script_error(lua_State *L, int pcall_result, const char *fxn); +void script_run_callbacks_f(lua_State *L, int nargs, + RunCallbacksMode mode, const char *fxn); +void log_deprecated(lua_State *L, const std::string &message); #endif /* C_INTERNAL_H_ */ |