bool CLuaHandle::LoadCode(const string& code, const string& debug) { lua_settop(L, 0); int error; error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str()); if (error != 0) { logOutput.Print("Lua LoadCode loadbuffer error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_pop(L, 1); return false; } CLuaHandle* orig = activeHandle; SetActiveHandle(); error = lua_pcall(L, 0, 0, 0); SetActiveHandle(orig); if (error != 0) { logOutput.Print("Lua LoadCode pcall error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_pop(L, 1); return false; } return true; }
bool CLuaHandleSynced::LoadUnsyncedCode(const string& code, const string& debug) { lua_settop(L, 0); int error; error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str()); if (error != 0) { logOutput.Print("error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_settop(L, 0); return false; } unsyncedStr.GetRegistry(L); if (!lua_istable(L, -1)) { lua_settop(L, 0); return false; } lua_setfenv(L, -2); CLuaHandle* orig = activeHandle; SetActiveHandle(); error = lua_pcall(L, 0, 0, 0); SetActiveHandle(orig); if (error != 0) { logOutput.Print("error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_settop(L, 0); return false; } return true; }
int CLuaHandle::RunCallInTraceback(int inArgs, int outArgs, int errfuncIndex, std::string& traceback) { #if defined(__SUPPORT_SNAN__) // do not signal floating point exceptions in user Lua code feclearexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif CLuaHandle* orig = activeHandle; SetActiveHandle(); const int error = lua_pcall(L, inArgs, outArgs, errfuncIndex); SetActiveHandle(orig); if (error == 0) { // pop the error handler if (errfuncIndex != 0) { lua_remove(L, errfuncIndex); } } else { traceback = lua_tostring(L, -1); lua_pop(L, 1); if (errfuncIndex != 0) lua_remove(L, errfuncIndex); // log only errors that lead to a crash callinErrors += (error == 2); } #if defined(__SUPPORT_SNAN__) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif return error; }
void CLuaHandle::KillLua() { if (L != NULL) { CLuaHandle* orig = activeHandle; SetActiveHandle(); lua_close(L); SetActiveHandle(orig); } L = NULL; }
bool CLuaHandle::RunCallIn(const LuaHashString& hs, int inArgs, int outArgs) { CLuaHandle* orig = activeHandle; SetActiveHandle(); const int error = lua_pcall(L, inArgs, outArgs, 0); SetActiveHandle(orig); if (error != 0) { logOutput.Print("%s::RunCallIn: error = %i, %s, %s\n", GetName().c_str(), error, hs.GetString().c_str(), lua_tostring(L, -1)); lua_pop(L, 1); // log only errors that lead to a crash callinErrors += (error == 2); return false; } return true; }
bool CLuaHandle::LoadCode(const string& code, const string& debug) { lua_settop(L, 0); #if defined(__SUPPORT_SNAN__) // do not signal floating point exceptions in user Lua code feclearexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif int error; error = luaL_loadbuffer(L, code.c_str(), code.size(), debug.c_str()); if (error != 0) { logOutput.Print("Lua LoadCode loadbuffer error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_pop(L, 1); #if defined(__SUPPORT_SNAN__) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif return false; } CLuaHandle* orig = activeHandle; SetActiveHandle(); error = lua_pcall(L, 0, 0, 0); SetActiveHandle(orig); #if defined(__SUPPORT_SNAN__) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif if (error != 0) { logOutput.Print("Lua LoadCode pcall error = %i, %s, %s\n", error, debug.c_str(), lua_tostring(L, -1)); lua_pop(L, 1); return false; } return true; }
void CLuaHandleSynced::Init(const string& syncedFile, const string& unsyncedFile, const string& modes) { if (L == NULL) { return; } if (fullCtrl) { // numWeaponDefs has an extra slot for (int w = 0; w <= weaponDefHandler->numWeaponDefs; w++) { watchWeapons.push_back(false); } } const string syncedCode = LoadFile(syncedFile, modes); const string unsyncedCode = LoadFile(unsyncedFile, modes); if (syncedCode.empty() && unsyncedCode.empty()) { KillLua(); return; } // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); LUA_OPEN_LIB(L, luaopen_math); LUA_OPEN_LIB(L, luaopen_table); LUA_OPEN_LIB(L, luaopen_string); //LUA_OPEN_LIB(L, luaopen_io); //LUA_OPEN_LIB(L, luaopen_os); //LUA_OPEN_LIB(L, luaopen_package); //LUA_OPEN_LIB(L, luaopen_debug); // delete some dangerous functions lua_pushnil(L); lua_setglobal(L, "dofile"); lua_pushnil(L); lua_setglobal(L, "loadfile"); lua_pushnil(L); lua_setglobal(L, "loadlib"); lua_pushnil(L); lua_setglobal(L, "loadstring"); // replaced lua_pushnil(L); lua_setglobal(L, "require"); lua_pushnil(L); lua_setglobal(L, "rawequal"); lua_pushnil(L); lua_setglobal(L, "rawget"); lua_pushnil(L); lua_setglobal(L, "rawset"); // lua_pushnil(L); lua_setglobal(L, "getfenv"); // lua_pushnil(L); lua_setglobal(L, "setfenv"); lua_pushnil(L); lua_setglobal(L, "newproxy"); lua_pushnil(L); lua_setglobal(L, "gcinfo"); lua_pushnil(L); lua_setglobal(L, "collectgarbage"); // use gs->randFloat() for the synchronized code, and disable randomseed() // (this first copies the original functions to the registry for unsynced) if (!SyncifyRandomFuncs()) { KillLua(); return; } CLuaHandle* origHandle = activeHandle; SetActiveHandle(); synced = true; const bool haveSynced = SetupSynced(syncedCode, syncedFile); if (L == NULL) { SetActiveHandle(origHandle); return; } synced = false; const bool haveUnsynced = SetupUnsynced(unsyncedCode, unsyncedFile); if (L == NULL) { SetActiveHandle(origHandle); return; } synced = true; if (!haveSynced && !haveUnsynced) { KillLua(); SetActiveHandle(origHandle); return; } // register for call-ins eventHandler.AddClient(this); SetActiveHandle(origHandle); }