Skip to content

Commit

Permalink
Fix Lua reference leaks (fixes #638)
Browse files Browse the repository at this point in the history
  • Loading branch information
LBPHacker committed Apr 9, 2019
1 parent 783310d commit 06e2836
Show file tree
Hide file tree
Showing 21 changed files with 311 additions and 349 deletions.
1 change: 1 addition & 0 deletions src/graphics/Renderer.cpp
Expand Up @@ -18,6 +18,7 @@
#ifdef LUACONSOLE
#include "lua/LuaScriptInterface.h"
#include "lua/LuaScriptHelper.h"
#include "lua/LuaSmartRef.h"
#endif
#include "hmap.h"
#ifdef OGLR
Expand Down
1 change: 1 addition & 0 deletions src/gui/interface/Window.cpp
Expand Up @@ -80,6 +80,7 @@ void Window::RemoveComponent(Component* c)
Components.erase(Components.begin() + i);

// we're done
c->SetParentWindow(NULL);
return;
}
}
Expand Down
17 changes: 6 additions & 11 deletions src/lua/LegacyLuaAPI.cpp
Expand Up @@ -8,6 +8,7 @@
#include "Format.h"
#include "LuaScriptInterface.h"
#include "LuaScriptHelper.h"
#include "LuaSmartRef.h"
#include "Platform.h"
#include "PowderToy.h"

Expand Down Expand Up @@ -136,7 +137,7 @@ int luacon_partsread(lua_State* l)
if (i < 0 || i >= NPART)
return luaL_error(l, "array index out of bounds");

lua_rawgeti(l, LUA_REGISTRYINDEX, tptPart);
lua_rawgeti(l, LUA_REGISTRYINDEX, *tptPart);
cIndex = i;
return 1;
}
Expand Down Expand Up @@ -317,12 +318,9 @@ int luatpt_element_func(lua_State *l)
{
int element = luaL_optint(l, 2, 0);
int replace = luaL_optint(l, 3, 0);
int function;
lua_pushvalue(l, 1);
function = luaL_ref(l, LUA_REGISTRYINDEX);
if(element > 0 && element < PT_NUM)
{
lua_el_func[element] = function;
lua_el_func[element].Assign(1);
if (replace == 2)
lua_el_mode[element] = 3; //update before
else if (replace)
Expand All @@ -341,7 +339,7 @@ int luatpt_element_func(lua_State *l)
int element = luaL_optint(l, 2, 0);
if(element > 0 && element < PT_NUM)
{
lua_el_func[element] = 0;
lua_el_func[element].Clear();
lua_el_mode[element] = 0;
}
else
Expand Down Expand Up @@ -390,12 +388,9 @@ int luatpt_graphics_func(lua_State *l)
if(lua_isfunction(l, 1))
{
int element = luaL_optint(l, 2, 0);
int function;
lua_pushvalue(l, 1);
function = luaL_ref(l, LUA_REGISTRYINDEX);
if (element > 0 && element < PT_NUM)
{
lua_gr_func[element] = function;
lua_gr_func[element].Assign(1);
luacon_ren->graphicscache[element].isready = 0;
return 0;
}
Expand All @@ -409,7 +404,7 @@ int luatpt_graphics_func(lua_State *l)
int element = luaL_optint(l, 2, 0);
if (element > 0 && element < PT_NUM)
{
lua_gr_func[element] = 0;
lua_gr_func[element].Clear();
luacon_ren->graphicscache[element].isready = 0;
return 0;
}
Expand Down
16 changes: 3 additions & 13 deletions src/lua/LuaButton.cpp
Expand Up @@ -20,7 +20,7 @@ Luna<LuaButton>::RegType LuaButton::methods[] = {

LuaButton::LuaButton(lua_State * l) :
LuaComponent(l),
actionFunction(0)
actionFunction(l)
{
int posX = luaL_optinteger(l, 1, 0);
int posY = luaL_optinteger(l, 2, 0);
Expand Down Expand Up @@ -62,17 +62,7 @@ int LuaButton::enabled(lua_State * l)

int LuaButton::action(lua_State * l)
{
if(lua_type(l, 1) != LUA_TNIL)
{
luaL_checktype(l, 1, LUA_TFUNCTION);
lua_pushvalue(l, 1);
actionFunction = luaL_ref(l, LUA_REGISTRYINDEX);
}
else
{
actionFunction = 0;
}
return 0;
return actionFunction.CheckAndAssignArg1();
}

int LuaButton::text(lua_State * l)
Expand All @@ -96,7 +86,7 @@ void LuaButton::triggerAction()
if(actionFunction)
{
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
if (lua_pcall(l, 1, 0, 0))
{
ci->Log(CommandInterface::LogError, ByteString(lua_tostring(l, -1)).FromUtf8());
Expand Down
2 changes: 1 addition & 1 deletion src/lua/LuaButton.h
Expand Up @@ -13,7 +13,7 @@ class LuaScriptInterface;
class LuaButton: public LuaComponent
{
ui::Button * button;
int actionFunction;
LuaComponentCallback actionFunction;
void triggerAction();
int action(lua_State * l);
int text(lua_State * l);
Expand Down
16 changes: 3 additions & 13 deletions src/lua/LuaCheckbox.cpp
Expand Up @@ -20,7 +20,7 @@ Luna<LuaCheckbox>::RegType LuaCheckbox::methods[] = {

LuaCheckbox::LuaCheckbox(lua_State * l) :
LuaComponent(l),
actionFunction(0)
actionFunction(l)
{
int posX = luaL_optinteger(l, 1, 0);
int posY = luaL_optinteger(l, 2, 0);
Expand Down Expand Up @@ -60,17 +60,7 @@ int LuaCheckbox::checked(lua_State * l)

int LuaCheckbox::action(lua_State * l)
{
if(lua_type(l, 1) != LUA_TNIL)
{
luaL_checktype(l, 1, LUA_TFUNCTION);
lua_pushvalue(l, 1);
actionFunction = luaL_ref(l, LUA_REGISTRYINDEX);
}
else
{
actionFunction = 0;
}
return 0;
return actionFunction.CheckAndAssignArg1();
}

int LuaCheckbox::text(lua_State * l)
Expand All @@ -93,7 +83,7 @@ void LuaCheckbox::triggerAction()
if(actionFunction)
{
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
lua_pushboolean(l, checkbox->GetChecked());
if (lua_pcall(l, 2, 0, 0))
{
Expand Down
2 changes: 1 addition & 1 deletion src/lua/LuaCheckbox.h
Expand Up @@ -13,7 +13,7 @@ class LuaScriptInterface;
class LuaCheckbox: public LuaComponent
{
ui::Checkbox * checkbox;
int actionFunction;
LuaComponentCallback actionFunction;
void triggerAction();
int action(lua_State * l);
int checked(lua_State * l);
Expand Down
11 changes: 10 additions & 1 deletion src/lua/LuaComponent.cpp
Expand Up @@ -5,8 +5,17 @@
#include "LuaScriptInterface.h"
#include "gui/interface/Component.h"

int LuaComponentCallback::CheckAndAssignArg1()
{
if (lua_type(l, 1) != LUA_TNIL)
{
luaL_checktype(l, 1, LUA_TFUNCTION);
}
LuaSmartRef::Assign(1);
return 0;
}

LuaComponent::LuaComponent(lua_State * l)
LuaComponent::LuaComponent(lua_State * l) : owner_ref(LUA_REFNIL)
{
this->l = l;

Expand Down
10 changes: 9 additions & 1 deletion src/lua/LuaComponent.h
@@ -1,6 +1,7 @@
#pragma once

#include "LuaLuna.h"
#include "LuaSmartRef.h"

namespace ui
{
Expand All @@ -9,6 +10,13 @@ namespace ui

class LuaScriptInterface;

class LuaComponentCallback : public LuaSmartRef
{
public:
using LuaSmartRef::LuaSmartRef;
int CheckAndAssignArg1();
};

class LuaComponent
{
protected:
Expand All @@ -19,7 +27,7 @@ class LuaComponent
int visible(lua_State * l);
public:
LuaScriptInterface * ci;
int UserData;
int owner_ref;

ui::Component * GetComponent() { return component; }
LuaComponent(lua_State * l);
Expand Down
3 changes: 0 additions & 3 deletions src/lua/LuaLuna.h
Expand Up @@ -133,9 +133,6 @@ template <typename T> class Luna
userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
ud->pT = obj; // store pointer to object in userdata

obj->UserData = luaL_ref(L, LUA_REGISTRYINDEX);
lua_rawgeti(L, LUA_REGISTRYINDEX, obj->UserData);

luaL_getmetatable(L, T::className); // lookup metatable in Lua registry
lua_setmetatable(L, -2);
return 1; // userdata containing pointer to T object
Expand Down
7 changes: 5 additions & 2 deletions src/lua/LuaScriptHelper.h
Expand Up @@ -11,13 +11,16 @@ extern Renderer * luacon_ren;
extern bool *luacon_currentCommand;
extern String *luacon_lastError;

extern int *lua_el_func, *lua_el_mode, *lua_gr_func;
class LuaSmartRef;
extern int *lua_el_mode;
extern LuaSmartRef *lua_el_func, *lua_gr_func;

extern int getPartIndex_curIdx;
extern int tptProperties; //Table for some TPT properties
extern int tptPropertiesVersion;
extern int tptElements; //Table for TPT element names
extern int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, tptPart, cIndex;
extern int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, cIndex;
extern LuaSmartRef *tptPart;

void luaopen_eventcompat(lua_State *l);
void luacon_hook(lua_State *L, lua_Debug *ar);
Expand Down

0 comments on commit 06e2836

Please sign in to comment.