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