From: John L. <jr...@us...> - 2007-11-28 00:20:54
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv15269/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlstate.cpp Log Message: Clarify that the "index" parameter really means stack_idx Don't crash if someone calls a wxLua userdata with something other than a string in our __index function Don't use lua_rawset(L, old_top), but -3 to make sure that everything is right and we're not hiding problems Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** wxlstate.cpp 17 Nov 2007 00:15:02 -0000 1.137 --- wxlstate.cpp 28 Nov 2007 00:20:49 -0000 1.138 *************** *** 505,509 **** } ! lua_rawset(L, -3); // t["method_name"] = func lua_pop(L, 1); // pop the table from wxluaT_get we got from the wxLuaReferences registry table return true; --- 505,509 ---- } ! lua_rawset(L, -3); // t["method_name"] = closure of func (and upvalues) lua_pop(L, 1); // pop the table from wxluaT_get we got from the wxLuaReferences registry table return true; Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** wxlbind.cpp 17 Nov 2007 00:15:02 -0000 1.94 --- wxlbind.cpp 28 Nov 2007 00:20:49 -0000 1.95 *************** *** 284,308 **** int result = 0; wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); - const char *name = NULL; ! if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxluaT_tag(L, 1) == *wxlClass->class_tag)) { void *pObject = wxlua_touserdata(L, 1, false); - name = lua_tostring(L, 2); // name of the __index method called in Lua - callbase = (name[0] == '_'); ! if (callbase) ! name++; // skip past "_"[FunctionName] ! else { ! // if there's a derived method, push it onto the stack to be run ! if (wxlua_hasderivedmethod(L, pObject, name, true)) { ! found = true; ! result = 1; // the function for Lua to call } } if (!found) { --- 284,338 ---- int result = 0; wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); ! ! // // See if the function or value is in our metatable ! // if (lua_getmetatable(L, 1)) ! // { ! // lua_pushvalue(L, 2); ! // lua_rawget(L, -2); ! // ! // if (!lua_isnil(L, -1)) ! // { ! // found = true; ! // result = 1; ! // lua_remove(L, -2); // remove metatable, leave value ! // return result; ! // } ! // else ! // lua_pop(L, 2); // pop nil and metatable ! // } ! ! const char *name = lua_tostring(L, 2); // name of the __index method called in Lua ! ! if (!name) ! { ! // name is NULL if it's not a string ! wxlua_error(L, wxString::Format(_("wxLua: Attempt to call a class method using '%s' on a '%s' type."), ! lua2wx(lua_typename(L, lua_type(L, 2))).c_str(), lua2wx(wxlClass ? wxlClass->name : "").c_str())); ! } ! else if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxluaT_tag(L, 1) == *wxlClass->class_tag)) { void *pObject = wxlua_touserdata(L, 1, false); ! // check if we're to call the baseclass function or if it's a Lua derived function ! if (!found) { ! callbase = (name[0] == '_'); ! ! if (callbase) ! name++; // skip past "_"[FunctionName] ! else { ! // if there's a derived method, push it onto the stack to be run ! if (wxlua_hasderivedmethod(L, pObject, name, true)) ! { ! found = true; ! result = 1; // the function for Lua to call ! } } } + // Search through the bindings for the function to call if (!found) { *************** *** 357,361 **** if (!found) ! wxlua_error(L, wxString::Format(_("wxLua: Attempt to call an invalid method '%s'."), lua2wx(name).c_str())); return result; --- 387,394 ---- if (!found) ! { ! wxlua_error(L, wxString::Format(_("wxLua: Attempt to call an unknown method '%s' on a '%s' type."), ! lua2wx(name).c_str(), lua2wx(wxlClass ? wxlClass->name : "").c_str())); ! } return result; *************** *** 608,649 **** luaI_openlib(L, wx2lua(m_nameSpace), wxlualib, 0); - int tableOffset = lua_gettop(L); if (!lua_istable(L, -1)) { lua_pop(L, 1); // pop the nil value - // luaI_openlib should have given error message about why it couldn't - // create the table for us return false; } ! else { ! // leave the table on the stack, it's the one we'll populate ! tableOffset = lua_gettop(L); ! // Find a registered binding with the same namespace, if any, ! // and share the m_luaTable_tag to that of the previously loaded binding ! wxLuaBindingList::compatibility_iterator node = wxlState.GetLuaBindingList()->GetFirst(); ! for (; node; node = node->GetNext()) { ! wxLuaBinding* binding = node->GetData(); ! ! if ((binding->GetLuaNamespace() == m_nameSpace) && (binding->m_luaTable_tag >= 0)) ! { ! m_luaTable_tag = binding->m_luaTable_tag; ! break; ! } } ! // first time adding this namespace table ! if (m_luaTable_tag < 1) ! { ! // create a tag for the wxLua table ! m_luaTable_tag = wxlState.wxluaT_NewTag(); ! // set the table tag ! wxlState.wxluaT_SetTag(m_luaTable_tag); ! } } --- 641,680 ---- luaI_openlib(L, wx2lua(m_nameSpace), wxlualib, 0); + // luaI_openlib should have given error message about why it couldn't + // create the table for us if (!lua_istable(L, -1)) { lua_pop(L, 1); // pop the nil value return false; } ! ! ! // leave the table on the stack, it's the one we'll populate ! int tableOffset = lua_gettop(L); ! ! // Find a registered binding with the same namespace, if any, ! // and share the m_luaTable_tag to that of the previously loaded binding ! wxLuaBindingList::compatibility_iterator node = wxlState.GetLuaBindingList()->GetFirst(); ! for (; node; node = node->GetNext()) { ! wxLuaBinding* binding = node->GetData(); ! if ((binding->GetLuaNamespace() == m_nameSpace) && (binding->m_luaTable_tag >= 0)) { ! m_luaTable_tag = binding->m_luaTable_tag; ! break; } + } ! // first time adding this namespace table ! if (m_luaTable_tag < 1) ! { ! // create a tag for the wxLua table ! m_luaTable_tag = wxlState.wxluaT_NewTag(); ! // set the table tag ! wxlState.wxluaT_SetTag(m_luaTable_tag); } *************** *** 693,708 **** for (size_t i_class = 0; i_class < m_classCount; ++i_class, ++wxlClass) { ! // Create a new tag if registering types, else use tag already set ! iTag = wxlState.wxluaT_NewTag(); ! *wxlClass->class_tag = iTag; ! ! // store a lookup table for the class tags to wxLuaBindClass structs ! wxluaT_get(L, iTag); ! wxlua_pushkey_metatableClass(L); ! lua_pushlightuserdata(L, (void *)wxlClass); ! lua_rawset(L, -3); // t[name] = tag ! lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table ! ! // store a lookup table for the class names to wxLuaBindClass structs wxlua_pushkey_wxLuaClasses(L); lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) --- 724,729 ---- for (size_t i_class = 0; i_class < m_classCount; ++i_class, ++wxlClass) { ! // ------------------------------------------------------------------ ! // Add to the lookup table for "class name" to wxLuaBindClass struct wxlua_pushkey_wxLuaClasses(L); lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the classes table) *************** *** 712,722 **** lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table ! // set the metatable functions for the classes for (size_t i_func = 0; i_func < s_funcCount; ++i_func) { ! wxlState.wxluaT_SetTagMethod(iTag, s_funcTable[i_func].name, s_funcTable[i_func].func, (void *)wxlClass); } // install the table for the class lua_pushstring(L, wxlClass->name); lua_newtable(L); --- 733,763 ---- lua_remove(L, -1); // remove wxLua's registry wxLuaClasses table ! // ------------------------------------------------------------------ ! // Create a new metatable for this class with a numerical tag index ! iTag = wxlState.wxluaT_NewTag(); ! *wxlClass->class_tag = iTag; ! ! // store a lookup in the class metatable to the wxLuaBindClass struct ! wxluaT_get(L, iTag); ! wxlua_pushkey_metatableClass(L); ! lua_pushlightuserdata(L, (void *)wxlClass); ! lua_rawset(L, -3); // t[name] = tag ! ! // set the functions for the class in the metatable for (size_t i_func = 0; i_func < s_funcCount; ++i_func) { ! //wxlState.wxluaT_SetTagMethod(iTag, s_funcTable[i_func].name, s_funcTable[i_func].func, (void *)wxlClass); ! ! lua_pushstring(L, s_funcTable[i_func].name); // push method name ! lua_pushlightuserdata(L, (void *)wxlClass); // push the userdata ! lua_pushcclosure(L, s_funcTable[i_func].func, 1); // push func with wxlClass as upvalue ! lua_rawset(L, -3); // t["method_name"] = closure of func and upvalues } + lua_remove(L, -1); // remove metatable we got from wxluaT_get + + // ------------------------------------------------------------------ // install the table for the class + lua_pushstring(L, wxlClass->name); lua_newtable(L); *************** *** 743,748 **** --- 784,791 ---- } } + lua_rawset(L, -3); // same as lua_settable(L, tableOffset); + // ------------------------------------------------------------------ // Install public functions like constructors or global functions wxlMethod = wxlClass->methods; *************** *** 756,759 **** --- 799,803 ---- // that are of the same class and so they share the same tag. lua_pushstring(L, wxlMethod->name); + if (strcmp(wxlMethod->name, wxlClass->name) != 0) lua_newtable(L); *************** *** 771,775 **** lua_pushstring(L, "__call"); - //lua_pushcfunction(L, wxlMethod->func); lua_pushlightuserdata(L, &wxluabind_checkremovetable); // push tag to recognize table call lua_pushcclosure(L, wxlMethod->funcs[0].func, 1); // push func with tag as upvalue --- 815,818 ---- *************** *** 785,843 **** lua_rawset(L, -3); // same as lua_settable(L, tableOffset); ! #elif 0 // C++ constructors are cfunctions, use metatable for access to items. ! lua_pushstring(L, wxlMethod->name); ! lua_pushcfunction(L, wxlMethod->func); ! ! // Create the metatable for this cfunction ! //luaL_newmetatable(L, wxlMethod->func); // we don't need to register it ! lua_newtable(L); ! ! // create the t[__index] = { table } ! lua_pushstring(L, "__index"); ! lua_newtable(L); ! ! // add the items to the table as t[first pushed] = second pushed ! lua_pushstring(L, "key"); ! lua_pushstring(L, "value"); ! lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") ! ! ! lua_pushstring(L, "key1"); ! lua_pushstring(L, "value1"); ! lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") ! ! ! //set the table ! lua_rawset(L, -3); ! ! ! // create the t[__call] = { table } ! lua_pushstring(L, "__call"); ! lua_newtable(L); ! ! for (size_t i = 0; i < m_functionCount; ++i) ! { ! if (strcmp(m_functionArray[i].name, "wxGetCwd") == 0) ! { ! wxPrintf(wxT("Adding wxGetCwd '%s' %p\n"), lua2wx(m_functionArray[i].name).c_str(), m_functionArray[i].func); ! ! lua_pushstring(L, m_functionArray[i].name); ! lua_pushcfunction(L, m_functionArray[i].func); ! lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") ! break; ! } ! } ! //set the table ! lua_rawset(L, -3); ! //lua_pushstring(L, "__metatable"); ! //lua_pushstring(L, "Metatable is not accessible"); ! //lua_rawset(L, -3); lua_setmetatable(L, -2); ! lua_rawset(L, tableOffset); #else // C++ class constructors are cfunctions only --- 828,845 ---- lua_rawset(L, -3); // same as lua_settable(L, tableOffset); ! #elif 0 // C++ constructors are userdata, use metatable for access to items. ! // This almost works, but we need to add __call to the metatable which means ! // that if you append () to any instance of this class you call the constructor. ! lua_pushstring(L, wxlMethod->name); ! const void **ptr = (const void **)lua_newuserdata(L, sizeof(void *)); ! *ptr = wxlClass; + wxluaT_get(L, iTag); lua_setmetatable(L, -2); ! lua_rawset(L, -3); #else // C++ class constructors are cfunctions only *************** *** 859,863 **** lua_pushstring(L, wxlMethod->name); lua_pushcfunction(L, wxlMethod->funcs[0].func); ! lua_rawset(L, tableOffset); } --- 861,865 ---- lua_pushstring(L, wxlMethod->name); lua_pushcfunction(L, wxlMethod->funcs[0].func); ! lua_rawset(L, -3); } *************** *** 868,872 **** lua_pushstring(L, wxlDefine->name); lua_pushnumber(L, wxlDefine->value); ! lua_rawset(L, tableOffset); } --- 870,874 ---- lua_pushstring(L, wxlDefine->name); lua_pushnumber(L, wxlDefine->value); ! lua_rawset(L, -3); } *************** *** 877,881 **** lua_pushstring(L, wxlString->name); lua_pushstring(L, wx2lua(wxlString->value)); ! lua_rawset(L, tableOffset); } --- 879,883 ---- lua_pushstring(L, wxlString->name); lua_pushstring(L, wx2lua(wxlString->value)); ! lua_rawset(L, -3); } *************** *** 891,895 **** wxlState.wxluaT_PushUserTag(*wxlObject->pObjPtr, *wxlObject->class_tag, true); ! lua_rawset(L, tableOffset); } --- 893,897 ---- wxlState.wxluaT_PushUserTag(*wxlObject->pObjPtr, *wxlObject->class_tag, true); ! lua_rawset(L, -3); } *************** *** 900,904 **** lua_pushstring(L, wxlEvent->name); lua_pushnumber(L, *wxlEvent->eventType); ! lua_rawset(L, tableOffset); } } --- 902,906 ---- lua_pushstring(L, wxlEvent->name); lua_pushnumber(L, *wxlEvent->eventType); ! lua_rawset(L, -3); } } |