From da7cd267eaeefb35fc21b137285fce8e2d9a2693 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 9 Aug 2014 16:04:59 -0300 Subject: [PATCH] Changed luax_pushtype to retain the pushed object itself, but only if the object isn't in the Lua state already. Previously, calling e.g. love.graphics.getFont() 10,000 times would retain the object 10,000 times (and release it 10,000 times when the Font object was garbage-collected in the Lua state.) Now it will only retain it once and release it once. --- src/common/Variant.cpp | 1 - src/common/runtime.cpp | 64 ++++++------------- src/common/runtime.h | 25 ++++---- src/modules/audio/wrap_Audio.cpp | 13 +++- src/modules/audio/wrap_Source.cpp | 1 + src/modules/filesystem/wrap_Filesystem.cpp | 9 ++- src/modules/font/freetype/wrap_Font.cpp | 4 ++ src/modules/font/wrap_Rasterizer.cpp | 1 + src/modules/graphics/opengl/wrap_Canvas.cpp | 1 + src/modules/graphics/opengl/wrap_Graphics.cpp | 27 ++++---- src/modules/graphics/opengl/wrap_Image.cpp | 6 -- src/modules/graphics/opengl/wrap_Mesh.cpp | 5 -- .../graphics/opengl/wrap_ParticleSystem.cpp | 6 +- .../graphics/opengl/wrap_SpriteBatch.cpp | 4 -- src/modules/image/wrap_Image.cpp | 3 + src/modules/joystick/wrap_JoystickModule.cpp | 1 - src/modules/math/wrap_BezierCurve.cpp | 1 + src/modules/math/wrap_Math.cpp | 2 + src/modules/mouse/wrap_Mouse.cpp | 5 +- src/modules/physics/box2d/Body.cpp | 2 +- src/modules/physics/box2d/Physics.cpp | 3 +- src/modules/physics/box2d/World.cpp | 14 +--- src/modules/physics/box2d/wrap_Body.cpp | 1 - src/modules/physics/box2d/wrap_ChainShape.cpp | 1 + src/modules/physics/box2d/wrap_Contact.cpp | 2 - src/modules/physics/box2d/wrap_Fixture.cpp | 2 +- src/modules/physics/box2d/wrap_Physics.cpp | 19 ++++++ src/modules/sound/wrap_Sound.cpp | 2 + src/modules/thread/wrap_ThreadModule.cpp | 3 + src/modules/window/wrap_Window.cpp | 3 - 30 files changed, 113 insertions(+), 118 deletions(-) diff --git a/src/common/Variant.cpp b/src/common/Variant.cpp index f37e5c7b6..654d284fa 100644 --- a/src/common/Variant.cpp +++ b/src/common/Variant.cpp @@ -226,7 +226,6 @@ void Variant::toLua(lua_State *L) { const char *name = NULL; love::types.find(udatatype, name); - ((love::Object *) data.userdata)->retain(); luax_pushtype(L, name, flags, (love::Object *) data.userdata); } else diff --git a/src/common/runtime.cpp b/src/common/runtime.cpp index eed6295c0..dd9156909 100644 --- a/src/common/runtime.cpp +++ b/src/common/runtime.cpp @@ -36,8 +36,7 @@ namespace love { -static thread::Mutex *gcmutex = 0; -void *_gcmutex = 0; +static thread::Mutex *gcmutex = nullptr; /** * Called when an object is collected. The object is released @@ -46,25 +45,16 @@ void *_gcmutex = 0; static int w__gc(lua_State *L) { if (!gcmutex) - { gcmutex = thread::newMutex(); - _gcmutex = (void *) gcmutex; - } - Proxy *p = (Proxy *)lua_touserdata(L, 1); - Object *t = (Object *)p->data; + Proxy *p = (Proxy *) lua_touserdata(L, 1); + Object *object = (Object *) p->data; thread::Lock lock(gcmutex); - int numretains = p->retains; - if (numretains >= 0) - numretains = std::min(numretains, t->getReferenceCount()); + if (p->own) + object->release(); - for (int i = numretains; i > 0; i--) - t->release(); - - // Signal that this Proxy is dead. - p->retains = -1; return 0; } @@ -228,7 +218,7 @@ int luax_register_module(lua_State *L, const WrappedModule &m) luax_insistregistry(L, REGISTRY_MODULES); Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); - p->retains = 1; + p->own = true; p->data = m.module; p->flags = m.flags; @@ -394,20 +384,26 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos) return 0; } -void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own) +void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object, bool own) { Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); - u->data = (void *) data; + if (own) + object->retain(); + + u->data = (void *) object; u->flags = flags; - u->retains = own ? 1 : 0; + u->own = own; luaL_newmetatable(L, name); lua_setmetatable(L, -2); } -void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own) +void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object, bool own) { + if (object == nullptr) + lua_pushnil(L); + // Fetch the registry table of instantiated types. luax_getregistry(L, REGISTRY_TYPES); @@ -415,11 +411,11 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *dat if (!lua_istable(L, -1)) { lua_pop(L, 1); - return luax_rawnewtype(L, name, flags, data, own); + return luax_rawnewtype(L, name, flags, object, own); } // Get the value of lovetypes[data] on the stack. - lua_pushlightuserdata(L, (void *) data); + lua_pushlightuserdata(L, (void *) object); lua_gettable(L, -2); // If the Proxy userdata isn't in the instantiated types table yet, add it. @@ -427,38 +423,18 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *dat { lua_pop(L, 1); - luax_rawnewtype(L, name, flags, data, own); + luax_rawnewtype(L, name, flags, object, own); - lua_pushlightuserdata(L, (void *) data); + lua_pushlightuserdata(L, (void *) object); lua_pushvalue(L, -2); // lovetypes[data] = Proxy. lua_settable(L, -4); - - // Remove the lovetypes table from the stack. - lua_remove(L, -2); - - // The Proxy userdata remains at the top of the stack. - return; } // Remove the lovetypes table from the stack. lua_remove(L, -2); - // If the object should be released on GC and we already have a stored - // Proxy, we should tell the Proxy that the object was retained again. - if (own) - { - Proxy *p = (Proxy *) lua_touserdata(L, -1); - - thread::EmptyLock lock; - if (gcmutex) - lock.setLock(gcmutex); - - if (p->retains >= 0) - ++(p->retains); - } - // Keep the Proxy userdata on the stack. } diff --git a/src/common/runtime.h b/src/common/runtime.h index c9c4ffafd..40c7bb0f4 100644 --- a/src/common/runtime.h +++ b/src/common/runtime.h @@ -43,9 +43,6 @@ namespace love class Module; class Reference; -// Exposed mutex of the GC -extern void *_gcmutex; - /** * Registries represent special tables which can be accessed with * luax_insistregistry and luax_getregistry. @@ -71,8 +68,8 @@ struct Proxy // The light userdata (pointer to the love::Object). void *data; - // The number of times release() should be called on GC. - int retains; + // Whether release() should be called on GC. + bool own; }; /** @@ -271,27 +268,31 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1); /** * Pushes a Lua representation of the given object onto the stack, creating and * storing the Lua representation in a weak table if it doesn't exist yet. + * NOTE: If own is true, the object will be retained by Lua. * @param L The Lua state. * @param name The name of the type. This must match the name used with luax_register_type. * @param flags The type information of the object. - * @param data The pointer to the actual object. - * @param own Set this to true (default) if the object should be released upon garbage collection. + * @param object The pointer to the actual object. + * @param own Set this to true (default) if the object should be retained by + * Lua and released upon garbage collection. **/ -void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true); +void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object, bool own = true); /** * Creates a new Lua representation of the given object *without* checking if it * exists yet, and *without* storing it in a weak table. * This should only be used when performance is an extreme concern and the * object is not ever expected to be pushed to Lua again, as it prevents the - * Lua-side objects from working in all cases when used as keys in tables. + * Lua-side objects from working in some cases when used as keys in tables. + * NOTE: if own is true, the object will be retained by Lua. * @param L The Lua state. * @param name The name of the type. This must match the name used with luax_register_type. * @param flags The type information of the object. - * @param data The pointer to the actual object. - * @param own Set this to true (default) if the object should be released upon garbage collection. + * @param object The pointer to the actual object. + * @param own Set this to true (default) if the object should be retained by + * Lua and released upon garbage collection. **/ -void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true); +void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object, bool own = true); /** * Checks whether the value at idx is a certain type. diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index 2e037260e..c2be44f85 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -63,6 +63,7 @@ int w_newSource(lua_State *L) if (t) { luax_pushtype(L, "Source", AUDIO_SOURCE_T, t); + t->release(); return 1; } else @@ -224,7 +225,10 @@ int w_getRecordedData(lua_State *L) if (!sd) lua_pushnil(L); else + { luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, sd); + sd->release(); + } return 1; } @@ -233,8 +237,13 @@ int w_stopRecording(lua_State *L) if (luax_optboolean(L, 1, true)) { love::sound::SoundData *sd = instance()->stopRecording(true); - if (!sd) lua_pushnil(L); - else luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, sd); + if (!sd) + lua_pushnil(L); + else + { + luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, sd); + sd->release(); + } return 1; } instance()->stopRecording(false); diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index 6bdd71d0d..1f199b815 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -38,6 +38,7 @@ int w_Source_clone(lua_State *L) Source *clone = nullptr; luax_catchexcept(L, [&](){ clone = t->clone(); }); luax_pushtype(L, "Source", AUDIO_SOURCE_T, clone); + clone->release(); return 1; } diff --git a/src/modules/filesystem/wrap_Filesystem.cpp b/src/modules/filesystem/wrap_Filesystem.cpp index d8e83b256..6384e7bab 100644 --- a/src/modules/filesystem/wrap_Filesystem.cpp +++ b/src/modules/filesystem/wrap_Filesystem.cpp @@ -145,6 +145,7 @@ int w_newFile(lua_State *L) } luax_pushtype(L, "File", FILESYSTEM_FILE_T, t); + t->release(); return 1; } @@ -210,6 +211,7 @@ int w_newFileData(lua_State *L) return luax_ioError(L, "%s", e.what()); } luax_pushtype(L, "FileData", FILESYSTEM_FILE_DATA_T, data); + data->release(); return 1; } else @@ -241,6 +243,7 @@ int w_newFileData(lua_State *L) } luax_pushtype(L, "FileData", FILESYSTEM_FILE_DATA_T, t); + t->release(); return 1; } @@ -403,9 +406,13 @@ int w_lines(lua_State *L) luax_catchexcept(L, [&](){ success = file->open(File::READ); }); if (!success) + { + file->release(); return luaL_error(L, "Could not open file."); - + } + luax_pushtype(L, "File", FILESYSTEM_FILE_T, file); + file->release(); } else return luaL_argerror(L, 1, "expected filename."); diff --git a/src/modules/font/freetype/wrap_Font.cpp b/src/modules/font/freetype/wrap_Font.cpp index 814e0e318..534594471 100644 --- a/src/modules/font/freetype/wrap_Font.cpp +++ b/src/modules/font/freetype/wrap_Font.cpp @@ -58,8 +58,11 @@ int w_newRasterizer(lua_State *L) [&]() { d->release(); } ); } + else + return luaL_argerror(L, 1, "expected ImageData, filename, or FileData"); luax_pushtype(L, "Rasterizer", FONT_RASTERIZER_T, t); + t->release(); return 1; } @@ -81,6 +84,7 @@ int w_newGlyphData(lua_State *L) } luax_pushtype(L, "GlyphData", FONT_GLYPH_DATA_T, t); + t->release(); return 1; } diff --git a/src/modules/font/wrap_Rasterizer.cpp b/src/modules/font/wrap_Rasterizer.cpp index 048c9edc9..99844ba86 100644 --- a/src/modules/font/wrap_Rasterizer.cpp +++ b/src/modules/font/wrap_Rasterizer.cpp @@ -87,6 +87,7 @@ int w_Rasterizer_getGlyphData(lua_State *L) }); luax_pushtype(L, "GlyphData", FONT_GLYPH_DATA_T, g); + g->release(); return 1; } diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index 92addd5ae..4777f8502 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -68,6 +68,7 @@ int w_Canvas_getImageData(lua_State *L) love::image::Image *image = luax_getmodule(L, "image", MODULE_IMAGE_T); love::image::ImageData *img = canvas->getImageData(image); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, img); + img->release(); return 1; } diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 0a88cd2f4..80c0dde59 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -222,6 +222,7 @@ int w_newImage(lua_State *L) // Push the type. luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, image); + image->release(); return 1; } @@ -238,6 +239,7 @@ int w_newQuad(lua_State *L) Quad *quad = instance()->newQuad(v, sw, sh); luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad); + quad->release(); return 1; } @@ -262,6 +264,7 @@ int w_newFont(lua_State *L) // Push the type. luax_pushtype(L, "Font", GRAPHICS_FONT_T, font); + font->release(); return 1; } @@ -302,6 +305,7 @@ int w_newImageFont(lua_State *L) // Push the type. luax_pushtype(L, "Font", GRAPHICS_FONT_T, font); + font->release(); return 1; } @@ -324,6 +328,7 @@ int w_newSpriteBatch(lua_State *L) ); luax_pushtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, t); + t->release(); return 1; } @@ -340,6 +345,7 @@ int w_newParticleSystem(lua_State *L) ); luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, t); + t->release(); return 1; } @@ -364,6 +370,7 @@ int w_newCanvas(lua_State *L) return luaL_error(L, "Canvas not created, but no error thrown. I don't even..."); luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas); + canvas->release(); return 1; } @@ -450,6 +457,7 @@ int w_newShader(lua_State *L) { Shader *shader = instance()->newShader(sources); luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader); + shader->release(); } catch (love::Exception &e) { @@ -542,6 +550,7 @@ int w_newMesh(lua_State *L) t->setTexture(tex); luax_pushtype(L, "Mesh", GRAPHICS_MESH_T, t); + t->release(); return 1; } @@ -631,7 +640,6 @@ int w_getFont(lua_State *L) if (f == 0) return 0; - f->retain(); luax_pushtype(L, "Font", GRAPHICS_FONT_T, f); return 1; } @@ -883,6 +891,7 @@ int w_newScreenshot(lua_State *L) luax_catchexcept(L, [&](){ i = instance()->newScreenshot(image, copyAlpha); }); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i); + i->release(); return 1; } @@ -931,16 +940,13 @@ int w_getCanvas(lua_State *L) const std::vector canvases = instance()->getCanvas(); int n = 0; - if (!canvases.empty()) + for (Canvas *c : canvases) { - for (Canvas *c : canvases) - { - c->retain(); - luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, c); - n++; - } + luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, c); + n++; } - else + + if (n == 0) { lua_pushnil(L); n = 1; @@ -966,10 +972,7 @@ int w_getShader(lua_State *L) { Shader *shader = instance()->getShader(); if (shader) - { - shader->retain(); luax_pushtype(L, "Shader", GRAPHICS_SHADER_T, shader); - } else lua_pushnil(L); diff --git a/src/modules/graphics/opengl/wrap_Image.cpp b/src/modules/graphics/opengl/wrap_Image.cpp index da9107e5a..c2ee5a6f7 100644 --- a/src/modules/graphics/opengl/wrap_Image.cpp +++ b/src/modules/graphics/opengl/wrap_Image.cpp @@ -93,10 +93,7 @@ int w_Image_getData(lua_State *L) { love::image::CompressedData *t = i->getCompressedData(); if (t) - { - t->retain(); luax_pushtype(L, "CompressedData", IMAGE_COMPRESSED_DATA_T, t); - } else lua_pushnil(L); } @@ -104,10 +101,7 @@ int w_Image_getData(lua_State *L) { love::image::ImageData *t = i->getImageData(); if (t) - { - t->retain(); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); - } else lua_pushnil(L); } diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index ea2928a4c..d26486b73 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -263,18 +263,13 @@ int w_Mesh_getTexture(lua_State *L) if (tex == nullptr) return 0; - tex->retain(); - // FIXME: big hack right here. if (typeid(*tex) == typeid(Image)) luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, tex); else if (typeid(*tex) == typeid(Canvas)) luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); else - { - tex->release(); return luaL_error(L, "Unable to determine texture type."); - } return 1; } diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp index 72bd113f7..62ad1a1cf 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp +++ b/src/modules/graphics/opengl/wrap_ParticleSystem.cpp @@ -52,6 +52,7 @@ int w_ParticleSystem_clone(lua_State *L) luax_catchexcept(L, [&](){ clone = t->clone(); }); luax_pushtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, clone); + clone->release(); return 1; } @@ -67,7 +68,6 @@ int w_ParticleSystem_getTexture(lua_State *L) { ParticleSystem *t = luax_checkparticlesystem(L, 1); Texture *tex = t->getTexture(); - tex->retain(); // FIXME: big hack right here. if (typeid(*tex) == typeid(Image)) @@ -75,10 +75,7 @@ int w_ParticleSystem_getTexture(lua_State *L) else if (typeid(*tex) == typeid(Canvas)) luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); else - { - tex->release(); return luaL_error(L, "Unable to determine texture type."); - } return 1; } @@ -608,7 +605,6 @@ int w_ParticleSystem_getQuads(lua_State *L) for (size_t i = 0; i < quads.size(); i++) { - quads[i]->retain(); luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quads[i]); lua_rawseti(L, -2, i + 1); } diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp index 97d2675e8..fb62b830c 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp @@ -143,7 +143,6 @@ int w_SpriteBatch_getTexture(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); Texture *tex = t->getTexture(); - tex->retain(); // FIXME: big hack right here. if (typeid(*tex) == typeid(Image)) @@ -151,10 +150,7 @@ int w_SpriteBatch_getTexture(lua_State *L) else if (typeid(*tex) == typeid(Canvas)) luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, tex); else - { - tex->release(); return luaL_error(L, "Unable to determine texture type."); - } return 1; } diff --git a/src/modules/image/wrap_Image.cpp b/src/modules/image/wrap_Image.cpp index 9f223deea..ffbccd105 100644 --- a/src/modules/image/wrap_Image.cpp +++ b/src/modules/image/wrap_Image.cpp @@ -48,6 +48,7 @@ int w_newImageData(lua_State *L) luax_catchexcept(L, [&](){ t = instance()->newImageData(w, h); }); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); + t->release(); return 1; } @@ -61,6 +62,7 @@ int w_newImageData(lua_State *L) ); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, t); + t->release(); return 1; } @@ -75,6 +77,7 @@ int w_newCompressedData(lua_State *L) ); luax_pushtype(L, "CompressedData", IMAGE_COMPRESSED_DATA_T, t); + t->release(); return 1; } diff --git a/src/modules/joystick/wrap_JoystickModule.cpp b/src/modules/joystick/wrap_JoystickModule.cpp index 0b9565afa..f70c291ce 100644 --- a/src/modules/joystick/wrap_JoystickModule.cpp +++ b/src/modules/joystick/wrap_JoystickModule.cpp @@ -40,7 +40,6 @@ int w_getJoysticks(lua_State *L) for (int i = 0; i < stickcount; i++) { Joystick *stick = instance()->getJoystick(i); - stick->retain(); luax_pushtype(L, "Joystick", JOYSTICK_JOYSTICK_T, stick); lua_rawseti(L, -2, i + 1); } diff --git a/src/modules/math/wrap_BezierCurve.cpp b/src/modules/math/wrap_BezierCurve.cpp index e13d14701..659c0bd7f 100644 --- a/src/modules/math/wrap_BezierCurve.cpp +++ b/src/modules/math/wrap_BezierCurve.cpp @@ -45,6 +45,7 @@ int w_BezierCurve_getDerivative(lua_State *L) BezierCurve *curve = luax_checkbeziercurve(L, 1); BezierCurve *deriv = new BezierCurve(curve->getDerivative()); luax_pushtype(L, "BezierCurve", MATH_BEZIER_CURVE_T, deriv); + deriv->release(); return 1; } diff --git a/src/modules/math/wrap_Math.cpp b/src/modules/math/wrap_Math.cpp index 402d7af4f..6e7c0195e 100644 --- a/src/modules/math/wrap_Math.cpp +++ b/src/modules/math/wrap_Math.cpp @@ -101,6 +101,7 @@ int w_newRandomGenerator(lua_State *L) } luax_pushtype(L, "RandomGenerator", MATH_RANDOM_GENERATOR_T, t); + t->release(); return 1; } @@ -139,6 +140,7 @@ int w_newBezierCurve(lua_State *L) BezierCurve *curve = Math::instance.newBezierCurve(points); luax_pushtype(L, "BezierCurve", MATH_BEZIER_CURVE_T, curve); + curve->release(); return 1; } diff --git a/src/modules/mouse/wrap_Mouse.cpp b/src/modules/mouse/wrap_Mouse.cpp index 1732dd9b2..7659cf7e6 100644 --- a/src/modules/mouse/wrap_Mouse.cpp +++ b/src/modules/mouse/wrap_Mouse.cpp @@ -46,6 +46,7 @@ int w_newCursor(lua_State *L) luax_catchexcept(L, [&](){ cursor = instance()->newCursor(data, hotx, hoty); }); luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); + cursor->release(); return 1; } @@ -60,7 +61,6 @@ int w_getSystemCursor(lua_State *L) Cursor *cursor = 0; luax_catchexcept(L, [&](){ cursor = instance()->getSystemCursor(systemCursor); }); - cursor->retain(); luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); return 1; } @@ -84,10 +84,7 @@ int w_getCursor(lua_State *L) Cursor *cursor = instance()->getCursor(); if (cursor) - { - cursor->retain(); luax_pushtype(L, "Cursor", MOUSE_CURSOR_T, cursor); - } else lua_pushnil(L); diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index cc18e98bd..e28d1f027 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -432,7 +432,6 @@ int Body::getFixtureList(lua_State *L) const Fixture *fixture = (Fixture *)Memoizer::find(f); if (!fixture) throw love::Exception("A fixture has escaped Memoizer!"); - fixture->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture); lua_rawseti(L, -2, i); i++; @@ -458,6 +457,7 @@ int Body::getContactList(lua_State *L) const contact->retain(); luax_pushtype(L, "Contact", PHYSICS_CONTACT_T, contact); + contact->release(); lua_rawseti(L, -2, i); i++; } diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 96bc49424..b62c17efe 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -125,8 +125,8 @@ int Physics::newPolygonShape(lua_State *L) } PolygonShape *p = new PolygonShape(s); - luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, p); + p->release(); return 1; } @@ -167,6 +167,7 @@ int Physics::newChainShape(lua_State *L) ChainShape *c = new ChainShape(s); luax_pushtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, c); + c->release(); return 1; } diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index c08846ec4..2de82e550 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/src/modules/physics/box2d/World.cpp @@ -57,10 +57,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse { Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA()); if (a != 0) - { - a->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a); - } else throw love::Exception("A fixture has escaped Memoizer!"); } @@ -69,10 +66,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse { Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB()); if (b != 0) - { - b->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b); - } else throw love::Exception("A fixture has escaped Memoizer!"); } @@ -84,6 +78,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse cobj->retain(); luax_pushtype(L, "Contact", (PHYSICS_CONTACT_T), cobj); + cobj->release(); int args = 3; if (impulse) @@ -131,8 +126,6 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b) if (ref != 0) { - a->retain(); - b->retain(); lua_State *L = ref->getL(); ref->push(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a); @@ -163,7 +156,6 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture) Fixture *f = (Fixture *)Memoizer::find(fixture); if (!f) throw love::Exception("A fixture has escaped Memoizer!"); - f->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f); lua_call(L, 1, 1); return luax_toboolean(L, -1); @@ -191,7 +183,6 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 & Fixture *f = (Fixture *)Memoizer::find(fixture); if (!f) throw love::Exception("A fixture has escaped Memoizer!"); - f->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f); b2Vec2 scaledPoint = Physics::scaleUp(point); lua_pushnumber(L, scaledPoint.x); @@ -440,7 +431,6 @@ int World::getBodyList(lua_State *L) const Body *body = (Body *)Memoizer::find(b); if (!body) throw love::Exception("A body has escaped Memoizer!"); - body->retain(); luax_pushtype(L, "Body", PHYSICS_BODY_T, body); lua_rawseti(L, -2, i); i++; @@ -459,7 +449,6 @@ int World::getJointList(lua_State *L) const if (!j) break; Joint *joint = (Joint *)Memoizer::find(j); if (!joint) throw love::Exception("A joint has escaped Memoizer!"); - joint->retain(); luax_pushtype(L, "Joint", PHYSICS_JOINT_T, joint); lua_rawseti(L, -2, i); i++; @@ -482,6 +471,7 @@ int World::getContactList(lua_State *L) const else contact->retain(); luax_pushtype(L, "Contact", PHYSICS_CONTACT_T, contact); + contact->release(); lua_rawseti(L, -2, i); i++; } diff --git a/src/modules/physics/box2d/wrap_Body.cpp b/src/modules/physics/box2d/wrap_Body.cpp index 8e97138d0..1b29613d5 100644 --- a/src/modules/physics/box2d/wrap_Body.cpp +++ b/src/modules/physics/box2d/wrap_Body.cpp @@ -526,7 +526,6 @@ int w_Body_getWorld(lua_State *L) { Body *t = luax_checkbody(L, 1); World *world = t->getWorld(); - world->retain(); luax_pushtype(L, "World", PHYSICS_WORLD_T, world); return 1; } diff --git a/src/modules/physics/box2d/wrap_ChainShape.cpp b/src/modules/physics/box2d/wrap_ChainShape.cpp index 76a1a5b90..5e20279c2 100644 --- a/src/modules/physics/box2d/wrap_ChainShape.cpp +++ b/src/modules/physics/box2d/wrap_ChainShape.cpp @@ -66,6 +66,7 @@ int w_ChainShape_getChildEdge(lua_State *L) EdgeShape *e = 0; luax_catchexcept(L, [&](){ e = c->getChildEdge(index); }); luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e); + e->release(); return 1; } diff --git a/src/modules/physics/box2d/wrap_Contact.cpp b/src/modules/physics/box2d/wrap_Contact.cpp index 7911c7ff2..e51786eb9 100644 --- a/src/modules/physics/box2d/wrap_Contact.cpp +++ b/src/modules/physics/box2d/wrap_Contact.cpp @@ -146,9 +146,7 @@ int w_Contact_getFixtures(lua_State *L) Fixture *b = nullptr; luax_catchexcept(L, [&](){ t->getFixtures(a, b); }); - a->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a); - b->retain(); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b); return 2; } diff --git a/src/modules/physics/box2d/wrap_Fixture.cpp b/src/modules/physics/box2d/wrap_Fixture.cpp index 621e58bd9..23678bc9f 100644 --- a/src/modules/physics/box2d/wrap_Fixture.cpp +++ b/src/modules/physics/box2d/wrap_Fixture.cpp @@ -111,7 +111,6 @@ int w_Fixture_getBody(lua_State *L) Body *body = t->getBody(); if (body == 0) return 0; - body->retain(); luax_pushtype(L, "Body", PHYSICS_BODY_T, body); return 1; } @@ -140,6 +139,7 @@ int w_Fixture_getShape(lua_State *L) luax_pushtype(L, "Shape", PHYSICS_SHAPE_T, shape); break; } + shape->release(); return 1; } diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index ce4e13c79..e14ea8070 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -60,6 +60,7 @@ int w_newWorld(lua_State *L) World *w; luax_catchexcept(L, [&](){ w = instance()->newWorld(gx, gy, sleep); }); luax_pushtype(L, "World", PHYSICS_WORLD_T, w); + w->release(); return 1; } @@ -78,6 +79,7 @@ int w_newBody(lua_State *L) Body *body; luax_catchexcept(L, [&](){ body = instance()->newBody(world, x, y, btype); }); luax_pushtype(L, "Body", PHYSICS_BODY_T, body); + body->release(); return 1; } @@ -89,6 +91,7 @@ int w_newFixture(lua_State *L) Fixture *fixture; luax_catchexcept(L, [&](){ fixture = instance()->newFixture(body, shape, density); }); luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture); + fixture->release(); return 1; } @@ -102,6 +105,7 @@ int w_newCircleShape(lua_State *L) CircleShape *shape; luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(radius); }); luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape); + shape->release(); return 1; } else if (top == 3) @@ -112,6 +116,7 @@ int w_newCircleShape(lua_State *L) CircleShape *shape; luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(x, y, radius); }); luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape); + shape->release(); return 1; } else @@ -129,6 +134,7 @@ int w_newRectangleShape(lua_State *L) PolygonShape *shape; luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(w, h); }); luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape); + shape->release(); return 1; } else if (top == 4 || top == 5) @@ -141,6 +147,7 @@ int w_newRectangleShape(lua_State *L) PolygonShape *shape; luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(x, y, w, h, angle); }); luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape); + shape->release(); return 1; } else @@ -156,6 +163,7 @@ int w_newEdgeShape(lua_State *L) EdgeShape *shape; luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(x1, y1, x2, y2); }); luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, shape); + shape->release(); return 1; } @@ -187,6 +195,7 @@ int w_newDistanceJoint(lua_State *L) j = instance()->newDistanceJoint(body1, body2, x1, y1, x2, y2, collideConnected); }); luax_pushtype(L, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T, j); + j->release(); return 1; } @@ -198,6 +207,7 @@ int w_newMouseJoint(lua_State *L) MouseJoint *j; luax_catchexcept(L, [&](){ j = instance()->newMouseJoint(body, x, y); }); luax_pushtype(L, "MouseJoint", PHYSICS_MOUSE_JOINT_T, j); + j->release(); return 1; } @@ -213,6 +223,7 @@ int w_newRevoluteJoint(lua_State *L) j = instance()->newRevoluteJoint(body1, body2, x, y, collideConnected); }); luax_pushtype(L, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T, j); + j->release(); return 1; } @@ -245,6 +256,7 @@ int w_newPrismaticJoint(lua_State *L) j = instance()->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); }); luax_pushtype(L, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T, j); + j->release(); return 1; } @@ -268,6 +280,7 @@ int w_newPulleyJoint(lua_State *L) j = instance()->newPulleyJoint(body1, body2, b2Vec2(gx1,gy1), b2Vec2(gx2,gy2), b2Vec2(x1,y1), b2Vec2(x2,y2), ratio, collideConnected); }); luax_pushtype(L, "PulleyJoint", PHYSICS_PULLEY_JOINT_T, j); + j->release(); return 1; } @@ -283,6 +296,7 @@ int w_newGearJoint(lua_State *L) j = instance()->newGearJoint(joint1, joint2, ratio, collideConnected); }); luax_pushtype(L, "GearJoint", PHYSICS_GEAR_JOINT_T, j); + j->release(); return 1; } @@ -311,6 +325,7 @@ int w_newFrictionJoint(lua_State *L) j = instance()->newFrictionJoint(body1, body2, xA, yA, xB, yB, collideConnected); }); luax_pushtype(L, "FrictionJoint", PHYSICS_FRICTION_JOINT_T, j); + j->release(); return 1; } @@ -339,6 +354,7 @@ int w_newWeldJoint(lua_State *L) j = instance()->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected); }); luax_pushtype(L, "WeldJoint", PHYSICS_WELD_JOINT_T, j); + j->release(); return 1; } @@ -372,6 +388,7 @@ int w_newWheelJoint(lua_State *L) j = instance()->newWheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); }); luax_pushtype(L, "WheelJoint", PHYSICS_WHEEL_JOINT_T, j); + j->release(); return 1; } @@ -390,6 +407,7 @@ int w_newRopeJoint(lua_State *L) j = instance()->newRopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected); }); luax_pushtype(L, "RopeJoint", PHYSICS_ROPE_JOINT_T, j); + j->release(); return 1; } @@ -410,6 +428,7 @@ int w_newMotorJoint(lua_State *L) luax_catchexcept(L, [&](){ j = instance()->newMotorJoint(body1, body2); }); } luax_pushtype(L, "MotorJoint", PHYSICS_MOTOR_JOINT_T, j); + j->release(); return 1; } diff --git a/src/modules/sound/wrap_Sound.cpp b/src/modules/sound/wrap_Sound.cpp index 1d211ddb1..d1efeb1ea 100644 --- a/src/modules/sound/wrap_Sound.cpp +++ b/src/modules/sound/wrap_Sound.cpp @@ -59,6 +59,7 @@ int w_newSoundData(lua_State *L) } luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, t); + t->release(); return 1; } @@ -77,6 +78,7 @@ int w_newDecoder(lua_State *L) return luaL_error(L, "Extension \"%s\" not supported.", data->getExtension().c_str()); luax_pushtype(L, "Decoder", SOUND_DECODER_T, t); + t->release(); return 1; } diff --git a/src/modules/thread/wrap_ThreadModule.cpp b/src/modules/thread/wrap_ThreadModule.cpp index c99e8472c..769867b42 100644 --- a/src/modules/thread/wrap_ThreadModule.cpp +++ b/src/modules/thread/wrap_ThreadModule.cpp @@ -55,6 +55,7 @@ int w_newThread(lua_State *L) LuaThread *t = instance()->newThread(name, data); luax_pushtype(L, "Thread", THREAD_THREAD_T, t); + t->release(); return 1; } @@ -62,6 +63,7 @@ int w_newChannel(lua_State *L) { Channel *c = instance()->newChannel(); luax_pushtype(L, "Channel", THREAD_CHANNEL_T, c); + c->release(); return 1; } @@ -70,6 +72,7 @@ int w_getChannel(lua_State *L) std::string name = luax_checkstring(L, 1); Channel *c = instance()->getChannel(name); luax_pushtype(L, "Channel", THREAD_CHANNEL_T, c); + c->release(); return 1; } diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 5982dd881..c90f29e4d 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -288,10 +288,7 @@ int w_getIcon(lua_State *L) { image::ImageData *i = instance()->getIcon(); if (i) - { - i->retain(); luax_pushtype(L, "ImageData", IMAGE_IMAGE_DATA_T, i); - } else lua_pushnil(L); return 1;