Esempio n. 1
0
/*
* void= mt.__gc( proxy_ud )
*
* End of life for a proxy object; reduce the deep reference count and clean
* it up if reaches 0.
*/
static
int deep_userdata_gc( lua_State *L ) {
    DEEP_PRELUDE **proxy= (DEEP_PRELUDE**)lua_touserdata( L, 1 );
    DEEP_PRELUDE *p= *proxy;
    int v;

    *proxy= 0;  // make sure we don't use it any more

    MUTEX_LOCK( &deep_lock );
      v= --(p->refcount);
    MUTEX_UNLOCK( &deep_lock );

    if (v==0) {
        int pushed;

        // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup
        //
        lua_CFunction idfunc= get_idfunc(L,1);
        ASSERT_L(idfunc);
        
        lua_settop(L,0);    // clean stack so we can call 'idfunc' directly

        // void= idfunc( "delete", lightuserdata )
        //
        lua_pushliteral( L, "delete" );
        lua_pushlightuserdata( L, p->deep );
        pushed= idfunc(L);
        
        if (pushed)
            luaL_error( L, "Bad idfunc on \"delete\": returned something" );

        DEEP_FREE( (void*)p );
    }
    return 0;
}
Esempio n. 2
0
/*
* Access deep userdata through a proxy.
*
* Reference count is not changed, and access to the deep userdata is not
* serialized. It is the module's responsibility to prevent conflicting usage.
*/
void *luaG_todeep( lua_State *L, lua_CFunction idfunc, int index ) {
    DEEP_PRELUDE **proxy;

  STACK_CHECK(L)
    if (get_idfunc(L,index) != idfunc)
        return NULL;    // no metatable, or wrong kind

    proxy= (DEEP_PRELUDE**)lua_touserdata( L, index );
  STACK_END(L,0)

    return (*proxy)->deep;
}
Esempio n. 3
0
/*
* Access deep userdata through a proxy.
*
* Reference count is not changed, and access to the deep userdata is not
* serialized. It is the module's responsibility to prevent conflicting usage.
*/
void* luaG_todeep( lua_State* L, luaG_IdFunction idfunc, int index)
{
	DEEP_PRELUDE** proxy;

	STACK_CHECK( L);
	// ensure it is actually a deep userdata
	if( get_idfunc( L, index, eLM_LaneBody) != idfunc)
	{
		return NULL;    // no metatable, or wrong kind
	}

	proxy = (DEEP_PRELUDE**) lua_touserdata( L, index);
	STACK_END( L, 0);

	return (*proxy)->deep;
}
Esempio n. 4
0
/*
 * Copy deep userdata between two separate Lua states (from L to L2)
 *
 * Returns:
 *   the id function of the copied value, or NULL for non-deep userdata
 *   (not copied)
 */
luaG_IdFunction copydeep( struct s_Universe* U, lua_State* L, lua_State* L2, int index, enum eLookupMode mode_)
{
	char const* errmsg;
	luaG_IdFunction idfunc = get_idfunc( L, index, mode_);
	if( idfunc == NULL)
	{
		return NULL;   // not a deep userdata
	}

	errmsg = push_deep_proxy( U, L2, *(DEEP_PRELUDE**) lua_touserdata( L, index), mode_);
	if( errmsg != NULL)
	{
		// raise the error in the proper state (not the keeper)
		lua_State* errL = (mode_ == eLM_FromKeeper) ? L2 : L;
		luaL_error( errL, errmsg);
	}
	return idfunc;
}
Esempio n. 5
0
/*
* Copy deep userdata between two separate Lua states.
*
* Returns:
*   the id function of the copied value, or NULL for non-deep userdata
*   (not copied)
*/
static
lua_CFunction luaG_copydeep( lua_State *L, lua_State *L2, int index ) {
    DEEP_PRELUDE **proxy;
    DEEP_PRELUDE *p;

    lua_CFunction idfunc;
    
    idfunc= get_idfunc( L, index );
    if (!idfunc) return NULL;   // not a deep userdata

    // Increment reference count
    //
    proxy= (DEEP_PRELUDE**)lua_touserdata( L, index );
    p= *proxy;

    luaG_push_proxy( L2, idfunc, p );
        //
        // L2 [-1]: proxy userdata

    return idfunc;
}