From: John L. <jr...@us...> - 2010-12-03 04:39:51
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv5929/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlcallb.cpp wxlstate.cpp wxlua_bind.cpp Log Message: Fix wxLuaObject to take a lua_State for all functions so that it works with coroutines. Send an error message in Lua is trying to install a wxEventHandler from a coroutine since a) it will only be called when the thread is suspended or dead b) we cannot track when the coroutine state is closed so we will call an invalid lua_State Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.188 retrieving revision 1.189 diff -C2 -d -r1.188 -r1.189 *** wxlstate.cpp 30 Jan 2010 19:00:49 -0000 1.188 --- wxlstate.cpp 3 Dec 2010 04:39:43 -0000 1.189 *************** *** 559,563 **** lua_pop(L, 1); // pop delobj table ! // delete the object using the function stored in the wxLuaBindClass if (obj_ptr) --- 559,563 ---- lua_pop(L, 1); // pop delobj table ! // delete the object using the function stored in the wxLuaBindClass if (obj_ptr) *************** *** 1942,1945 **** --- 1942,1946 ---- // already have a method, delete it before replacing it wxLuaObject* o = (wxLuaObject*)lua_touserdata( L, -1 ); + o->RemoveReference(L); delete o; } *************** *** 1984,1988 **** { // if we've got the object, put it on top of the stack ! if (push_method && wxlObj->GetObject()) found = true; else if (!push_method) --- 1985,1989 ---- { // if we've got the object, put it on top of the stack ! if (push_method && wxlObj->GetObject(L)) found = true; else if (!push_method) *************** *** 2014,2017 **** --- 2015,2019 ---- { wxLuaObject* o = (wxLuaObject*)lua_touserdata(L, -1); + o->RemoveReference(L); delete o; } *************** *** 2642,2646 **** wxlState = (wxLuaState*)lua_touserdata( L, -1 ); ! lua_pop(L, 1); // pop the wxLuaStateRefData or nil on failure if (wxlState && (wxlState->GetLuaState() != L)) --- 2644,2648 ---- wxlState = (wxLuaState*)lua_touserdata( L, -1 ); ! lua_pop(L, 1); // pop the wxLuaState or nil on failure if (wxlState && (wxlState->GetLuaState() != L)) *************** *** 3432,3436 **** lua_remove(M_WXLSTATEDATA->m_lua_State, index); } ! void wxLuaState::lua_Pop(int count) { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); --- 3434,3438 ---- lua_remove(M_WXLSTATEDATA->m_lua_State, index); } ! void wxLuaState::lua_Pop(int count) const { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -d -r1.128 -r1.129 *** wxlbind.cpp 30 Jan 2010 19:00:48 -0000 1.128 --- wxlbind.cpp 3 Dec 2010 04:39:43 -0000 1.129 *************** *** 70,76 **** --- 70,94 ---- m_reference = m_wxlState->wxluaR_Ref(stack_idx, &wxlua_lreg_refs_key); } + wxLuaObject::wxLuaObject(lua_State* L, int stack_idx) + : m_alloc_flag(wxLUAOBJECT_NONE), + m_int(0) // GCC only wants one initializer + + { + m_wxlState = new wxLuaState(L, wxLUASTATE_GETSTATE); + + // set up the reference to the item on the stack + m_reference = m_wxlState->wxluaR_Ref(stack_idx, &wxlua_lreg_refs_key); + } wxLuaObject::~wxLuaObject() { + if ((m_reference != LUA_NOREF) && m_wxlState->Ok() && !m_wxlState->IsClosing()) + { + m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key); + m_reference = LUA_NOREF; + } + else if (!m_wxlState->IsClosing()) + wxPrintf(wxT("~wxLuaObject %d %d %d\n"), (int)m_reference, (int)m_wxlState->Ok(), (int)m_wxlState->IsClosing()); + if (m_alloc_flag == wxLUAOBJECT_STRING) delete m_string; *************** *** 78,98 **** delete m_arrayInt; - // If a refererence exists, remove it, but don't bother if Lua is being closed - if ((m_reference != LUA_NOREF) && m_wxlState->Ok() && !m_wxlState->IsClosing()) - m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key); - delete m_wxlState; } ! wxLuaState wxLuaObject::GetwxLuaState() const { ! return (m_wxlState != NULL) ? *m_wxlState : wxNullLuaState; } ! bool wxLuaObject::GetObject() { - wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState")); - lua_State* L = m_wxlState->GetLuaState(); - if (m_alloc_flag == wxLUAOBJECT_BOOL) { --- 96,113 ---- delete m_arrayInt; delete m_wxlState; } ! void wxLuaObject::RemoveReference(lua_State* L) { ! // If a refererence exists, remove it, but don't bother if Lua is being closed ! if ((m_reference != LUA_NOREF) && m_wxlState->Ok() && !m_wxlState->IsClosing()) ! wxluaR_unref(L, m_reference, &wxlua_lreg_refs_key); ! ! m_reference = LUA_NOREF; } ! bool wxLuaObject::GetObject(lua_State* L) { if (m_alloc_flag == wxLUAOBJECT_BOOL) { *************** *** 115,119 **** return true; } ! else if (wxluaR_getref(L, m_reference, &wxlua_lreg_refs_key)) return true; --- 130,134 ---- return true; } ! else if ((m_reference != LUA_NOREF) && wxluaR_getref(L, m_reference, &wxlua_lreg_refs_key)) return true; *************** *** 121,174 **** } ! void wxLuaObject::SetObject(int stack_idx) { ! wxCHECK_RET(m_wxlState->Ok(), wxT("Invalid wxLuaState")); if (m_reference != LUA_NOREF) // FIXME should this error out? ! m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key); ! m_reference = m_wxlState->wxluaR_Ref(stack_idx, &wxlua_lreg_refs_key); } ! bool *wxLuaObject::GetBoolPtr() { ! wxCHECK_MSG(m_wxlState->Ok(), 0, wxT("Invalid wxLuaState")); ! wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetBoolPtr")); ! if ((m_reference != LUA_NOREF) && GetObject()) { ! m_bool = (m_wxlState->lua_ToBoolean(-1) != 0); ! m_alloc_flag = wxLUAOBJECT_BOOL; ! m_wxlState->lua_Pop(1); } return &m_bool; } ! int *wxLuaObject::GetIntPtr() { ! wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState")); ! wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetIntPtr")); ! if ((m_reference != LUA_NOREF) && GetObject()) { ! m_int = (int)m_wxlState->lua_ToNumber(-1); ! m_alloc_flag = wxLUAOBJECT_INT; ! m_wxlState->lua_Pop(1); } return &m_int; } ! wxString *wxLuaObject::GetStringPtr() { ! wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState")); ! wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetStringPtr")); ! ! m_string = new wxString(); // create valid string for return ! if ((m_reference != LUA_NOREF) && GetObject()) { ! *m_string = m_wxlState->lua_TowxString(-1); ! m_alloc_flag = wxLUAOBJECT_STRING; ! m_wxlState->lua_Pop(1); } --- 136,200 ---- } ! void wxLuaObject::SetObject(lua_State* L, int stack_idx) { ! wxCHECK_RET(m_alloc_flag == wxLUAOBJECT_NONE, wxT("wxLuaObject already initialized by wxLuaObject::GetXXXPtr")); if (m_reference != LUA_NOREF) // FIXME should this error out? ! wxluaR_unref(L, m_reference, &wxlua_lreg_refs_key); ! m_reference = wxluaR_ref(L, stack_idx, &wxlua_lreg_refs_key); } ! bool *wxLuaObject::GetBoolPtr(lua_State* L) { ! wxCHECK_MSG((m_alloc_flag == wxLUAOBJECT_NONE) || (m_alloc_flag == wxLUAOBJECT_BOOL), ! 0, wxT("wxLuaObject already initialized in wxLuaObject::GetBoolPtr")); ! if (m_alloc_flag == wxLUAOBJECT_NONE) { ! if ((m_reference != LUA_NOREF) && GetObject(L)) ! { ! m_bool = (lua_toboolean(L, -1) != 0); ! m_alloc_flag = wxLUAOBJECT_BOOL; ! lua_pop(L, 1); ! } } + return &m_bool; } ! int *wxLuaObject::GetIntPtr(lua_State* L) { ! wxCHECK_MSG((m_alloc_flag == wxLUAOBJECT_NONE) || (m_alloc_flag == wxLUAOBJECT_INT), ! 0, wxT("wxLuaObject already initialized in wxLuaObject::GetIntPtr")); ! if (m_alloc_flag == wxLUAOBJECT_NONE) { ! if ((m_reference != LUA_NOREF) && GetObject(L)) ! { ! m_int = (int)lua_tonumber(L, -1); ! m_alloc_flag = wxLUAOBJECT_INT; ! lua_pop(L, 1); ! } } + return &m_int; } ! wxString *wxLuaObject::GetStringPtr(lua_State* L) { ! wxCHECK_MSG((m_alloc_flag == wxLUAOBJECT_NONE) || (m_alloc_flag == wxLUAOBJECT_STRING), ! 0, wxT("wxLuaObject already initialized in wxLuaObject::GetStringPtr")); ! if (m_alloc_flag == wxLUAOBJECT_NONE) { ! m_string = new wxString(); // create valid string for return ! ! if ((m_reference != LUA_NOREF) && GetObject(L)) ! { ! *m_string = lua2wx(lua_tostring(L, -1)); ! m_alloc_flag = wxLUAOBJECT_STRING; ! lua_pop(L, 1); ! } } *************** *** 176,192 **** } ! wxArrayInt *wxLuaObject::GetArrayPtr() { ! wxCHECK_MSG(m_wxlState->Ok(), false, wxT("Invalid wxLuaState")); ! wxCHECK_MSG(m_alloc_flag == wxLUAOBJECT_NONE, 0, wxT("wxLuaObject already initialized in wxLuaObject::GetArrayPtr")); ! ! m_arrayInt = new wxArrayInt(); // create valid array for return ! if ((m_reference != LUA_NOREF) && GetObject()) { ! *m_arrayInt = (wxArrayInt&)m_wxlState->GetwxArrayInt(-1); // coerce wxLuaSmartwxArrayInt ! m_alloc_flag = wxLUAOBJECT_ARRAYINT; ! m_wxlState->lua_Pop(1); } return m_arrayInt; } --- 202,222 ---- } ! wxArrayInt *wxLuaObject::GetArrayPtr(lua_State* L) { ! wxCHECK_MSG((m_alloc_flag == wxLUAOBJECT_NONE) || (m_alloc_flag == wxLUAOBJECT_ARRAYINT), ! 0, wxT("wxLuaObject already initialized in wxLuaObject::GetArrayPtr")); ! if (m_alloc_flag == wxLUAOBJECT_NONE) { ! m_arrayInt = new wxArrayInt(); // create valid array for return ! ! if ((m_reference != LUA_NOREF) && GetObject(L)) ! { ! *m_arrayInt = (wxArrayInt&)wxlua_getwxArrayInt(L, -1); // coerce wxLuaSmartwxArrayInt ! m_alloc_flag = wxLUAOBJECT_ARRAYINT; ! lua_pop(L, 1); ! } } + return m_arrayInt; } *************** *** 384,388 **** if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_GETPROP)) { ! // The user wants to call the C++ function as a property // which is treated as though it were a member variable. // It shouldn't have been called as a function with () --- 414,418 ---- if (WXLUA_HASBIT(wxlMethod->method_type, WXLUAMETHOD_GETPROP)) { ! // The user wants to call the C++ function as a property // which is treated as though it were a member variable. // It shouldn't have been called as a function with () *************** *** 512,520 **** { found = true; - wxLuaState wxlState(L); - wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); void *obj_ptr = wxlua_touserdata(L, 1, false); ! wxLuaObject* wxlObj = new wxLuaObject(wxlState, 3); wxlua_setderivedmethod(L, obj_ptr, name, wxlObj); } --- 542,548 ---- { found = true; void *obj_ptr = wxlua_touserdata(L, 1, false); ! wxLuaObject* wxlObj = new wxLuaObject(L, 3); wxlua_setderivedmethod(L, obj_ptr, name, wxlObj); } *************** *** 1588,1592 **** // update if a binding was added or removed ! if ((sm_bindingArray_initialized == binding_count) && !force_update) return; --- 1616,1620 ---- // update if a binding was added or removed ! if ((sm_bindingArray_initialized == binding_count) && !force_update) return; Index: wxlcallb.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlcallb.cpp,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** wxlcallb.cpp 21 Dec 2009 04:06:14 -0000 1.62 --- wxlcallb.cpp 3 Dec 2010 04:39:43 -0000 1.63 *************** *** 53,56 **** --- 53,67 ---- wxCHECK_MSG(wxlState.Ok(), wxT("Invalid wxLuaState"), wxT("Invalid wxLuaState")); + // We must always be installed into the main lua_State, never a coroutine + // 1) It will be called only when the lua_State is suspended or dead + // 2) We have no way of tracking when the coroutine state is garbage collected/dead + if (lua_pushthread(wxlState.GetLuaState()) != 1) + { + wxlState.lua_Pop(1); + return wxT("wxLua: Creating a callback function in a coroutine is not allowed since it will only be called when the thread is either suspended or dead."); + } + + wxlState.lua_Pop(1); + m_wxlState = wxlState; m_evtHandler = evtHandler; *************** *** 94,101 **** { return wxString::Format(wxT("%s(%d) -> wxLuaEventCallback(%p, ids %d, %d)|wxEvtHandler(%p) -> %s : %s"), ! lua2wx(m_wxlBindEvent ? m_wxlBindEvent->name : "?NULL?").c_str(), (int)GetEventType(), this, m_id, m_last_id, ! m_evtHandler, m_evtHandler ? m_evtHandler->GetClassInfo()->GetClassName() : wxT("?NULL?"), m_wxlState.GetwxLuaTypeName(m_wxlBindEvent ? *m_wxlBindEvent->wxluatype : WXLUA_TUNKNOWN).c_str()); --- 105,112 ---- { return wxString::Format(wxT("%s(%d) -> wxLuaEventCallback(%p, ids %d, %d)|wxEvtHandler(%p) -> %s : %s"), ! lua2wx(m_wxlBindEvent ? m_wxlBindEvent->name : "?NULL?").c_str(), (int)GetEventType(), this, m_id, m_last_id, ! m_evtHandler, m_evtHandler ? m_evtHandler->GetClassInfo()->GetClassName() : wxT("?NULL?"), m_wxlState.GetwxLuaTypeName(m_wxlBindEvent ? *m_wxlBindEvent->wxluatype : WXLUA_TUNKNOWN).c_str()); *************** *** 188,195 **** } else ! wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), function is not a Lua function."); } else ! wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), function to call is not refed."); wxlState.lua_SetTop(oldTop); // pop function and error message from the stack (if they're there) --- 199,206 ---- } else ! wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), callback function is not a Lua function."); } else ! wxlState.wxlua_Error("wxLua: wxEvtHandler::Connect() in wxLuaEventCallback::OnEvent(), callback function to call is not refed."); wxlState.lua_SetTop(oldTop); // pop function and error message from the stack (if they're there) Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** wxlua_bind.cpp 21 Dec 2009 04:06:14 -0000 1.36 --- wxlua_bind.cpp 3 Dec 2010 04:39:43 -0000 1.37 *************** *** 86,90 **** wxLuaObject *self = (wxLuaObject *)wxluaT_getuserdatatype(L, 1, wxluatype_wxLuaObject); // call GetObject that push the item onto the stack, or nil ! if (self->GetObject()) return 1; --- 86,90 ---- wxLuaObject *self = (wxLuaObject *)wxluaT_getuserdatatype(L, 1, wxluatype_wxLuaObject); // call GetObject that push the item onto the stack, or nil ! if (self->GetObject(L)) return 1; *************** *** 103,107 **** wxLuaObject *self = (wxLuaObject *)wxluaT_getuserdatatype(L, 1, wxluatype_wxLuaObject); // call SetObject ! self->SetObject(1); // return the number of parameters return 0; --- 103,107 ---- wxLuaObject *self = (wxLuaObject *)wxluaT_getuserdatatype(L, 1, wxluatype_wxLuaObject); // call SetObject ! self->SetObject(L, 1); // return the number of parameters return 0; *************** *** 118,126 **** static int LUACALL wxLua_wxLuaObject_constructor(lua_State *L) { - wxLuaState wxlState(L); - wxLuaObject *returns; // call constructor ! returns = new wxLuaObject(wxlState, 1); // add to tracked memory list wxluaO_addgcobject(L, returns, wxluatype_wxLuaObject); --- 118,124 ---- static int LUACALL wxLua_wxLuaObject_constructor(lua_State *L) { wxLuaObject *returns; // call constructor ! returns = new wxLuaObject(L, 1); // add to tracked memory list wxluaO_addgcobject(L, returns, wxluatype_wxLuaObject); |