diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-10 12:25:02 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-10 12:25:02 -0300 |
| commit | dcc070683cf89d82aae4f2cbe00ff8dbd97392ca (patch) | |
| tree | c0306f88134237a51453b4892bbc4082de2c5873 | |
| parent | 2d81cfa4e195a31d92d5ffff313918e4da549a71 (diff) | |
| download | lua-dcc070683cf89d82aae4f2cbe00ff8dbd97392ca.tar.gz lua-dcc070683cf89d82aae4f2cbe00ff8dbd97392ca.tar.bz2 lua-dcc070683cf89d82aae4f2cbe00ff8dbd97392ca.zip | |
avoid reserving LUA_RIDX_LAST slots in any table used by reference
system. Store free list in a field indexed by a unique name,
instead of using a numerical index.
| -rw-r--r-- | lauxlib.c | 24 |
1 files changed, 9 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.207 2010/04/09 16:14:46 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.208 2010/04/14 15:14: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 | */ |
| @@ -436,8 +436,8 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { | |||
| 436 | ** ======================================================= | 436 | ** ======================================================= |
| 437 | */ | 437 | */ |
| 438 | 438 | ||
| 439 | /* number of prereserved references (for internal use) */ | 439 | /* index of free-list header */ |
| 440 | #define FREELIST_REF (LUA_RIDX_LAST + 1) /* free list of references */ | 440 | #define freelist "lua-freelist" |
| 441 | 441 | ||
| 442 | 442 | ||
| 443 | LUALIB_API int luaL_ref (lua_State *L, int t) { | 443 | LUALIB_API int luaL_ref (lua_State *L, int t) { |
| @@ -447,21 +447,15 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
| 447 | lua_pop(L, 1); /* remove from stack */ | 447 | lua_pop(L, 1); /* remove from stack */ |
| 448 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ | 448 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ |
| 449 | } | 449 | } |
| 450 | lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ | 450 | lua_getfield(L, t, freelist); /* get first free element */ |
| 451 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ | 451 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ |
| 452 | lua_pop(L, 1); /* remove it from stack */ | 452 | lua_pop(L, 1); /* remove it from stack */ |
| 453 | if (ref != 0) { /* any free element? */ | 453 | if (ref != 0) { /* any free element? */ |
| 454 | lua_rawgeti(L, t, ref); /* remove it from list */ | 454 | lua_rawgeti(L, t, ref); /* remove it from list */ |
| 455 | lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ | 455 | lua_setfield(L, t, freelist); /* (t[freelist] = t[ref]) */ |
| 456 | } | 456 | } |
| 457 | else { /* no free elements */ | 457 | else /* no free elements */ |
| 458 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ | 458 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ |
| 459 | if (ref == FREELIST_REF) { /* FREELIST_REF not initialized? */ | ||
| 460 | lua_pushinteger(L, 0); | ||
| 461 | lua_rawseti(L, t, FREELIST_REF); | ||
| 462 | ref = FREELIST_REF + 1; | ||
| 463 | } | ||
| 464 | } | ||
| 465 | lua_rawseti(L, t, ref); | 459 | lua_rawseti(L, t, ref); |
| 466 | return ref; | 460 | return ref; |
| 467 | } | 461 | } |
| @@ -470,10 +464,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
| 470 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | 464 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { |
| 471 | if (ref >= 0) { | 465 | if (ref >= 0) { |
| 472 | t = abs_index(L, t); | 466 | t = abs_index(L, t); |
| 473 | lua_rawgeti(L, t, FREELIST_REF); | 467 | lua_getfield(L, t, freelist); |
| 474 | lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ | 468 | lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ |
| 475 | lua_pushinteger(L, ref); | 469 | lua_pushinteger(L, ref); |
| 476 | lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ | 470 | lua_setfield(L, t, freelist); /* t[freelist] = ref */ |
| 477 | } | 471 | } |
| 478 | } | 472 | } |
| 479 | 473 | ||
