lua-users home
lua-l archive

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


For that technique, you could probably use lua_rawequal.

Another variant if you can come up with a void* to identify the type is
something like the following:

    void* checkudata_udkey( lua_State* L, int index, void* udkey )
    {
        if( !lua_getmetatable( L, index ) )
            return NULL;
        lua_pushlightuserdata( L, udkey );      /* ( ... mt udkey )
        lua_rawget( L, -2 );                    /* ( ... mt mt[ udkey ] )
        if( !lua_toboolean( L, -1 ) ) {
            lua_pop( L, 2 );
            return NULL;
        }
        lua_pop( L, 2 );
        return lua_touserdata( L, index );
    }

This needs versions of the other udata routines as well.

Arguably, this should really be called toudata_udkey and the check version
should throw.

What's more, this version is friendly toward inheritance since we just need
to mark the metatable with every type it belongs to.

Mark

on 8/26/04 2:23 PM, Shannon Stewman at stew@uchicago.edu wrote:

> Hello all,
> 
> After profiling some C extensions I had written, I noticed that many
> of my fast routines spent an enormous percentage of time (60% or more)
> calling luaL_checkudata, and most of that was spent in its strcmp call.
> 
> I wrote a faster routine that works on pointers, and should work for
> both userdata and tables.
> 
> Is there are problem using this technique, assuming the metatables I'm
> comparing are allocated in a library's luaopen_XXX function and only
> freed on a lua_close() call?
> 
> void* fastcheckudata( lua_State* L, int index, const char* id)
> {
> lua_getmetatable(L,index);
> const void* p1 = lua_topointer(L,-1);
> luaL_getmetatable(L,id);
> const void* p2 = lua_topointer(L,-1);
> 
> lua_pop(L,2);
> 
> return p1 == p2 ? lua_touserdata(L, index) : NULL;
> }
> 
> Best,