aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-02-11 07:44:38 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-02-11 07:44:38 -0200
commit3cdeacbbfba9308dd2dcc995a9bcc510bfcead31 (patch)
treeea40da115fb71a31af48affd190f0afaf71658c1
parent6f207b15fb20f1c7d06224354cfdf5e32fdbba68 (diff)
downloadlua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.tar.gz
lua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.tar.bz2
lua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.zip
reference system also uses getn/setn (plus small corrections)
-rw-r--r--lauxlib.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 9f39b46b..adc0f905 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.92 2003/01/23 11:34:18 roberto Exp roberto $ 2** $Id: lauxlib.c,v 1.93 2003/01/27 13:46:16 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*/
@@ -24,10 +24,11 @@
24 24
25 25
26/* number of prereserved references (for internal use) */ 26/* number of prereserved references (for internal use) */
27#define RESERVED_REFS 1 27#define RESERVED_REFS 2
28 28
29/* reserved reference for array sizes */ 29/* reserved references */
30#define ARRAYSIZE_REF 1 30#define FREELIST_REF 1 /* free list of references */
31#define ARRAYSIZE_REF 2 /* array sizes */
31 32
32 33
33/* 34/*
@@ -219,6 +220,7 @@ static int checkint (lua_State *L, int topop) {
219static void getsizes (lua_State *L) { 220static void getsizes (lua_State *L) {
220 lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); 221 lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
221 if (lua_isnil(L, -1)) { /* no `size' table? */ 222 if (lua_isnil(L, -1)) { /* no `size' table? */
223 lua_pop(L, 1); /* remove nil */
222 lua_newtable(L); /* create it */ 224 lua_newtable(L); /* create it */
223 lua_pushvalue(L, -1); /* `size' will be its own metatable */ 225 lua_pushvalue(L, -1); /* `size' will be its own metatable */
224 lua_setmetatable(L, -2); 226 lua_setmetatable(L, -2);
@@ -258,16 +260,13 @@ int luaL_getn (lua_State *L, int t) {
258 lua_pushvalue(L, t); 260 lua_pushvalue(L, t);
259 lua_rawget(L, -2); 261 lua_rawget(L, -2);
260 if ((n = checkint(L, 2)) >= 0) return n; 262 if ((n = checkint(L, 2)) >= 0) return n;
261 else { /* must count elements */ 263 for (n = 1; ; n++) { /* else must count elements */
262 for (n = 1; ; n++) { 264 lua_rawgeti(L, t, n);
263 lua_rawgeti(L, t, n); 265 if (lua_isnil(L, -1)) break;
264 if (lua_isnil(L, -1)) break;
265 lua_pop(L, 1);
266 }
267 lua_pop(L, 1); 266 lua_pop(L, 1);
268 luaL_setn(L, t, n - 1);
269 return n - 1;
270 } 267 }
268 lua_pop(L, 1);
269 return n - 1;
271} 270}
272 271
273/* }====================================================== */ 272/* }====================================================== */
@@ -376,23 +375,19 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
376 lua_pop(L, 1); /* remove from stack */ 375 lua_pop(L, 1); /* remove from stack */
377 return LUA_REFNIL; /* `nil' has a unique fixed reference */ 376 return LUA_REFNIL; /* `nil' has a unique fixed reference */
378 } 377 }
379 lua_rawgeti(L, t, 0); /* get first free element */ 378 lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
380 ref = (int)lua_tonumber(L, -1); /* ref = t[0] */ 379 ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
381 lua_pop(L, 1); /* remove it from stack */ 380 lua_pop(L, 1); /* remove it from stack */
382 if (ref != 0) { /* any free element? */ 381 if (ref != 0) { /* any free element? */
383 lua_rawgeti(L, t, ref); /* remove it from list */ 382 lua_rawgeti(L, t, ref); /* remove it from list */
384 lua_rawseti(L, t, 0); /* (that is, t[0] = t[ref]) */ 383 lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
385 } 384 }
386 else { /* no free elements */ 385 else { /* no free elements */
387 lua_pushliteral(L, "n"); 386 ref = luaL_getn(L, t);
388 lua_pushvalue(L, -1); 387 if (ref < RESERVED_REFS)
389 lua_rawget(L, t); /* get t.n */ 388 ref = RESERVED_REFS; /* skip reserved references */
390 ref = (int)lua_tonumber(L, -1); /* ref = t.n */
391 lua_pop(L, 1); /* pop t.n */
392 if (ref == 0) ref = RESERVED_REFS; /* skip reserved references */
393 ref++; /* create new reference */ 389 ref++; /* create new reference */
394 lua_pushnumber(L, ref); 390 luaL_setn(L, t, ref);
395 lua_rawset(L, t); /* t.n = t.n + 1 */
396 } 391 }
397 lua_rawseti(L, t, ref); 392 lua_rawseti(L, t, ref);
398 return ref; 393 return ref;
@@ -401,10 +396,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
401 396
402LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { 397LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
403 if (ref >= 0) { 398 if (ref >= 0) {
404 lua_rawgeti(L, t, 0); 399 lua_rawgeti(L, t, FREELIST_REF);
405 lua_rawseti(L, t, ref); /* t[ref] = t[0] */ 400 lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
406 lua_pushnumber(L, ref); 401 lua_pushnumber(L, ref);
407 lua_rawseti(L, t, 0); /* t[0] = ref */ 402 lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
408 } 403 }
409} 404}
410 405