LuaValueList LuaFunction::call(const LuaValueList& args) { int err_idx = 0; int stackTop; if (_errorFunction) { // push the error function _errorFunction->pushValue(); err_idx = lua_gettop(_luaState); stackTop = err_idx; } else { stackTop = lua_gettop(_luaState); } // Push the function onto the stack this->pushValue(); // Push the arguments onto the stack for (LuaValueList::const_iterator iter = args.begin(); iter != args.end(); ++iter) { iter->pushValue(); } // actually call the function now! int err = lua_pcall(_luaState, (int) args.size(), LUA_MULTRET, err_idx); if (!err) { int numReturn = lua_gettop(_luaState) - stackTop; LuaValueList values; values.reserve(numReturn); LuaValue val; for (int i = 0; i < numReturn; ++i) { if (convert::popValue(_luaState, val)) { // Add values at the begin as the last return value is on top // of the stack. values.insert(values.begin(), val); } } if (err_idx != 0) { // Remove the error function lua_pop(_luaState, 1); } return values; } else { // Make sure that there is exactly one parameter left on the stack // If the error function didn't return anything then this will push nil // If it pushed more than one value then this will discard all of them except the last one lua_settop(_luaState, stackTop + 1); std::string err_msg; if (!lua_isstring(_luaState, -1)) { err_msg = "Invalid lua value on stack!"; lua_pop(_luaState, 1); // Remove the value on the stack } else { err_msg = convert::popValue<std::string>(_luaState); } // Throw exception with generated message LuaException exception(err_msg); if (err_idx != 0) { // Pop the error function lua_pop(_luaState, 1); } throw exception; } }
LuaValueList LuaFunction::call(const LuaValueList& args) { int err_idx = 0; int stackTop; if (errorFunction) { // push the error function errorFunction->pushValue(); err_idx = lua_gettop(luaState); stackTop = err_idx; } else { stackTop = lua_gettop(luaState); } // Push the function onto the stack this->pushValue(); // Push the arguments onto the stack for (LuaValueList::const_iterator iter = args.begin(); iter != args.end(); ++iter) { iter->pushValue(); } // actually call the function now! int err = lua_pcall(luaState, args.size(), LUA_MULTRET, err_idx); if (!err) { int numReturn = lua_gettop(luaState) - stackTop; LuaValueList values; values.reserve(numReturn); LuaValue val; for (int i = 0; i < numReturn; ++i) { auto top = lua_gettop(luaState); if (convert::popValue(luaState, val)) { top = lua_gettop(luaState); // Add values at the begin as the last return value is on top // of the stack. values.insert(values.begin(), val); } } if (err_idx != 0) { // Remove the error function lua_remove(luaState, err_idx); } return values; } else { // Throw exception with generated message LuaException exception(convert::popValue<std::string>(luaState)); if (err_idx != 0) { // Pop the error function lua_pop(luaState, 1); } throw exception; } }