From 3da07e6736bfc79fa4f61b58a65f025e0fa88c62 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 12 Apr 2019 04:12:22 +0200 Subject: [PATCH] Special case Lua copy-construction of trackable instances This fixes an crashing issue with ArdourUI.SelectionList a bug introduced in 6dc3bdf252c and 35dcd46d7d. Since removal of the special cases in 35dcd46d7d, when using a C-pointer in a std::list<>, std::list::push_back(TypeListValue) TypeListValues<>'s Head was expanded to "class*& const" implied by void ::push_back(const T& value); This resulted in lifetime issues with a classes that derive from sigc::trackable (e.g. Ardour's Selection). The reference leaves scope and isn't duplicated when it is pushed back to the std::list<>. The script scripts/select_every_2nd_region.lua crashed because entries in the SelectionList were no longer valid. Previously (before 6dc3bdf252c) TypeListValues explicitly copy-constructed the value to work around the lifetime issue. This new solution bypasses the issue by directly using the c-pointer without dereferencing it. --- libs/lua/LuaBridge/detail/CFunctions.h | 14 ++++++++++++++ libs/lua/LuaBridge/detail/Namespace.h | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libs/lua/LuaBridge/detail/CFunctions.h b/libs/lua/LuaBridge/detail/CFunctions.h index 7300e9cb70..22dc115a6a 100644 --- a/libs/lua/LuaBridge/detail/CFunctions.h +++ b/libs/lua/LuaBridge/detail/CFunctions.h @@ -1233,6 +1233,20 @@ struct CFunc return listToTableHelper (L, t->get()); } + //-------------------------------------------------------------------------- + // push back a C-pointer to a std::list + + template + static int pushbackptr (lua_State *L) + { + C * const c = Userdata::get (L, 1, false); + if (!c) { return luaL_error (L, "invalid pointer to std::list<>"); } + T * const v = Userdata::get (L, 2, true); + if (!v) { return luaL_error (L, "invalid pointer to std::list<>::value_type"); } + c->push_back (v); + return 0; + } + //-------------------------------------------------------------------------- // generate std::map from table diff --git a/libs/lua/LuaBridge/detail/Namespace.h b/libs/lua/LuaBridge/detail/Namespace.h index 5ea139ee22..76474aa703 100644 --- a/libs/lua/LuaBridge/detail/Namespace.h +++ b/libs/lua/LuaBridge/detail/Namespace.h @@ -1911,7 +1911,7 @@ public: typedef std::list LT; return beginConstStdCPtrList (name) .addFunction ("unique", (void (LT::*)())<::unique) - .addFunction ("push_back", (void (LT::*)(const TP&))<::push_back); + .addExtCFunction ("push_back", &CFunc::pushbackptr); }