aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lauxlib.c')
-rw-r--r--lauxlib.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 73504389..074ff08c 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -639,10 +639,14 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
639** ======================================================= 639** =======================================================
640*/ 640*/
641 641
642/* index of free-list header */ 642/* index of free-list header (after the predefined values) */
643#define freelist 0 643#define freelist (LUA_RIDX_LAST + 1)
644
645 644
645/*
646** The previously freed references form a linked list:
647** t[freelist] is the index of a first free index, or zero if list is
648** empty; t[t[freelist]] is the index of the second element; etc.
649*/
646LUALIB_API int luaL_ref (lua_State *L, int t) { 650LUALIB_API int luaL_ref (lua_State *L, int t) {
647 int ref; 651 int ref;
648 if (lua_isnil(L, -1)) { 652 if (lua_isnil(L, -1)) {
@@ -650,9 +654,16 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
650 return LUA_REFNIL; /* 'nil' has a unique fixed reference */ 654 return LUA_REFNIL; /* 'nil' has a unique fixed reference */
651 } 655 }
652 t = lua_absindex(L, t); 656 t = lua_absindex(L, t);
653 lua_rawgeti(L, t, freelist); /* get first free element */ 657 if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */
654 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ 658 ref = 0; /* list is empty */
655 lua_pop(L, 1); /* remove it from stack */ 659 lua_pushinteger(L, 0); /* initialize as an empty list */
660 lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */
661 }
662 else { /* already initialized */
663 lua_assert(lua_isinteger(L, -1));
664 ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
665 }
666 lua_pop(L, 1); /* remove element from stack */
656 if (ref != 0) { /* any free element? */ 667 if (ref != 0) { /* any free element? */
657 lua_rawgeti(L, t, ref); /* remove it from list */ 668 lua_rawgeti(L, t, ref); /* remove it from list */
658 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ 669 lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
@@ -668,6 +679,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
668 if (ref >= 0) { 679 if (ref >= 0) {
669 t = lua_absindex(L, t); 680 t = lua_absindex(L, t);
670 lua_rawgeti(L, t, freelist); 681 lua_rawgeti(L, t, freelist);
682 lua_assert(lua_isinteger(L, -1));
671 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ 683 lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
672 lua_pushinteger(L, ref); 684 lua_pushinteger(L, ref);
673 lua_rawseti(L, t, freelist); /* t[freelist] = ref */ 685 lua_rawseti(L, t, freelist); /* t[freelist] = ref */