This one has got me puzzled.
My application uses Lua 5.0.2 through the Lunar C++ interface. A
preliminary question is -- why does Lunar::Register lack the newindex
event? This is what I added to the registration:
// hide metatable from Lua getmetatable()
lua_pushvalue(L, methods);
set(L, metatable, "__metatable");
lua_pushvalue(L, methods);
set(L, metatable, "__index");
lua_pushvalue(L, methods);
set(L, metatable, "__newindex");
Now, assuming that the above is correct... In my Object class I need
to handle the __index event, since accessing missing members of an
object should actually add them (properly initialized) to the object.
It is currently done this way:
int script::do__index (lua_State* L)
{
const int iTable = 1;
const int iKey = 2;
...
if ( objectDoesNotExist )
{
int iObject = CreateAndPushObject(L);
if ( !lua_isnil(L,iObject) )
{
lua_pushvalue(L,iKey);
lua_pushvalue(L,iObject);
lua_settable(L,iTable);
}
lua_pop(L,1);
}
lua_pushvalue(L,iKey);
lua_rawget(L,iTable);
return 1;
}
This seems to work fine and I'm fairly happy with its performance.
However, my application now needs to handle the __newindex metamethod
as well, for book-keeping purposes. I have tried to add said
metamethod to my metatable -- currently it's basically a no-op:
int script::do__newindex (lua_State* L)
{
const int iTable = 1;
const int iKey = 2;
const int iValue = 3;
lua_pushvalue(L,iKey);
lua_pushvalue(L,iValue);
lua_rawset(L,iTable);
return 0;
}
As soon as I've added it, I realized that it would get invoked from
the index event because of the lua_settable call. In fact, stepping
through the code in gdb revealed that do__newindex was being invoked
exactly as expected.
However, the lua_rawset call crashes in the newkey function in the
ltable.c file -- the
Node *othern = luaH_mainposition(t, gkey(mp))
statement is returning othern == mp, and the
Node *n = t->firstfree
statement is returning NULL, so I get a segfault on the
n->next = mp->next
statement. If I substitute the lua_settable call in do__index with a
lua_rawset I get the same exact crash.
Quite obviously this is my shameful fault, but I am unable to
understand what I've messed up. If I don't add the newindex event to
my metatable, everything works fine -- but obviously I cannot track
assignments to my object class, and I do really need that for keeping
internal statistics.
Ideas, anyone?