diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-02-11 07:44:38 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-02-11 07:44:38 -0200 |
commit | 3cdeacbbfba9308dd2dcc995a9bcc510bfcead31 (patch) | |
tree | ea40da115fb71a31af48affd190f0afaf71658c1 | |
parent | 6f207b15fb20f1c7d06224354cfdf5e32fdbba68 (diff) | |
download | lua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.tar.gz lua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.tar.bz2 lua-3cdeacbbfba9308dd2dcc995a9bcc510bfcead31.zip |
reference system also uses getn/setn (plus small corrections)
-rw-r--r-- | lauxlib.c | 47 |
1 files changed, 21 insertions, 26 deletions
@@ -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) { | |||
219 | static void getsizes (lua_State *L) { | 220 | static 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 | ||
402 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | 397 | LUALIB_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 | ||