inheritance cast_graph cache bug/fix

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

inheritance cast_graph cache bug/fix

eduard mueller
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

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user