lua-users home
lua-l archive

C upvalue cleanup not being called

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


I copied some code from another module that works ok but does not call the __gc callback for a userdata. I'm stumped. I'm a newbie with the C API but suspect it may have something to do with the lua_setfuncs() compatibility function (I'm using Lua 5.1). TBH, I'm not sure if this is even the best way to achieve what I want. What's the best way to register a cleanup handler for userdata?
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
/* Compatibility for Lua 5.1.
 *
* luaL_setfuncs() is used to create a module table where the functions have * ispf_config_t as their first upvalue. Code borrowed from Lua 5.2 source. */
static void luaL_setfuncs( lua_State * l, const luaL_Reg * reg, int nup )
{
 int i;
 luaL_checkstack( l, nup, "too many upvalues" );
for (; reg->name != NULL; reg++ ) /* fill the table with given functions */
 {
 for ( i = 0; i < nup; i++ ) /* copy upvalues to the top */
 lua_pushvalue( l, -nup );
lua_pushcclosure( l, reg->func, nup ); /* closure with those upvalues */
 lua_setfield( l, -( nup + 2 ), reg->name );
 }
 lua_pop( l, nup ); /* remove upvalues */
}
#endif
static int destroy_config( lua_State * L ) // not being called
{
 ispf_config_t * ispf = fetch_config( L );
 printf( "ispexec=%p\n", ispf->ispexec );
 return 1;
}
extern "C" int luaopen_ispf( lua_State * L )
{
 luaL_Reg reg[] = {
 { "bind", ispf_bind },
 { "ispexec", ispf_exec },
 { "vcopy", ispf_vcopy },
 { "vreplace", ispf_vreplace },
 { NULL, NULL }
 };
 // module table
 lua_newtable( L );
 // register functions with config data as upvalue
ispf_config_t * config = ( ispf_config_t * )lua_newuserdata( L, sizeof*config );
 config->isplink = ( isplink_t * )( fetch( "ISPLINK" ) );
 config->ispexec = ( ispexec_t * )( fetch( "ISPEXEC" ) );
 // create GC method to clean up loaded functions
 lua_newtable( L );
 lua_pushcfunction( L, destroy_config );
 lua_setfield( L, -2, "__gc" );
 lua_setmetatable( L, -2 );
 luaL_setfuncs( L, reg, 1 );
 // set module name / version fields
 lua_pushliteral( L, ISPF_MODNAME );
 lua_setfield( L, -2, "_NAME" );
 lua_pushliteral( L, ISPF_VERSION );
 lua_setfield( L, -2, "_VERSION" );
 return 1;
}

AltStyle によって変換されたページ (->オリジナル) /