lua-users home
lua-l archive

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

On 9-Jun-07, at 6:01 PM, Thomas Harning Jr. wrote:

I setup the ENV index at the beginning of the registration of the
library and the function that is responsible for the callback is one
of the functions registered.  Could it be that the ENV table is tied
to the current coroutine?  Even in that case it doesn't explain why
lua_rawgeti works and luaL_unref doesnt.

The ENVIRONMENT table is tied to the currently executing CFunction
(where "currently executing" refers to the thread corresponding to
the lua_State specified.) If there is no currently active callframe
then you'll get a crash when you try to use LUA_ENVIRONINDEX. I
suspect that's what is happening in your case, although the <snip>'s
make it hard to tell.

I think you're trying to use something like thread-local storage,
which is best emulated in Lua by using LUA_GLOBALSINDEX; despite
the name, which is historical, the "GLOBAL" table is actually
the thread's environment table. By default, newly created
thread's inherit the environment table from the thread which
creates the new thread, but it can be changed. If you supply a
new table, of course, you'll have to appropriately populate it,
since it will be used for lookup of "globals" (unbound variables) --
more accurately, it will be the default environment table for
newly created closures, and thus be used for lookup of unbound
variables from those closures.

The code:
	lua_rawgeti(L, LUA_ENVIRONINDEX, arg->callbackRef);
	lua_pushinteger(L, event);
	ret = lua_resume(L, 1);
pushes two things on the stack belonging to L, and then resumes
that thread claiming to provide one argument. That's only valid
if the thread is "fresh" and the first thing you're pushing is
a closure. When the closure return's (rather than yielding), the
thread is once again "fresh" and there is no active closure;
consequently, the use of LUA_ENVIRONINDEX is invalid and will
lead to a crash.

I strongly recommend that you compile Lua with -DLUA_USE_APICHECK
which will cause most API argument errors to assert(). There is an
experimental patch for Lua 5.1.2 in the ldb distribution [1] which
adds some additional API checks (all the ones I could think of
which were not being checked by standard Lua) and also adds some
indication of what the assert() means. You might find this useful
as well.

Hope that helps

[1] <>