aboutsummaryrefslogtreecommitdiff
path: root/lauxlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-03-16 13:58:41 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-03-16 13:58:41 -0300
commit9ffae705ee8894d68bbc07a1a5f77a112c40efad (patch)
treee162bb7ecfd1a3e6776cf09e62736ec8eb0fca41 /lauxlib.c
parent6bfef60e77f5eec1057470010b4179ee6f830fe6 (diff)
downloadlua-9ffae705ee8894d68bbc07a1a5f77a112c40efad.tar.gz
lua-9ffae705ee8894d68bbc07a1a5f77a112c40efad.tar.bz2
lua-9ffae705ee8894d68bbc07a1a5f77a112c40efad.zip
new "primitive" getn
Diffstat (limited to 'lauxlib.c')
-rw-r--r--lauxlib.c49
1 files changed, 10 insertions, 39 deletions
diff --git a/lauxlib.c b/lauxlib.c
index cccff91b..835ae5b9 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
278static int checkint (lua_State *L, int topop) { 275static 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
285static void getsizes (lua_State *L) { 282static 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 */
311static 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
335LUALIB_API int luaL_getn (lua_State *L, int t) { 307LUALIB_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;