From: John L. <jr...@us...> - 2007-07-19 03:09:55
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv32730/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlcallb.cpp wxlstate.cpp wxlua_bind.cpp Log Message: Implement a better fix for the gc of duplicate pointers Don't track wxLuaFunctions, should be much faster now Make wxLuaState::RemoveTrackedMemory also clear the rest of the "tracking" info Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** wxlstate.cpp 17 Jul 2007 03:30:23 -0000 1.121 --- wxlstate.cpp 19 Jul 2007 03:09:46 -0000 1.122 *************** *** 341,346 **** } ! bool LUACALL wxlua_tpushusertag(lua_State *L, const void *u, int tag) { // Wrap the void* pointer in a newuserdata const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); --- 341,366 ---- } ! bool LUACALL wxlua_tpushusertag(lua_State *L, const void *u, int tag, bool track) { + // First check to see if we've already pushed this object into Lua. + // This avoids the problem of the gc deleting a returned pointer to a permanent object. + // Test code is this: + // il = wx.wxImageList(16,16); ... noteBook:SetImageList(il); ... local il2 = noteBook:GetImageList() + // When il2 gets gc it will delete il even though il may still be valid and used by the notebook. + + wxlua_pushkey_wxLuaObjects(L); + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the obj table) + lua_pushlightuserdata(L, (void*)u); // key on Lua's userdata + lua_rawget(L, -2); + + if (wxlua_iswxuserdata(L, -1)) + { + lua_remove(L, -2); // remove the obj table + return true; + } + + // pop the table and the nil. + lua_pop(L, 2); + // Wrap the void* pointer in a newuserdata const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); *************** *** 354,364 **** if (lua_setmetatable(L, -2) != 0) { ! wxlua_pushkey_wxLuaObjects(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the obj table) ! lua_pushlightuserdata(L, (void**)u); // key on Lua's userdata ! lua_pushnumber(L, tag); // t["lightuserdata ptr"] = tag ! lua_rawset(L, -3); ! lua_pop(L, 1); return true; --- 374,388 ---- if (lua_setmetatable(L, -2) != 0) { ! if (track) ! { ! wxlua_pushkey_wxLuaObjects(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the obj table) ! lua_pushlightuserdata(L, (void*)u); // key on Lua's userdata ! lua_pushvalue(L, -3); // push the lua userdata as the value (note: weak valued table) ! ! lua_rawset(L, -3); ! lua_pop(L, 1); // pop obj table ! } return true; *************** *** 425,428 **** --- 449,454 ---- lua_newtable(L); // metatable + lua_pushlstring(L, "__mode", 6); + // for metatable.__weak = k for weak keys, v for weak values if (weak_keys) *************** *** 441,445 **** } - lua_pushlstring(L, "__mode", 6); lua_rawset(L, -3); // set mode of main table lua_setmetatable(L, -2); // via the metatable --- 467,470 ---- *************** *** 1958,1963 **** // Create a table for all userdata that we've pushed into lua wxlua_pushkey_wxLuaObjects(L); ! lua_newtable(L); lua_rawset( L, LUA_REGISTRYINDEX ); // set the value --- 1983,1994 ---- // Create a table for all userdata that we've pushed into lua + // Use weak values so the gc works on them wxlua_pushkey_wxLuaObjects(L); ! lua_newtable(L); // main table ! lua_newtable(L); // metatable ! lua_pushlstring(L, "__mode", 6); ! lua_pushlstring(L, "v", 1); ! lua_rawset(L, -3); // set mode of main table ! lua_setmetatable(L, -2); // via the metatable lua_rawset( L, LUA_REGISTRYINDEX ); // set the value *************** *** 2222,2225 **** --- 2253,2269 ---- wxCHECK_MSG(Ok() && pObject, false, wxT("Invalid wxLuaState or object")); + lua_State* L = M_WXLSTATEDATA->m_lua_State; + + // No derived methods anymore + wxlua_removederivedmethod(L, pObject); + + // Nor are we tracking it within Lua + wxlua_pushkey_wxLuaObjects(L); + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the object table) + lua_pushlightuserdata(L, (void*)pObject); + lua_pushnil(L); // t["lightuserdata ptr"] = nil to remove it + lua_rawset(L, -3); + lua_pop(L, 1); + wxLongToLongHashMap::iterator it = M_WXLSTATEDATA->m_wxlStateData->m_trackedObjects.find((long) pObject); *************** *** 2529,2536 **** } ! bool wxLuaState::tpushusertag(const void *u, int tag) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxlua_tpushusertag(M_WXLSTATEDATA->m_lua_State, u, tag); } --- 2573,2580 ---- } ! bool wxLuaState::tpushusertag(const void *u, int tag, bool track) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxlua_tpushusertag(M_WXLSTATEDATA->m_lua_State, u, tag, track); } *************** *** 2695,2699 **** // Otherwise handle normally if (!handled) ! wxlua_tpushusertag(L, data, tag); } else --- 2739,2743 ---- // Otherwise handle normally if (!handled) ! wxlua_tpushusertag(L, data, tag, true); } else Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** wxlbind.cpp 17 Jul 2007 03:30:22 -0000 1.84 --- wxlbind.cpp 19 Jul 2007 03:09:46 -0000 1.85 *************** *** 249,267 **** wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! void* key = lua_touserdata(L, 1); ! wxlua_ttouserdata(L, 1, true); ! ! ! wxCHECK_MSG(key != 0, 0, wxT("NULL user data in wxluabind_gc_wxLuaBindClass")); ! wxlua_pushkey_wxLuaObjects(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) ! lua_pushlightuserdata(L, (void*)key); ! lua_pushnil(L); // t["lightuserdata ptr"] = nil to remove it ! lua_rawset(L, -3); ! lua_pop(L, 1); wxlState.RemoveTrackedObject(key, true); - wxlua_removederivedmethod(L, key); } --- 249,259 ---- wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); ! void* key = wxlua_ttouserdata(L, 1, true); ! //wxPrintf(wxT("__gcClass '%s' %p\n"), wxlState.GetLuaTagName(*wxlClass->class_tag).c_str(), key); ! //wxCHECK_MSG(key != 0, 0, wxT("NULL user data in wxluabind_gc_wxLuaBindClass")); + // clean up the rest of this, this won't error if the key doesn't exist wxlState.RemoveTrackedObject(key, true); } *************** *** 331,335 **** result = 1; wxLuaFunction *wxlFunc = new wxLuaFunction(wxlMethod, pObject); ! wxlua_tpushusertag(L, wxlFunc, g_wxluatag_wxLuaFunction); } } --- 323,328 ---- result = 1; wxLuaFunction *wxlFunc = new wxLuaFunction(wxlMethod, pObject); ! // Don't track the wxLuaFunction for speed ! wxlua_tpushusertag(L, wxlFunc, g_wxluatag_wxLuaFunction, false); } } *************** *** 913,919 **** if (wxlObject->objPtr != 0) ! wxlState.tpushusertag(wxlObject->objPtr, *wxlObject->class_tag); else ! wxlState.tpushusertag(*wxlObject->pObjPtr, *wxlObject->class_tag); lua_rawset(L, tableOffset); --- 906,912 ---- if (wxlObject->objPtr != 0) ! wxlState.tpushusertag(wxlObject->objPtr, *wxlObject->class_tag, true); else ! wxlState.tpushusertag(*wxlObject->pObjPtr, *wxlObject->class_tag, true); lua_rawset(L, tableOffset); Index: wxlcallb.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlcallb.cpp,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** wxlcallb.cpp 14 Jun 2007 23:59:48 -0000 1.32 --- wxlcallb.cpp 19 Jul 2007 03:09:46 -0000 1.33 *************** *** 42,46 **** // Do not install this invalid or unknown event type since we won't know // what wxEvent type class to use and someone probably made a mistake. ! wxString msg = wxString::Format(wxT("Invalid or unknown wxEventType : %d, winIds %d %d."), (int)eventType, winId, lastId); m_wxlState.terror(msg); --- 42,46 ---- // Do not install this invalid or unknown event type since we won't know // what wxEvent type class to use and someone probably made a mistake. ! wxString msg = wxString::Format(wxT("Invalid or unknown wxEventType : %d, winIds %d %d."), (int)eventType, winId, lastId); m_wxlState.terror(msg); *************** *** 132,136 **** int event_tag = 0; ! // If !m_wxlBindEvent, we would have errored in the constructor, but... if (m_wxlBindEvent != NULL) event_tag = *m_wxlBindEvent->class_tag; --- 132,136 ---- int event_tag = 0; ! // If !m_wxlBindEvent, we would have errored in the constructor, but... if (m_wxlBindEvent != NULL) event_tag = *m_wxlBindEvent->class_tag; *************** *** 145,149 **** if (wxlState.lua_SetFenv(-2) != 0) { ! wxlState.tpushusertag(event, event_tag); wxlState.LuaPCall(1, 0); } --- 145,149 ---- if (wxlState.lua_SetFenv(-2) != 0) { ! wxlState.tpushusertag(event, event_tag, true); wxlState.LuaPCall(1, 0); } *************** *** 154,158 **** wxlState.terror("wxLua: wxEvtHandler::Connect in wxLuaCallback::CallFunction: function has been garbage collected."); ! wxlState.lua_SetTop(oldTop); // pop function from the stack (if it's there) } --- 154,158 ---- wxlState.terror("wxLua: wxEvtHandler::Connect in wxLuaCallback::CallFunction: function has been garbage collected."); ! wxlState.lua_SetTop(oldTop); // pop function from the stack (if it's there) } Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** wxlua_bind.cpp 16 Jul 2007 19:35:30 -0000 1.7 --- wxlua_bind.cpp 19 Jul 2007 03:09:47 -0000 1.8 *************** *** 718,724 **** lua_pushstring(L, "object"); if (wxlObject->objPtr != 0) ! wxlState.tpushusertag(wxlObject->objPtr, *wxlObject->class_tag); else ! wxlState.tpushusertag(*wxlObject->pObjPtr, *wxlObject->class_tag); lua_rawset(L, -3); --- 718,724 ---- lua_pushstring(L, "object"); if (wxlObject->objPtr != 0) ! wxlState.tpushusertag(wxlObject->objPtr, *wxlObject->class_tag, false); else ! wxlState.tpushusertag(*wxlObject->pObjPtr, *wxlObject->class_tag, false); lua_rawset(L, -3); |