diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-01 16:23:58 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-01 16:23:58 -0300 |
commit | aa3da1605ceb50fe8353ecb7d03b6f074e131284 (patch) | |
tree | 8f57b48267660e3631368f8e579b5cd7816cab65 | |
parent | 9f4b5b52327497e3ce82cb0af1d94ad6c09b1da2 (diff) | |
download | lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.tar.gz lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.tar.bz2 lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.zip |
`newproxy' uses its own weaktable
-rw-r--r-- | lauxlib.c | 20 | ||||
-rw-r--r-- | lauxlib.h | 4 | ||||
-rw-r--r-- | lbaselib.c | 35 |
3 files changed, 24 insertions, 35 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.76 2002/06/25 19:15:21 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.77 2002/06/26 19:28:44 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -302,24 +302,6 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | |||
302 | } | 302 | } |
303 | 303 | ||
304 | 304 | ||
305 | LUALIB_API void luaL_weakregistry (lua_State *L) { | ||
306 | static const char dummy = '\0'; /* index for a weak table in registry */ | ||
307 | lua_pushudataval(L, (void *)&dummy); /* push index */ | ||
308 | lua_rawget(L, LUA_REGISTRYINDEX); /* get value */ | ||
309 | if (!lua_isnil(L, -1)) return; /* weak table already created? */ | ||
310 | /* else must create a weak table */ | ||
311 | lua_pop(L, 1); /* remove previous nil */ | ||
312 | lua_newtable(L); /* new table `w' */ | ||
313 | lua_pushvalue(L, -1); | ||
314 | lua_setmetatable(L, -2); /* setmetatable(w, w) */ | ||
315 | lua_pushliteral(L, "__mode"); | ||
316 | lua_pushliteral(L, "kv"); | ||
317 | lua_rawset(L, -3); /* metatable(w).__mode = "kv" */ | ||
318 | lua_pushudataval(L, (void *)&dummy); /* push index */ | ||
319 | lua_pushvalue(L, -2); /* push value */ | ||
320 | lua_rawset(L, LUA_REGISTRYINDEX); /* store new weak table into registry */ | ||
321 | } | ||
322 | |||
323 | 305 | ||
324 | /* | 306 | /* |
325 | ** {====================================================== | 307 | ** {====================================================== |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.h,v 1.49 2002/06/18 15:19:27 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.50 2002/06/25 19:15:21 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -49,8 +49,6 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); | |||
49 | LUALIB_API int luaL_findstring (const char *name, | 49 | LUALIB_API int luaL_findstring (const char *name, |
50 | const char *const list[]); | 50 | const char *const list[]); |
51 | 51 | ||
52 | LUALIB_API void luaL_weakregistry (lua_State *L); | ||
53 | |||
54 | LUALIB_API int luaL_ref (lua_State *L, int t); | 52 | LUALIB_API int luaL_ref (lua_State *L, int t); |
55 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref); | 53 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref); |
56 | 54 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.87 2002/06/26 19:28:44 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.88 2002/06/26 20:36:17 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -323,27 +323,27 @@ static int luaB_tostring (lua_State *L) { | |||
323 | 323 | ||
324 | 324 | ||
325 | static int luaB_newproxy (lua_State *L) { | 325 | static int luaB_newproxy (lua_State *L) { |
326 | static const char dummy = '\0'; | ||
327 | lua_settop(L, 1); | 326 | lua_settop(L, 1); |
328 | luaL_weakregistry(L); /* get weak registry */ | ||
329 | lua_newuserdata(L, 0); /* create proxy */ | 327 | lua_newuserdata(L, 0); /* create proxy */ |
330 | if (lua_toboolean(L, 1) == 0) | 328 | if (lua_toboolean(L, 1) == 0) |
331 | return 1; /* no metatable */ | 329 | return 1; /* no metatable */ |
332 | else if (lua_isboolean(L, 1)) { | 330 | else if (lua_isboolean(L, 1)) { |
333 | lua_newtable(L); /* create a new metatable `m' ... */ | 331 | lua_newtable(L); /* create a new metatable `m' ... */ |
334 | lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ | 332 | lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ |
335 | lua_pushudataval(L, (void *)&dummy); | 333 | lua_pushboolean(L, 1); |
336 | lua_rawset(L, 2); /* weakregistry[m] = &dummy */ | 334 | lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ |
337 | } | 335 | } |
338 | else { | 336 | else { |
339 | if (lua_getmetatable(L, 1)) /* check whether registry[m] == &dummy */ | 337 | int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ |
340 | lua_rawget(L, 2); | 338 | if (lua_getmetatable(L, 1)) { |
341 | luaL_arg_check(L, (char *)lua_touserdata(L, -1) == &dummy, 1, | 339 | lua_rawget(L, lua_upvalueindex(1)); |
342 | "boolean/proxy expected"); | 340 | validproxy = lua_toboolean(L, -1); |
343 | lua_getmetatable(L, 1); /* metatable is valid */ | 341 | lua_pop(L, 1); /* remove value */ |
342 | } | ||
343 | luaL_arg_check(L, validproxy, 1, "boolean/proxy expected"); | ||
344 | lua_getmetatable(L, 1); /* metatable is valid; get it */ | ||
344 | } | 345 | } |
345 | lua_setmetatable(L, 3); | 346 | lua_setmetatable(L, 2); |
346 | lua_pushvalue(L, 3); | ||
347 | return 1; | 347 | return 1; |
348 | } | 348 | } |
349 | 349 | ||
@@ -461,7 +461,6 @@ static const luaL_reg base_funcs[] = { | |||
461 | {"tostring", luaB_tostring}, | 461 | {"tostring", luaB_tostring}, |
462 | {"type", luaB_type}, | 462 | {"type", luaB_type}, |
463 | {"assert", luaB_assert}, | 463 | {"assert", luaB_assert}, |
464 | {"newproxy", luaB_newproxy}, | ||
465 | {"unpack", luaB_unpack}, | 464 | {"unpack", luaB_unpack}, |
466 | {"rawequal", luaB_rawequal}, | 465 | {"rawequal", luaB_rawequal}, |
467 | {"rawget", luaB_rawget}, | 466 | {"rawget", luaB_rawget}, |
@@ -569,6 +568,16 @@ static void base_open (lua_State *L) { | |||
569 | lua_pushliteral(L, "_VERSION"); | 568 | lua_pushliteral(L, "_VERSION"); |
570 | lua_pushliteral(L, LUA_VERSION); | 569 | lua_pushliteral(L, LUA_VERSION); |
571 | lua_rawset(L, -3); /* set global _VERSION */ | 570 | lua_rawset(L, -3); /* set global _VERSION */ |
571 | /* `newproxy' needs a weaktable as upvalue */ | ||
572 | lua_pushliteral(L, "newproxy"); | ||
573 | lua_newtable(L); /* new table `w' */ | ||
574 | lua_newtable(L); /* create `w's metatable */ | ||
575 | lua_pushliteral(L, "__mode"); | ||
576 | lua_pushliteral(L, "k"); | ||
577 | lua_rawset(L, -3); /* metatable(w).__mode = "k" */ | ||
578 | lua_setmetatable(L, -2); | ||
579 | lua_pushcclosure(L, luaB_newproxy, 1); | ||
580 | lua_rawset(L, -3); /* set global `newproxy' */ | ||
572 | lua_rawset(L, -1); /* set global _G */ | 581 | lua_rawset(L, -1); /* set global _G */ |
573 | } | 582 | } |
574 | 583 | ||