13
0

Special case Lua copy-construction of trackable instances

This fixes an crashing issue with ArdourUI.SelectionList a bug
introduced in 6dc3bdf252 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 6dc3bdf252) 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.
This commit is contained in:
Robin Gareus 2019-04-12 04:12:22 +02:00
parent 8dc883ebfa
commit 3da07e6736
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 15 additions and 1 deletions

View File

@ -1233,6 +1233,20 @@ struct CFunc
return listToTableHelper<T, C> (L, t->get());
}
//--------------------------------------------------------------------------
// 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

View File

@ -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>);
}