// this function just calls lua_pcall and checks for errors
static PushedObject callRaw(lua_State* state, PushedObject functionAndArguments, const int outArguments)
{
+ // provide traceback handler
+ int tbindex = lua_gettop(state) - (functionAndArguments.getNum() - 1);
+ lua_pushcfunction(state, gettraceback);
+
+ // move it back up, before our function and arguments
+ lua_insert(state, tbindex);
+
// calling pcall automatically pops the parameters and pushes output
- const auto pcallReturnValue = lua_pcall(state, functionAndArguments.getNum() - 1, outArguments, 0);
+ const auto pcallReturnValue = lua_pcall(state, functionAndArguments.getNum() - 1, outArguments, tbindex);
functionAndArguments.release();
+ lua_remove(state, tbindex); // remove traceback function
+
+
// if pcall failed, analyzing the problem and throwing
if (pcallReturnValue != 0) {
+
+ // stack top: {error, traceback}
+ lua_rawgeti(state, -1, 1); // stack top: {error, traceback}, error
+ lua_rawgeti(state, -2, 2); // stack top: {error, traceback}, error, traceback
+ lua_remove(state, -3); // stack top: error, traceback
+
+ PushedObject traceBackRef{state, 1};
+ const auto traceBack = readTopAndPop<std::string>(state, std::move(traceBackRef)); // stack top: error
PushedObject errorCode{state, 1};
- // an error occured during execution, either an error message or a std::exception_ptr was pushed on the stack
+ // an error occurred during execution, either an error message or a std::exception_ptr was pushed on the stack
if (pcallReturnValue == LUA_ERRMEM) {
throw std::bad_alloc{};