[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Recycling a Lua state
- From: Mark Hamburg <mhamburg@...>
- Date: Thu, 13 May 2004 08:22:14 -0700
I'm working on an app where I want to maintain a pool of Lua states to make
it easy to do things like index into a variable representing a Lua table
without the caller having to worry about managing Lua states. So, for
example, something like:
LuaObj* LuaObj::operator[]( LuaObj* index ) {
TempLuaState state;
lua_rawgeti( state.L, LUA_REGISTRYINDEX, this->_ref );
lua_rawgeti( state.L, LUA_REGISTRYINDEX, index->_ref );
lua_gettable( state.L, -2 );
return new LuaObj( state.L, -1 );
// Constructs a new ref to the indicated object
}
I've also rewired Lua exceptions into native exceptions instead of
setjmp/longjmp.
Now, we come to the problem: How to write the destructor for TempLuaState.
The goal should be that it takes the lua_State* and returns it to a pool of
states for reuse. However, when it does so, it needs to clean up anything
left over in the state. Essentially, I want to get back to the state things
were in after lua_newthread without having to allocate a new thread or
garbage collect the old one. Doing a lua_settop( L, 0 ) is insufficient
because we might have actually experienced an exception while down multiple
stack frame levels -- e.g., from an __index metamethod being called in the
above code. If I used pcall or cpcall, this would happen automatically but
the code above would be a lot more awkward to write.
Any advice on how to do this legitimately with the existing APIs? Any advice
on what I would need to do as an extension to the Lua implementation? Is the
following correct or am I wildly off on how the VM data structures work?
L->ci = L->base_ci;
L->base = L->ci->base;
L->nCcalls = 0;
luaF_close(L, L->base);
L->allowhook = 1;
L->errfunc = 0;
restore_stack_limit(L);
Thanks.
Mark