diff -urN lua/src/lib/lbaselib.c lua_weakrefs/src/lib/lbaselib.c --- lua/src/lib/lbaselib.c Mon Nov 6 22:45:18 2000 +++ lua_weakrefs/src/lib/lbaselib.c Fri Dec 14 14:55:57 2001 @@ -19,6 +19,11 @@ +typedef struct BaseCtrl { + int weakreftag; /* tag for weak reference objects */ +} BaseCtrl; + + /* ** If your system does not support `stderr', redefine this function, or ** redefine _ERRORMESSAGE so that it won't need _ALERT. @@ -430,6 +435,42 @@ } +/* +** Create and return a weak reference to given object. The weak reference +** object is an unlocked Lua reference stored as a userdata pointer. +*/ +static int luaB_weakref (lua_State *L) { + BaseCtrl *ctrl = (BaseCtrl *)lua_touserdata(L, -1); + lua_pop(L, 1); + luaL_arg_check(L, !lua_isnil(L, 1), 1, "non-nil value expected"); + lua_pushuserdata(L, (void*)lua_ref(L, 0)); + lua_settag(L, ctrl->weakreftag); + return 1; +} + + +/* +** When weak reference object is called as a function, dereference and +** return value. +*/ +static int weakref_call (lua_State *L) { + int r = (int)lua_touserdata(L, 1); + int valid = lua_getref(L, r); + if (!valid) lua_pushnil(L); + return 1; +} + + +/* +** When weak reference object goes out of scope, release the reference. +*/ +static int weakref_collect (lua_State *L) { + int r = (int)lua_touserdata(L, 1); + lua_unref(L, r); + return 0; +} + + /* @@ -641,11 +682,34 @@ }; +static const struct luaL_reg base_funcs_tag[] = { + {"weakref", luaB_weakref} +}; + + +static void openwithcontrol (lua_State *L) { + BaseCtrl *ctrl = (BaseCtrl *)lua_newuserdata(L, sizeof(BaseCtrl)); + unsigned int i; + ctrl->weakreftag = lua_newtag(L); + for (i=0; iweakreftag, "function"); + lua_pushcfunction(L, weakref_collect); + lua_settagmethod(L, ctrl->weakreftag, "gc"); +} + LUALIB_API void lua_baselibopen (lua_State *L) { luaL_openl(L, base_funcs); lua_pushstring(L, LUA_VERSION); lua_setglobal(L, "_VERSION"); deprecated_funcs(L); + openwithcontrol(L); } diff -urN lua/test/weakref.lua lua_weakrefs/test/weakref.lua --- lua/test/weakref.lua Thu Jan 1 09:00:00 1970 +++ lua_weakrefs/test/weakref.lua Fri Dec 14 14:55:57 2001 @@ -0,0 +1,13 @@ +local a_ref + +do + local a = { } + print(a) + a_ref = weakref(a) + print(a_ref()) +end + +-- variable a is now out of scope, force a gc cycle to collect it +collectgarbage() + +print(a_ref())

AltStyle によって変換されたページ (->オリジナル) /