diff options
Diffstat (limited to 'lauxlib.c')
| -rw-r--r-- | lauxlib.c | 49 |
1 files changed, 10 insertions, 39 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.128 2005/02/10 17:12:02 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.129 2005/02/23 17:30:22 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 | */ |
| @@ -25,12 +25,7 @@ | |||
| 25 | #include "lauxlib.h" | 25 | #include "lauxlib.h" |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | /* number of prereserved references (for internal use) */ | 28 | #define FREELIST_REF 0 /* free list of references */ |
| 29 | #define RESERVED_REFS 2 | ||
| 30 | |||
| 31 | /* reserved references */ | ||
| 32 | #define FREELIST_REF 1 /* free list of references */ | ||
| 33 | #define ARRAYSIZE_REF 2 /* array sizes */ | ||
| 34 | 29 | ||
| 35 | 30 | ||
| 36 | /* convert a stack index to positive */ | 31 | /* convert a stack index to positive */ |
| @@ -275,6 +270,8 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | |||
| 275 | ** ======================================================= | 270 | ** ======================================================= |
| 276 | */ | 271 | */ |
| 277 | 272 | ||
| 273 | #ifndef luaL_getn | ||
| 274 | |||
| 278 | static int checkint (lua_State *L, int topop) { | 275 | static int checkint (lua_State *L, int topop) { |
| 279 | int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; | 276 | int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; |
| 280 | lua_pop(L, topop); | 277 | lua_pop(L, topop); |
| @@ -283,7 +280,7 @@ static int checkint (lua_State *L, int topop) { | |||
| 283 | 280 | ||
| 284 | 281 | ||
| 285 | static void getsizes (lua_State *L) { | 282 | static void getsizes (lua_State *L) { |
| 286 | lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); | 283 | lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); |
| 287 | if (lua_isnil(L, -1)) { /* no `size' table? */ | 284 | if (lua_isnil(L, -1)) { /* no `size' table? */ |
| 288 | lua_pop(L, 1); /* remove nil */ | 285 | lua_pop(L, 1); /* remove nil */ |
| 289 | lua_newtable(L); /* create it */ | 286 | lua_newtable(L); /* create it */ |
| @@ -292,7 +289,7 @@ static void getsizes (lua_State *L) { | |||
| 292 | lua_pushliteral(L, "kv"); | 289 | lua_pushliteral(L, "kv"); |
| 293 | lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ | 290 | lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ |
| 294 | lua_pushvalue(L, -1); | 291 | lua_pushvalue(L, -1); |
| 295 | lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ | 292 | lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ |
| 296 | } | 293 | } |
| 297 | } | 294 | } |
| 298 | 295 | ||
| @@ -307,31 +304,6 @@ LUALIB_API void luaL_setn (lua_State *L, int t, int n) { | |||
| 307 | } | 304 | } |
| 308 | 305 | ||
| 309 | 306 | ||
| 310 | /* find an `n' such that t[n] ~= nil and t[n+1] == nil */ | ||
| 311 | static int countn (lua_State *L, int t) { | ||
| 312 | int i = LUA_FIRSTINDEX - 1; | ||
| 313 | int j = 2; | ||
| 314 | /* find `i' such that i <= n < i*2 (= j) */ | ||
| 315 | for (;;) { | ||
| 316 | lua_rawgeti(L, t, j); | ||
| 317 | if (lua_isnil(L, -1)) break; | ||
| 318 | lua_pop(L, 1); | ||
| 319 | i = j; | ||
| 320 | j = i*2; | ||
| 321 | } | ||
| 322 | lua_pop(L, 1); | ||
| 323 | /* i <= n < j; do a binary search */ | ||
| 324 | while (i < j-1) { | ||
| 325 | int m = (i+j)/2; | ||
| 326 | lua_rawgeti(L, t, m); | ||
| 327 | if (lua_isnil(L, -1)) j = m; | ||
| 328 | else i = m; | ||
| 329 | lua_pop(L, 1); | ||
| 330 | } | ||
| 331 | return i - LUA_FIRSTINDEX + 1; | ||
| 332 | } | ||
| 333 | |||
| 334 | |||
| 335 | LUALIB_API int luaL_getn (lua_State *L, int t) { | 307 | LUALIB_API int luaL_getn (lua_State *L, int t) { |
| 336 | int n; | 308 | int n; |
| 337 | t = abs_index(L, t); | 309 | t = abs_index(L, t); |
| @@ -341,9 +313,11 @@ LUALIB_API int luaL_getn (lua_State *L, int t) { | |||
| 341 | if ((n = checkint(L, 2)) >= 0) return n; | 313 | if ((n = checkint(L, 2)) >= 0) return n; |
| 342 | lua_getfield(L, t, "n"); /* else try t.n */ | 314 | lua_getfield(L, t, "n"); /* else try t.n */ |
| 343 | if ((n = checkint(L, 1)) >= 0) return n; | 315 | if ((n = checkint(L, 1)) >= 0) return n; |
| 344 | return countn(L, t); | 316 | return lua_objsize(L, t); |
| 345 | } | 317 | } |
| 346 | 318 | ||
| 319 | #endif | ||
| 320 | |||
| 347 | /* }====================================================== */ | 321 | /* }====================================================== */ |
| 348 | 322 | ||
| 349 | 323 | ||
| @@ -562,11 +536,8 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
| 562 | lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ | 536 | lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ |
| 563 | } | 537 | } |
| 564 | else { /* no free elements */ | 538 | else { /* no free elements */ |
| 565 | ref = luaL_getn(L, t); | 539 | ref = lua_objsize(L, t); |
| 566 | if (ref < RESERVED_REFS) | ||
| 567 | ref = RESERVED_REFS; /* skip reserved references */ | ||
| 568 | ref++; /* create new reference */ | 540 | ref++; /* create new reference */ |
| 569 | luaL_setn(L, t, ref); | ||
| 570 | } | 541 | } |
| 571 | lua_rawseti(L, t, ref); | 542 | lua_rawseti(L, t, ref); |
| 572 | return ref; | 543 | return ref; |
