lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello,

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?

Thanks a lot,
Dario