[luabind] inheritance cast_graph cache bug/fix
Brought to you by:
arvidn,
daniel_wallin
From: eduard m. <mue...@go...> - 2010-10-11 18:14:14
|
Hey all, stumbled upon a bug in the inheritance cast cache. Looks like this already was broken in earlier LuaBind versions, but now got relevant with the other inheritance graph cache fix included in 0.9.1: http://github.com/luabind/luabind/commit/8e9bb9c7e909b527cd87e7976e868c17ce97eb73 Problem is: with LuaBind 0.9.1 a failed cast gets an invalid, bogus cache entry, which then results into a bogus cast when called a second time. Below is a simple test and a proposal for a fix. Maybe it would make more sense to swap the args in void cache::put, so they reflect the order of the cache_entry pair? Greets, Eduard === >>> CastCache.patch diff --git a/src/inheritance.cpp b/src/inheritance.cpp index 2e2ec90..b8467ad 100644 --- a/src/inheritance.cpp +++ b/src/inheritance.cpp @@ -190,7 +190,7 @@ std::pair<void*, int> cast_graph::impl::cast( } } - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); + m_cache.put(src, target, dynamic_id, object_offset, 0, cache::invalid); return std::pair<void*, int>((void*)0, -1); } === <<< CastCache.patch === >>> CastCacheTest.cpp extern "C" { #include "lua.h" #include "lualib.h" } #include <luabind/luabind.hpp> // ============================================================================= class CppClassBase { }; class CppClass1 : public CppClassBase { }; class CppClass2 : public CppClassBase { }; // ============================================================================= static bool is_class1(const luabind::object& Object) { try { CppClass1* pObj = luabind::object_cast<CppClass1*>(Object); assert(typeid(pObj) == typeid(CppClass1)); (void)(pObj); } catch(luabind::cast_failed&) { return false; } return true; } // ============================================================================= int main(int, char**) { lua_State* L = lua_open(); luaL_openlibs(L); luabind::open(L); luabind::module(L)[ luabind::def("is_class1", is_class1), luabind::class_<CppClassBase>("CppClassBase"), luabind::class_<CppClass1, CppClassBase>("CppClass1") .def(luabind::constructor<>()), luabind::class_<CppClass2, CppClassBase>("CppClass2") .def(luabind::constructor<>()) ]; int result = luaL_dostring(L, "local obj2 = CppClass2()\n" "assert(not is_class1(obj2))\n" // OK "assert(not is_class1(obj2))\n"); // FAILS assert(result == 0); lua_close(L); return 0; } === <<< CastCacheTest.cpp |