c++lualua-userdata

When is it allowed to call lua_gc in C++ when also using lua_newuserdata


The below example is just to demonstrate the problem/question; in reality I have functions creating and returning many different userdata object, and between some of those I may want to call the Lua garbage collector.

Also, I am using Lua version 5.3.3, running both on Windows and Linux. Error handling is not shown for simplicity.

I have a C++ class exposed to Lua via standard userdata as described in e.g. "Programming in Lua" by Roberto Ierusalimschy. My problem is that I am not sure when Lua does have a reference to my object, so when am I allowed to call the garbage collector via C++ lua_gc function?

I have e.g. the standard Foo C++ class with constructor and destructor. And defined a metatable "FOO" with the __gc entry function called ReleaseFoo as also shown.

I create an instance in Lua via the following C++ code:

static int NewFoo(lua_State* L)
{
  Foo** foo;
  foo  = (Foo**) lua_newuserdata(L, sizeof(Foo**));
  *foo = new Foo();
  luaL_getmetatable(L, "FOO");
  lua_setmetatable(L, -2);

  // QUESTION: Can I call lua_gc(L, LUA_GCCOLLECT, 0) here without
  //           risking my user data object being garbage collected.
  //           As I see it, Lua does not yet have a reference
  //           to my user data object.

  return 1;
}

static int ReleaseFoo(lua_State* L)
{
  Foo* foo = *(Foo**)lua_touserdata(L,1);
  if (foo)
  {
    delete foo;
     foo = NULL;
  }
  return 0;
}

In Lua, use of it will look like (so only after the return of the C++ function NewFoo(L) the reference is established, but may I call the garbage collector as shown?):

LUA> foo = NewFoo()

Solution

  • lua_setmetatable does not remove object from stack so there exists reference to your userdata object. So Lua will not collect it.