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 | ||
