/* * Create a deep userdata * * proxy_ud= deep_userdata( idfunc [, ...] ) * * Creates a deep userdata entry of the type defined by 'idfunc'. * Other parameters are passed on to the 'idfunc' "new" invocation. * * 'idfunc' must fulfill the following features: * * lightuserdata = idfunc( eDO_new [, ...] ) -- creates a new deep data instance * void = idfunc( eDO_delete, lightuserdata ) -- releases a deep data instance * tbl = idfunc( eDO_metatable ) -- gives metatable for userdata proxies * * Reference counting and true userdata proxying are taken care of for the * actual data type. * * Types using the deep userdata system (and only those!) can be passed between * separate Lua states via 'luaG_inter_move()'. * * Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' */ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc) { char const* errmsg; DEEP_PRELUDE* prelude = DEEP_MALLOC( sizeof(DEEP_PRELUDE)); if( prelude == NULL) { return luaL_error( L, "couldn't not allocate deep prelude: out of memory"); } prelude->refcount = 0; // 'push_deep_proxy' will lift it to 1 prelude->idfunc = idfunc; STACK_GROW( L, 1); STACK_CHECK( L); { int oldtop = lua_gettop( L); prelude->deep = idfunc( L, eDO_new); if( prelude->deep == NULL) { luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); } if( lua_gettop( L) - oldtop != 0) { luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack"); } } errmsg = push_deep_proxy( get_universe( L), L, prelude, eLM_LaneBody); // proxy if( errmsg != NULL) { luaL_error( L, errmsg); } STACK_END( L, 1); return 1; }
/* * Create a deep userdata * * proxy_ud= deep_userdata( idfunc [, ...] ) * * Creates a deep userdata entry of the type defined by 'idfunc'. * Other parameters are passed on to the 'idfunc' "new" invocation. * * 'idfunc' must fulfill the following features: * * lightuserdata= idfunc( "new" [, ...] ) -- creates a new deep data instance * void= idfunc( "delete", lightuserdata ) -- releases a deep data instance * tbl= idfunc( "metatable" ) -- gives metatable for userdata proxies * * Reference counting and true userdata proxying are taken care of for the * actual data type. * * Types using the deep userdata system (and only those!) can be passed between * separate Lua states via 'luaG_inter_move()'. * * Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' */ int luaG_deep_userdata( lua_State *L ) { lua_CFunction idfunc= lua_tocfunction( L,1 ); int pushed; DEEP_PRELUDE *prelude= DEEP_MALLOC( sizeof(DEEP_PRELUDE) ); ASSERT_L(prelude); prelude->refcount= 0; // 'luaG_push_proxy' will lift it to 1 STACK_GROW(L,1); STACK_CHECK(L) // Replace 'idfunc' with "new" in the stack (keep possible other params) // lua_remove(L,1); lua_pushliteral( L, "new" ); lua_insert(L,1); // lightuserdata= idfunc( "new" [, ...] ) // pushed= idfunc(L); if ((pushed!=1) || lua_type(L,-1) != LUA_TLIGHTUSERDATA) luaL_error( L, "Bad idfunc on \"new\": did not return light userdata" ); prelude->deep= lua_touserdata(L,-1); ASSERT_L(prelude->deep); lua_pop(L,1); // pop deep data luaG_push_proxy( L, idfunc, prelude ); // // [-1]: proxy userdata STACK_END(L,1) return 1; }