/* * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. * Pops the both values off the stack. */ static void set_deep_lookup( lua_State* L) { STACK_GROW( L, 3); STACK_CHECK( L); // a b push_registry_subtable( L, DEEP_LOOKUP_KEY); // a b {} STACK_MID( L, 1); lua_insert( L, -3); // {} a b lua_pushvalue( L, -1); // {} a b b lua_pushvalue( L,-3); // {} a b b a lua_rawset( L, -5); // {} a b lua_rawset( L, -3); // {} lua_pop( L, 1); // STACK_END( L, -2); }
/* * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. * Pops the both values off the stack. */ void set_deep_lookup( lua_State *L ) { STACK_GROW(L,3); STACK_CHECK(L) #if 1 push_registry_subtable( L, DEEP_LOOKUP_KEY ); #else /* ..to be removed.. */ lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); lua_rawget( L, LUA_REGISTRYINDEX ); if (lua_isnil(L,-1)) { // First time here; let's make the lookup // lua_pop(L,1); lua_newtable(L); lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); lua_pushvalue(L,-2); // // [-3]: {} (2nd ref) // [-2]: DEEP_LOOKUP_KEY // [-1]: {} lua_rawset( L, LUA_REGISTRYINDEX ); // // [-1]: lookup table (empty) } #endif STACK_MID(L,1) lua_insert(L,-3); // [-3]: lookup table // [-2]: A // [-1]: B lua_pushvalue( L,-1 ); // B lua_pushvalue( L,-3 ); // A lua_rawset( L, -5 ); // B->A lua_rawset( L, -3 ); // A->B lua_pop( L,1 ); STACK_END(L,-2) }
/* * Get a unique ID for metatable at [i]. */ static uint_t get_mt_id( lua_State *L, int i ) { static uint_t last_id= 0; uint_t id; i= STACK_ABS(L,i); STACK_GROW(L,3); STACK_CHECK(L) push_registry_subtable( L, REG_MTID ); lua_pushvalue(L, i); lua_rawget( L, -2 ); // // [-2]: reg[REG_MTID] // [-1]: nil/uint id= lua_tointeger(L,-1); // 0 for nil lua_pop(L,1); STACK_MID(L,1) if (id==0) { MUTEX_LOCK( &mtid_lock ); id= ++last_id; MUTEX_UNLOCK( &mtid_lock ); /* Create two-way references: id_uint <-> table */ lua_pushvalue(L,i); lua_pushinteger(L,id); lua_rawset( L, -3 ); lua_pushinteger(L,id); lua_pushvalue(L,i); lua_rawset( L, -3 ); } lua_pop(L,1); // remove 'reg[REG_MTID]' reference STACK_END(L,0) return id; }