aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c24
-rw-r--r--lauxlib.c49
-rw-r--r--lbaselib.c10
-rw-r--r--ltable.c50
-rw-r--r--ltable.h3
-rw-r--r--ltablib.c21
-rw-r--r--ltests.c10
7 files changed, 101 insertions, 66 deletions
diff --git a/lapi.c b/lapi.c
index b13aa6c5..d51ac270 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.30 2005/03/08 20:10:05 roberto Exp roberto $ 2** $Id: lapi.c,v 2.31 2005/03/09 16:28:07 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -350,16 +350,18 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) {
350 350
351LUA_API size_t lua_objsize (lua_State *L, int idx) { 351LUA_API size_t lua_objsize (lua_State *L, int idx) {
352 StkId o = index2adr(L, idx); 352 StkId o = index2adr(L, idx);
353 if (ttisstring(o)) 353 switch (ttype(o)) {
354 return tsvalue(o)->len; 354 case LUA_TSTRING: return tsvalue(o)->len;
355 else if (ttisuserdata(o)) 355 case LUA_TUSERDATA: return uvalue(o)->len;
356 return uvalue(o)->len; 356 case LUA_TTABLE: return luaH_getn(hvalue(o));
357 else { 357 case LUA_TNUMBER: {
358 size_t l; 358 size_t l;
359 lua_lock(L); /* `luaV_tostring' may create a new string */ 359 lua_lock(L); /* `luaV_tostring' may create a new string */
360 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); 360 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
361 lua_unlock(L); 361 lua_unlock(L);
362 return l; 362 return l;
363 }
364 default: return 0;
363 } 365 }
364} 366}
365 367
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;
diff --git a/lbaselib.c b/lbaselib.c
index 442ca621..20dcefe2 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.169 2005/02/28 17:24:41 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.170 2005/03/11 15:51:08 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -332,6 +332,13 @@ static int luaB_assert (lua_State *L) {
332} 332}
333 333
334 334
335static int luaB_getn (lua_State *L) {
336 luaL_checktype(L, 1, LUA_TTABLE);
337 lua_pushinteger(L, lua_objsize(L, 1));
338 return 1;
339}
340
341
335static int luaB_unpack (lua_State *L) { 342static int luaB_unpack (lua_State *L) {
336 int i = luaL_optint(L, 2, LUA_FIRSTINDEX); 343 int i = luaL_optint(L, 2, LUA_FIRSTINDEX);
337 int e = luaL_optint(L, 3, -1); 344 int e = luaL_optint(L, 3, -1);
@@ -448,6 +455,7 @@ static const luaL_reg base_funcs[] = {
448 {"tostring", luaB_tostring}, 455 {"tostring", luaB_tostring},
449 {"type", luaB_type}, 456 {"type", luaB_type},
450 {"assert", luaB_assert}, 457 {"assert", luaB_assert},
458 {"getn", luaB_getn},
451 {"unpack", luaB_unpack}, 459 {"unpack", luaB_unpack},
452 {"select", luaB_select}, 460 {"select", luaB_select},
453 {"rawequal", luaB_rawequal}, 461 {"rawequal", luaB_rawequal},
diff --git a/ltable.c b/ltable.c
index d66cc2e5..eaf4ea7d 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.17 2005/03/08 20:10:05 roberto Exp roberto $ 2** $Id: ltable.c,v 2.18 2005/03/09 16:28:07 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -524,3 +524,51 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
524 } 524 }
525} 525}
526 526
527
528static int unbound_search (Table *t, unsigned int j) {
529 unsigned int i = j; /* i is zero or a present index */
530 j = j+1;
531 /* find `i' and `j' such that i is present and j is not */
532 while (!ttisnil(luaH_getnum(t, j))) {
533 i = j;
534 j = i*2;
535 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
536 /* table was built with bad purposes: resort to linear search */
537 i = 1;
538 while (!ttisnil(luaH_getnum(t, i))) i++;
539 return i - 1;
540 }
541 }
542 /* now do a binary search between them */
543 while (i < j-1) {
544 unsigned int m = (i+j)/2;
545 if (ttisnil(luaH_getnum(t, m))) j = m;
546 else i = m;
547 }
548 return i;
549}
550
551
552/*
553** Try to find a boundary in table `t'. A `boundary' is an integer index
554** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
555*/
556int luaH_getn (Table *t) {
557 unsigned int j = t->sizearray;
558 if (j > 0 && ttisnil(&t->array[j - 1])) {
559 /* there is a boundary in the array part: (binary) search for it */
560 unsigned int i = 1;
561 if (ttisnil(&t->array[1 - 1])) return 0;
562 while (i < j - 1) {
563 unsigned int m = (i+j)/2;
564 if (ttisnil(&t->array[m - 1])) j = m;
565 else i = m;
566 }
567 return i;
568 }
569 /* else must find a boundary in hash part */
570 else if (t->node == &luaH_dummynode) /* hash part is empty? */
571 return j; /* that is easy... */
572 else return unbound_search(t, j);
573}
574
diff --git a/ltable.h b/ltable.h
index d8ba8c8a..0036198f 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.4 2005/01/04 15:55:12 roberto Exp roberto $ 2** $Id: ltable.h,v 2.5 2005/01/05 18:20:51 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,6 +30,7 @@ Table *luaH_new (lua_State *L, int narray, int lnhash);
30void luaH_resizearray (lua_State *L, Table *t, int nasize); 30void luaH_resizearray (lua_State *L, Table *t, int nasize);
31void luaH_free (lua_State *L, Table *t); 31void luaH_free (lua_State *L, Table *t);
32int luaH_next (lua_State *L, Table *t, StkId key); 32int luaH_next (lua_State *L, Table *t, StkId key);
33int luaH_getn (Table *t);
33 34
34/* exported only for debugging */ 35/* exported only for debugging */
35Node *luaH_mainposition (const Table *t, const TValue *key); 36Node *luaH_mainposition (const Table *t, const TValue *key);
diff --git a/ltablib.c b/ltablib.c
index 572730aa..42575685 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltablib.c,v 1.26 2004/06/15 13:37:21 roberto Exp roberto $ 2** $Id: ltablib.c,v 1.27 2004/12/07 18:28:47 roberto Exp roberto $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -62,29 +62,32 @@ static int getn (lua_State *L) {
62 62
63static int setn (lua_State *L) { 63static int setn (lua_State *L) {
64 luaL_checktype(L, 1, LUA_TTABLE); 64 luaL_checktype(L, 1, LUA_TTABLE);
65#ifndef luaL_setn
65 luaL_setn(L, 1, luaL_checkint(L, 2)); 66 luaL_setn(L, 1, luaL_checkint(L, 2));
67#else
68 luaL_error(L, "`setn' is obsolete");
69#endif
66 lua_pushvalue(L, 1); 70 lua_pushvalue(L, 1);
67 return 1; 71 return 1;
68} 72}
69 73
70 74
71static int tinsert (lua_State *L) { 75static int tinsert (lua_State *L) {
72 int v = lua_gettop(L); /* number of arguments */
73 int e = aux_getn(L, 1) + LUA_FIRSTINDEX; /* first empty element */ 76 int e = aux_getn(L, 1) + LUA_FIRSTINDEX; /* first empty element */
74 int pos; /* where to insert new element */ 77 int pos; /* where to insert new element */
75 if (v == 2) /* called with only 2 arguments */ 78 if (lua_isnone(L, 3)) /* called with only 2 arguments */
76 pos = e; /* insert new element at the end */ 79 pos = e; /* insert new element at the end */
77 else { 80 else {
81 int i;
78 pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 82 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
79 if (pos > e) e = pos; /* `grow' array if necessary */ 83 if (pos > e) e = pos; /* `grow' array if necessary */
80 v = 3; /* function may be called with more than 3 args */ 84 lua_settop(L, 3); /* function may be called with more than 3 args */
85 for (i = e; i > pos; i--) { /* move up elements */
86 lua_rawgeti(L, 1, i-1);
87 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
88 }
81 } 89 }
82 luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */ 90 luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */
83 while (--e >= pos) { /* move up elements */
84 lua_rawgeti(L, 1, e);
85 lua_rawseti(L, 1, e+1); /* t[e+1] = t[e] */
86 }
87 lua_pushvalue(L, v);
88 lua_rawseti(L, 1, pos); /* t[pos] = v */ 91 lua_rawseti(L, 1, pos); /* t[pos] = v */
89 return 0; 92 return 0;
90} 93}
diff --git a/ltests.c b/ltests.c
index 620b6a41..717e0c5e 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.19 2005/01/19 15:54:26 roberto Exp roberto $ 2** $Id: ltests.c,v 2.20 2005/02/18 12:40:02 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -456,11 +456,11 @@ static int listlocals (lua_State *L) {
456 456
457static int get_limits (lua_State *L) { 457static int get_limits (lua_State *L) {
458 lua_createtable(L, 0, 5); 458 lua_createtable(L, 0, 5);
459 setnameval(L, "BITS_INT", LUA_BITSINT); 459 setnameval(L, "BITS_INT", LUAI_BITSINT);
460 setnameval(L, "LFPF", LFIELDS_PER_FLUSH); 460 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
461 setnameval(L, "MAXVARS", MAXVARS); 461 setnameval(L, "MAXVARS", LUAI_MAXVARS);
462 setnameval(L, "MAXSTACK", MAXSTACK); 462 setnameval(L, "MAXSTACK", MAXSTACK);
463 setnameval(L, "MAXUPVALUES", MAXUPVALUES); 463 setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
464 setnameval(L, "NUM_OPCODES", NUM_OPCODES); 464 setnameval(L, "NUM_OPCODES", NUM_OPCODES);
465 return 1; 465 return 1;
466} 466}
@@ -970,12 +970,14 @@ static int testC (lua_State *L) {
970 int i = getindex; 970 int i = getindex;
971 lua_pushinteger(L1, luaL_getn(L1, i)); 971 lua_pushinteger(L1, luaL_getn(L1, i));
972 } 972 }
973#ifndef luaL_setn
973 else if EQ("setn") { 974 else if EQ("setn") {
974 int i = getindex; 975 int i = getindex;
975 int n = cast(int, lua_tonumber(L1, -1)); 976 int n = cast(int, lua_tonumber(L1, -1));
976 luaL_setn(L1, i, n); 977 luaL_setn(L1, i, n);
977 lua_pop(L1, 1); 978 lua_pop(L1, 1);
978 } 979 }
980#endif
979 else if EQ("throw") { 981 else if EQ("throw") {
980#ifdef __cplusplus 982#ifdef __cplusplus
981static struct X { int x; } x; 983static struct X { int x; } x;