diff options
-rw-r--r-- | lapi.c | 24 | ||||
-rw-r--r-- | lauxlib.c | 49 | ||||
-rw-r--r-- | lbaselib.c | 10 | ||||
-rw-r--r-- | ltable.c | 50 | ||||
-rw-r--r-- | ltable.h | 3 | ||||
-rw-r--r-- | ltablib.c | 21 | ||||
-rw-r--r-- | ltests.c | 10 |
7 files changed, 101 insertions, 66 deletions
@@ -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 | ||
351 | LUA_API size_t lua_objsize (lua_State *L, int idx) { | 351 | LUA_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 | ||
@@ -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; |
@@ -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 | ||
335 | static 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 | |||
335 | static int luaB_unpack (lua_State *L) { | 342 | static 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}, |
@@ -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 | |||
528 | static 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 | */ | ||
556 | int 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 | |||
@@ -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); | |||
30 | void luaH_resizearray (lua_State *L, Table *t, int nasize); | 30 | void luaH_resizearray (lua_State *L, Table *t, int nasize); |
31 | void luaH_free (lua_State *L, Table *t); | 31 | void luaH_free (lua_State *L, Table *t); |
32 | int luaH_next (lua_State *L, Table *t, StkId key); | 32 | int luaH_next (lua_State *L, Table *t, StkId key); |
33 | int luaH_getn (Table *t); | ||
33 | 34 | ||
34 | /* exported only for debugging */ | 35 | /* exported only for debugging */ |
35 | Node *luaH_mainposition (const Table *t, const TValue *key); | 36 | Node *luaH_mainposition (const Table *t, const TValue *key); |
@@ -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 | ||
63 | static int setn (lua_State *L) { | 63 | static 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 | ||
71 | static int tinsert (lua_State *L) { | 75 | static 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 | } |
@@ -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 | ||
457 | static int get_limits (lua_State *L) { | 457 | static 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 |
981 | static struct X { int x; } x; | 983 | static struct X { int x; } x; |