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 /lbaselib.c | |
parent | 9f4b5b52327497e3ce82cb0af1d94ad6c09b1da2 (diff) | |
download | lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.tar.gz lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.tar.bz2 lua-aa3da1605ceb50fe8353ecb7d03b6f074e131284.zip |
`newproxy' uses its own weaktable
Diffstat (limited to 'lbaselib.c')
-rw-r--r-- | lbaselib.c | 35 |
1 files changed, 22 insertions, 13 deletions
@@ -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 | ||