Skip to content

Commit

Permalink
Fix weak_ref bug.
Browse files Browse the repository at this point in the history
See http://lua.2524044.n2.nabble.com/weak-ref-issue-patch-td7581558.html for an
explanation and a patch for an older luabind version, which I have just adapted.

Quote:
> This prevents the same id from being used by two weak_refs at the same time,
> which previously could result in the Lua portion of a wrap_base derived class
> from being lost or aliased by another object.
  • Loading branch information
Oberon00 committed Mar 27, 2013
1 parent 31fbf60 commit a3a400e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
33 changes: 31 additions & 2 deletions src/weak_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace
{

int weak_table_tag;
int impl_table_tag;

} // namespace unnamed

Expand All @@ -59,7 +60,28 @@ LUABIND_API void get_weak_table(lua_State* L)
lua_pushlightuserdata(L, &weak_table_tag);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);

}

}

LUABIND_API void get_impl_table(lua_State* L)
{

lua_pushlightuserdata(L, &impl_table_tag);
lua_rawget(L, LUA_REGISTRYINDEX);

if (lua_isnil(L, -1))
{
lua_pop(L, 1);

lua_newtable(L);
lua_pushlightuserdata(L, &impl_table_tag);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);

}

}

} // namespace luabind
Expand All @@ -74,15 +96,22 @@ namespace luabind
, state(main)
, ref(0)
{

get_impl_table(s);
lua_pushlightuserdata(s, this);
ref = luaL_ref(s, -2);
lua_pop(s, 1);

get_weak_table(s);
lua_pushvalue(s, index);
ref = luaL_ref(s, -2);
lua_rawseti(s, -2, ref);
lua_pop(s, 1);

}

~impl()
{
get_weak_table(state);
get_impl_table(state);
luaL_unref(state, -1, ref);
lua_pop(state, 1);
}
Expand Down
1 change: 1 addition & 0 deletions src/wrapper_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace luabind { namespace detail
LUABIND_API void do_call_member_selection(lua_State* L, char const* name)
{
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, -1));
assert(obj);
lua_pop(L, 1); // pop self

obj->crep()->get_table(L); // push the crep table
Expand Down

0 comments on commit a3a400e

Please sign in to comment.