mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Fix a memory leak when pushing love objects to threads which never load that object’s module (resolves issue #1267).
Also fix Variant assignment operator to call release() on the correct object. --HG-- branch : minor
This commit is contained in:
@@ -106,7 +106,7 @@ Variant::Variant(const Variant &v)
|
|||||||
{
|
{
|
||||||
if (type == STRING)
|
if (type == STRING)
|
||||||
data.string->retain();
|
data.string->retain();
|
||||||
else if (type == FUSERDATA && data.userdata != nullptr)
|
else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr)
|
||||||
((love::Object *) data.userdata)->retain();
|
((love::Object *) data.userdata)->retain();
|
||||||
else if (type == TABLE)
|
else if (type == TABLE)
|
||||||
data.table->retain();
|
data.table->retain();
|
||||||
@@ -128,7 +128,7 @@ Variant::~Variant()
|
|||||||
data.string->release();
|
data.string->release();
|
||||||
break;
|
break;
|
||||||
case FUSERDATA:
|
case FUSERDATA:
|
||||||
if (data.userdata != nullptr)
|
if (udatatype != nullptr && data.userdata != nullptr)
|
||||||
((love::Object *) data.userdata)->release();
|
((love::Object *) data.userdata)->release();
|
||||||
break;
|
break;
|
||||||
case TABLE:
|
case TABLE:
|
||||||
@@ -143,15 +143,15 @@ Variant &Variant::operator = (const Variant &v)
|
|||||||
{
|
{
|
||||||
if (v.type == STRING)
|
if (v.type == STRING)
|
||||||
v.data.string->retain();
|
v.data.string->retain();
|
||||||
else if (v.type == FUSERDATA && v.data.userdata != nullptr)
|
else if (v.type == FUSERDATA && v.udatatype != nullptr && v.data.userdata != nullptr)
|
||||||
((love::Object *) v.data.userdata)->retain();
|
((love::Object *) v.data.userdata)->retain();
|
||||||
else if (v.type == TABLE)
|
else if (v.type == TABLE)
|
||||||
v.data.table->retain();
|
v.data.table->retain();
|
||||||
|
|
||||||
if (type == STRING)
|
if (type == STRING)
|
||||||
data.string->release();
|
data.string->release();
|
||||||
else if (type == FUSERDATA && v.data.userdata != nullptr)
|
else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr)
|
||||||
((love::Object *) v.data.userdata)->release();
|
((love::Object *) data.userdata)->release();
|
||||||
else if (type == TABLE)
|
else if (type == TABLE)
|
||||||
data.table->release();
|
data.table->release();
|
||||||
|
|
||||||
|
|||||||
@@ -490,6 +490,19 @@ void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object)
|
|||||||
|
|
||||||
const char *name = type.getName();
|
const char *name = type.getName();
|
||||||
luaL_newmetatable(L, name);
|
luaL_newmetatable(L, name);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "__gc");
|
||||||
|
bool has_gc = !lua_isnoneornil(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
// Make sure mt.__gc exists, so Lua states which don't have the object's
|
||||||
|
// module loaded will still clean the object up when it's collected.
|
||||||
|
if (!has_gc)
|
||||||
|
{
|
||||||
|
lua_pushcfunction(L, w__gc);
|
||||||
|
lua_setfield(L, -2, "__gc");
|
||||||
|
}
|
||||||
|
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user