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