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 '')
| -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 | ||
