summaryrefslogtreecommitdiff
path: root/libs/lua
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-04-12 04:12:22 +0200
committerRobin Gareus <robin@gareus.org>2019-04-12 05:45:27 +0200
commit3da07e6736bfc79fa4f61b58a65f025e0fa88c62 (patch)
tree6e73ebee200d5d2f9f78578e2e2bf532579b3a3a /libs/lua
parent8dc883ebfac1560917948bc30f7f69cb8f76fc97 (diff)
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<class*>::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.
Diffstat (limited to 'libs/lua')
-rw-r--r--libs/lua/LuaBridge/detail/CFunctions.h14
-rw-r--r--libs/lua/LuaBridge/detail/Namespace.h2
2 files changed, 15 insertions, 1 deletions
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
@@ -1234,6 +1234,20 @@ struct CFunc
}
//--------------------------------------------------------------------------
+ // push back a C-pointer to a std::list<T*>
+
+ template <class T, class C>
+ static int pushbackptr (lua_State *L)
+ {
+ C * const c = Userdata::get <C> (L, 1, false);
+ if (!c) { return luaL_error (L, "invalid pointer to std::list<>"); }
+ T * const v = Userdata::get <T> (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
template <class K, class V>
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<TP> LT;
return beginConstStdCPtrList<T> (name)
.addFunction ("unique", (void (LT::*)())&LT::unique)
- .addFunction ("push_back", (void (LT::*)(const TP&))&LT::push_back);
+ .addExtCFunction ("push_back", &CFunc::pushbackptr<T, LT>);
}