From a1b113901ca21994e4cc1220229f234efd687a44 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 28 Jul 2009 10:40:51 +0200 Subject: [PATCH] luaobject: change global refering method We now store elements in registry: registry.pointer = userdata And count references. Signed-off-by: Julien Danjou --- common/luaobject.c | 19 +++++++++++ common/luaobject.h | 82 +++++++++++++++++++++++++++++++--------------- luaa.c | 2 ++ 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/common/luaobject.c b/common/luaobject.c index 7c69934a..672b6ece 100644 --- a/common/luaobject.c +++ b/common/luaobject.c @@ -21,6 +21,25 @@ #include "common/luaobject.h" +/** Setup the object system at startup. + * \param L The Lua VM state. + */ +void +luaA_object_setup(lua_State *L) +{ + /* Push identification string */ + lua_pushliteral(L, LUAA_OBJECT_REGISTRY_KEY); + /* Create an empty table */ + lua_newtable(L); + /* Create an empty metatable */ + lua_newtable(L); + /* Set this empty table as the registry metatable. + * It's used to store the number of reference on stored objects. */ + lua_setmetatable(L, -2); + /* Register table inside registry */ + lua_rawset(L, LUA_REGISTRYINDEX); +} + /** Increment a object reference in its store table. * \param L The Lua VM state. * \param tud The table index on the stack. diff --git a/common/luaobject.h b/common/luaobject.h index d713aaf3..8f9b1878 100644 --- a/common/luaobject.h +++ b/common/luaobject.h @@ -33,6 +33,9 @@ luaA_settype(lua_State *L, const char *type) return 1; } +#define LUAA_OBJECT_REGISTRY_KEY "awesome.object.registry" + +void luaA_object_setup(lua_State *); void * luaA_object_incref(lua_State *, int, int); void luaA_object_decref(lua_State *, int, void *); @@ -89,10 +92,57 @@ luaA_object_push_item(lua_State *L, int ud, void *pointer) return 1; } -DO_ARRAY(int, int, DO_NOTHING) +static inline void +luaA_object_registry_push(lua_State *L) +{ + lua_pushliteral(L, LUAA_OBJECT_REGISTRY_KEY); + lua_rawget(L, LUA_REGISTRYINDEX); +} -#define LUA_OBJECT_HEADER \ - int_array_t refs; +/** Reference an object and return a pointer to it. + * That only works with userdata, table, thread or function. + * \param L The Lua VM state. + * \param oud The object index on the stack. + * \return The object reference, or NULL if not referencable. + */ +static inline void * +luaA_object_ref(lua_State *L, int oud) +{ + luaA_object_registry_push(L); + void *p = luaA_object_incref(L, -1, oud < 0 ? oud - 1 : oud); + lua_pop(L, 1); + return p; +} + +/** Unreference an object and return a pointer to it. + * That only works with userdata, table, thread or function. + * \param L The Lua VM state. + * \param oud The object index on the stack. + */ +static inline void +luaA_object_unref(lua_State *L, void *pointer) +{ + luaA_object_registry_push(L); + luaA_object_decref(L, -1, pointer); + lua_pop(L, 1); +} + +/** Push a referenced object onto the stack. + * \param L The Lua VM state. + * \param pointer The object to push. + * \return The number of element pushed on stack. + */ +static inline int +luaA_object_push(lua_State *L, void *pointer) +{ + luaA_object_registry_push(L); + lua_pushlightuserdata(L, pointer); + lua_rawget(L, -2); + lua_remove(L, -2); + return 1; +} + +#define LUA_OBJECT_HEADER /** Generic type for all objects. * All Lua objects can be casted to this type. @@ -119,37 +169,19 @@ typedef struct static inline int \ prefix##_push(lua_State *L, type *item) \ { \ - if(item) \ - { \ - assert(item->refs.len); \ - lua_rawgeti(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \ - } \ - else \ - lua_pushnil(L); \ - return 1; \ + return luaA_object_push(L, item); \ } \ \ static inline type * \ prefix##_ref(lua_State *L, int ud) \ { \ - if(lua_isnil(L, ud)) \ - return NULL; \ - type *item = luaL_checkudata(L, ud, lua_type); \ - lua_pushvalue(L, ud); \ - int_array_append(&item->refs, luaL_ref(L, LUA_REGISTRYINDEX)); \ - lua_remove(L, ud); \ - return item; \ + return luaA_object_ref(L, ud); \ } \ \ static inline void \ prefix##_unref(lua_State *L, type *item) \ { \ - if(item) \ - { \ - assert(item->refs.len); \ - luaL_unref(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \ - int_array_take(&item->refs, 0); \ - } \ + luaA_object_unref(L, item); \ } \ \ static inline int \ @@ -169,8 +201,6 @@ typedef struct static inline int luaA_object_gc(lua_State *L) { - lua_object_t *item = lua_touserdata(L, 1); - int_array_wipe(&item->refs); return 0; } diff --git a/luaa.c b/luaa.c index ba5f7d14..910f5c11 100644 --- a/luaa.c +++ b/luaa.c @@ -677,6 +677,8 @@ luaA_init(xdgHandle* xdg) luaA_fixups(L); + luaA_object_setup(L); + /* Export awesome lib */ luaA_openlib(L, "awesome", awesome_lib, awesome_lib);