aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-05-10 12:25:02 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-05-10 12:25:02 -0300
commitdcc070683cf89d82aae4f2cbe00ff8dbd97392ca (patch)
treec0306f88134237a51453b4892bbc4082de2c5873
parent2d81cfa4e195a31d92d5ffff313918e4da549a71 (diff)
downloadlua-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.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/lauxlib.c b/lauxlib.c
index eebdaedd..7d35124c 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
443LUALIB_API int luaL_ref (lua_State *L, int t) { 443LUALIB_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) {
470LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { 464LUALIB_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