diff options
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 28 |
1 files changed, 12 insertions, 16 deletions
@@ -672,13 +672,10 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { | |||
672 | ** ======================================================= | 672 | ** ======================================================= |
673 | */ | 673 | */ |
674 | 674 | ||
675 | /* index of free-list header (after the predefined values) */ | ||
676 | #define freelist (LUA_RIDX_LAST + 1) | ||
677 | |||
678 | /* | 675 | /* |
679 | ** The previously freed references form a linked list: | 676 | ** The previously freed references form a linked list: t[1] is the index |
680 | ** t[freelist] is the index of a first free index, or zero if list is | 677 | ** of a first free index, t[t[1]] is the index of the second element, |
681 | ** empty; t[t[freelist]] is the index of the second element; etc. | 678 | ** etc. A zero signals the end of the list. |
682 | */ | 679 | */ |
683 | LUALIB_API int luaL_ref (lua_State *L, int t) { | 680 | LUALIB_API int luaL_ref (lua_State *L, int t) { |
684 | int ref; | 681 | int ref; |
@@ -687,19 +684,18 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
687 | return LUA_REFNIL; /* 'nil' has a unique fixed reference */ | 684 | return LUA_REFNIL; /* 'nil' has a unique fixed reference */ |
688 | } | 685 | } |
689 | t = lua_absindex(L, t); | 686 | t = lua_absindex(L, t); |
690 | if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ | 687 | if (lua_rawgeti(L, t, 1) == LUA_TNUMBER) /* already initialized? */ |
688 | ref = (int)lua_tointeger(L, -1); /* ref = t[1] */ | ||
689 | else { /* first access */ | ||
690 | lua_assert(!lua_toboolean(L, -1)); /* must be nil or false */ | ||
691 | ref = 0; /* list is empty */ | 691 | ref = 0; /* list is empty */ |
692 | lua_pushinteger(L, 0); /* initialize as an empty list */ | 692 | lua_pushinteger(L, 0); /* initialize as an empty list */ |
693 | lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ | 693 | lua_rawseti(L, t, 1); /* ref = t[1] = 0 */ |
694 | } | ||
695 | else { /* already initialized */ | ||
696 | lua_assert(lua_isinteger(L, -1)); | ||
697 | ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ | ||
698 | } | 694 | } |
699 | lua_pop(L, 1); /* remove element from stack */ | 695 | lua_pop(L, 1); /* remove element from stack */ |
700 | if (ref != 0) { /* any free element? */ | 696 | if (ref != 0) { /* any free element? */ |
701 | lua_rawgeti(L, t, ref); /* remove it from list */ | 697 | lua_rawgeti(L, t, ref); /* remove it from list */ |
702 | lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ | 698 | lua_rawseti(L, t, 1); /* (t[1] = t[ref]) */ |
703 | } | 699 | } |
704 | else /* no free elements */ | 700 | else /* no free elements */ |
705 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ | 701 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ |
@@ -711,11 +707,11 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
711 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | 707 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { |
712 | if (ref >= 0) { | 708 | if (ref >= 0) { |
713 | t = lua_absindex(L, t); | 709 | t = lua_absindex(L, t); |
714 | lua_rawgeti(L, t, freelist); | 710 | lua_rawgeti(L, t, 1); |
715 | lua_assert(lua_isinteger(L, -1)); | 711 | lua_assert(lua_isinteger(L, -1)); |
716 | lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ | 712 | lua_rawseti(L, t, ref); /* t[ref] = t[1] */ |
717 | lua_pushinteger(L, ref); | 713 | lua_pushinteger(L, ref); |
718 | lua_rawseti(L, t, freelist); /* t[freelist] = ref */ | 714 | lua_rawseti(L, t, 1); /* t[1] = ref */ |
719 | } | 715 | } |
720 | } | 716 | } |
721 | 717 | ||