diff options
-rw-r--r-- | lbuiltin.c | 33 | ||||
-rw-r--r-- | ltable.c | 45 | ||||
-rw-r--r-- | ltable.h | 7 |
3 files changed, 29 insertions, 56 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbuiltin.c,v 1.67 1999/10/14 19:13:31 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.68 1999/10/19 13:33:22 roberto Exp roberto $ |
3 | ** Built-in functions | 3 | ** Built-in functions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -68,7 +68,7 @@ static real getnarg (const Hash *a) { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | 70 | ||
71 | static Hash *gethash (int arg) { | 71 | static Hash *gettable (int arg) { |
72 | return avalue(luaA_Address(luaL_tablearg(arg))); | 72 | return avalue(luaA_Address(luaL_tablearg(arg))); |
73 | } | 73 | } |
74 | 74 | ||
@@ -285,7 +285,7 @@ static void luaB_dofile (void) { | |||
285 | 285 | ||
286 | static void luaB_call (void) { | 286 | static void luaB_call (void) { |
287 | lua_Object f = luaL_nonnullarg(1); | 287 | lua_Object f = luaL_nonnullarg(1); |
288 | const Hash *arg = gethash(2); | 288 | const Hash *arg = gettable(2); |
289 | const char *options = luaL_opt_string(3, ""); | 289 | const char *options = luaL_opt_string(3, ""); |
290 | lua_Object err = lua_getparam(4); | 290 | lua_Object err = lua_getparam(4); |
291 | int narg = (int)getnarg(arg); | 291 | int narg = (int)getnarg(arg); |
@@ -335,7 +335,7 @@ static void luaB_nextvar (void) { | |||
335 | 335 | ||
336 | 336 | ||
337 | static void luaB_next (void) { | 337 | static void luaB_next (void) { |
338 | const Hash *a = gethash(1); | 338 | const Hash *a = gettable(1); |
339 | const TObject *k = luaA_Address(luaL_nonnullarg(2)); | 339 | const TObject *k = luaA_Address(luaL_nonnullarg(2)); |
340 | int i; /* will get first element after `i' */ | 340 | int i; /* will get first element after `i' */ |
341 | if (ttype(k) == LUA_T_NIL) | 341 | if (ttype(k) == LUA_T_NIL) |
@@ -406,7 +406,7 @@ static void luaB_assert (void) { | |||
406 | 406 | ||
407 | 407 | ||
408 | static void luaB_foreachi (void) { | 408 | static void luaB_foreachi (void) { |
409 | const Hash *t = gethash(1); | 409 | const Hash *t = gettable(1); |
410 | int i; | 410 | int i; |
411 | int n = (int)getnarg(t); | 411 | int n = (int)getnarg(t); |
412 | TObject f; | 412 | TObject f; |
@@ -428,7 +428,7 @@ static void luaB_foreachi (void) { | |||
428 | 428 | ||
429 | 429 | ||
430 | static void luaB_foreach (void) { | 430 | static void luaB_foreach (void) { |
431 | const Hash *a = gethash(1); | 431 | const Hash *a = gettable(1); |
432 | int i; | 432 | int i; |
433 | TObject f; /* see comment in 'foreachi' */ | 433 | TObject f; /* see comment in 'foreachi' */ |
434 | f = *luaA_Address(luaL_functionarg(2)); | 434 | f = *luaA_Address(luaL_functionarg(2)); |
@@ -472,12 +472,12 @@ static void luaB_foreachvar (void) { | |||
472 | 472 | ||
473 | 473 | ||
474 | static void luaB_getn (void) { | 474 | static void luaB_getn (void) { |
475 | lua_pushnumber(getnarg(gethash(1))); | 475 | lua_pushnumber(getnarg(gettable(1))); |
476 | } | 476 | } |
477 | 477 | ||
478 | 478 | ||
479 | static void luaB_tinsert (void) { | 479 | static void luaB_tinsert (void) { |
480 | Hash *a = gethash(1); | 480 | Hash *a = gettable(1); |
481 | lua_Object v = lua_getparam(3); | 481 | lua_Object v = lua_getparam(3); |
482 | int n = (int)getnarg(a); | 482 | int n = (int)getnarg(a); |
483 | int pos; | 483 | int pos; |
@@ -495,7 +495,7 @@ static void luaB_tinsert (void) { | |||
495 | 495 | ||
496 | 496 | ||
497 | static void luaB_tremove (void) { | 497 | static void luaB_tremove (void) { |
498 | Hash *a = gethash(1); | 498 | Hash *a = gettable(1); |
499 | int n = (int)getnarg(a); | 499 | int n = (int)getnarg(a); |
500 | int pos = luaL_opt_int(2, n); | 500 | int pos = luaL_opt_int(2, n); |
501 | if (n <= 0) return; /* table is "empty" */ | 501 | if (n <= 0) return; /* table is "empty" */ |
@@ -583,7 +583,7 @@ static void auxsort (Hash *a, int l, int u, lua_Object f) { | |||
583 | 583 | ||
584 | static void luaB_sort (void) { | 584 | static void luaB_sort (void) { |
585 | lua_Object t = lua_getparam(1); | 585 | lua_Object t = lua_getparam(1); |
586 | Hash *a = gethash(1); | 586 | Hash *a = gettable(1); |
587 | int n = (int)getnarg(a); | 587 | int n = (int)getnarg(a); |
588 | lua_Object func = lua_getparam(2); | 588 | lua_Object func = lua_getparam(2); |
589 | luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2, | 589 | luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2, |
@@ -616,8 +616,14 @@ static void mem_query (void) { | |||
616 | 616 | ||
617 | static void hash_query (void) { | 617 | static void hash_query (void) { |
618 | const TObject *o = luaA_Address(luaL_nonnullarg(1)); | 618 | const TObject *o = luaA_Address(luaL_nonnullarg(1)); |
619 | luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "string expected"); | 619 | if (lua_getparam(2) == LUA_NOOBJECT) { |
620 | lua_pushnumber(tsvalue(o)->hash); | 620 | luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "string expected"); |
621 | lua_pushnumber(tsvalue(o)->hash); | ||
622 | } | ||
623 | else { | ||
624 | const Hash *t = avalue(luaA_Address(luaL_tablearg(2))); | ||
625 | lua_pushnumber(luaH_mainposition(t, o) - t->node); | ||
626 | } | ||
621 | } | 627 | } |
622 | 628 | ||
623 | 629 | ||
@@ -631,7 +637,8 @@ static void table_query (void) { | |||
631 | else if (i < t->size) { | 637 | else if (i < t->size) { |
632 | luaA_pushobject(&t->node[i].key); | 638 | luaA_pushobject(&t->node[i].key); |
633 | luaA_pushobject(&t->node[i].val); | 639 | luaA_pushobject(&t->node[i].val); |
634 | lua_pushnumber(t->node[i].next == NULL ? 0 : t->node[i].next - t->node); | 640 | if (t->node[i].next) |
641 | lua_pushnumber(t->node[i].next - t->node); | ||
635 | } | 642 | } |
636 | } | 643 | } |
637 | 644 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.26 1999/10/14 19:13:31 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.27 1999/10/19 13:33:22 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 | */ |
@@ -38,7 +38,7 @@ | |||
38 | ** returns the `main' position of an element in a table (that is, the index | 38 | ** returns the `main' position of an element in a table (that is, the index |
39 | ** of its hash value) | 39 | ** of its hash value) |
40 | */ | 40 | */ |
41 | static Node *luaH_mainposition (const Hash *t, const TObject *key) { | 41 | Node *luaH_mainposition (const Hash *t, const TObject *key) { |
42 | unsigned long h; | 42 | unsigned long h; |
43 | switch (ttype(key)) { | 43 | switch (ttype(key)) { |
44 | case LUA_T_NUMBER: | 44 | case LUA_T_NUMBER: |
@@ -90,7 +90,7 @@ static Node *hashnodecreate (int nhash) { | |||
90 | Node *v = luaM_newvector(nhash, Node); | 90 | Node *v = luaM_newvector(nhash, Node); |
91 | int i; | 91 | int i; |
92 | for (i=0; i<nhash; i++) { | 92 | for (i=0; i<nhash; i++) { |
93 | ttype(key(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL; | 93 | ttype(&v[i].key) = ttype(&v[i].val) = LUA_T_NIL; |
94 | v[i].next = NULL; | 94 | v[i].next = NULL; |
95 | } | 95 | } |
96 | return v; | 96 | return v; |
@@ -129,48 +129,13 @@ static int newsize (const Hash *t) { | |||
129 | int realuse = 0; | 129 | int realuse = 0; |
130 | int i; | 130 | int i; |
131 | for (i=0; i<size; i++) { | 131 | for (i=0; i<size; i++) { |
132 | if (ttype(val(v+i)) != LUA_T_NIL) | 132 | if (ttype(&v[i].val) != LUA_T_NIL) |
133 | realuse++; | 133 | realuse++; |
134 | } | 134 | } |
135 | return luaO_redimension(realuse*2); | 135 | return luaO_redimension(realuse*2); |
136 | } | 136 | } |
137 | 137 | ||
138 | 138 | ||
139 | #ifdef DEBUG | ||
140 | /* check invariant of a table */ | ||
141 | static int listfind (const Node *m, const Node *n) { | ||
142 | do { | ||
143 | if (m==n) return 1; | ||
144 | m = m->next; | ||
145 | } while (m); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int check_invariant (const Hash *t, int filled) { | ||
150 | Node *n; | ||
151 | for (n=t->node; n<t->firstfree; n++) { | ||
152 | TObject *key = &n->key; | ||
153 | LUA_ASSERT(ttype(key) == LUA_T_NIL || n == luaH_mainposition(t, key), | ||
154 | "all elements before firstfree are empty or in their main positions"); | ||
155 | } | ||
156 | if (!filled) | ||
157 | LUA_ASSERT(ttype(&(n++)->key) == LUA_T_NIL, "firstfree must be empty"); | ||
158 | else | ||
159 | LUA_ASSERT(n == t->node, "table cannot have empty places"); | ||
160 | for (; n<t->node+t->size; n++) { | ||
161 | TObject *key = &n->key; | ||
162 | Node *mp = luaH_mainposition(t, key); | ||
163 | LUA_ASSERT(ttype(key) != LUA_T_NIL, | ||
164 | "cannot exist empty elements after firstfree"); | ||
165 | LUA_ASSERT(n == mp || luaH_mainposition(t, &mp->key) == mp, | ||
166 | "either an element or its colliding element is in its main position"); | ||
167 | LUA_ASSERT(listfind(mp,n), "element is in its main position list"); | ||
168 | } | ||
169 | return 1; | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | |||
174 | /* | 139 | /* |
175 | ** the rehash is done in two stages: first, we insert only the elements whose | 140 | ** the rehash is done in two stages: first, we insert only the elements whose |
176 | ** main position is free, to avoid needless collisions. In the second stage, | 141 | ** main position is free, to avoid needless collisions. In the second stage, |
@@ -180,7 +145,6 @@ static void rehash (Hash *t) { | |||
180 | int oldsize = t->size; | 145 | int oldsize = t->size; |
181 | Node *nold = t->node; | 146 | Node *nold = t->node; |
182 | int i; | 147 | int i; |
183 | LUA_ASSERT(check_invariant(t, 1), "invalid table"); | ||
184 | L->nblocks -= gcsize(oldsize); | 148 | L->nblocks -= gcsize(oldsize); |
185 | setnodevector(t, newsize(t)); /* create new array of nodes */ | 149 | setnodevector(t, newsize(t)); /* create new array of nodes */ |
186 | /* first loop; set only elements that can go in their main positions */ | 150 | /* first loop; set only elements that can go in their main positions */ |
@@ -216,7 +180,6 @@ static void rehash (Hash *t) { | |||
216 | } while (ttype(&t->firstfree->key) != LUA_T_NIL); | 180 | } while (ttype(&t->firstfree->key) != LUA_T_NIL); |
217 | } | 181 | } |
218 | } | 182 | } |
219 | LUA_ASSERT(check_invariant(t, 0), "invalid table"); | ||
220 | luaM_free(nold); /* free old array */ | 183 | luaM_free(nold); /* free old array */ |
221 | } | 184 | } |
222 | 185 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.h,v 1.13 1999/10/04 17:51:04 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 1.14 1999/10/14 19:13:31 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 | */ |
@@ -23,7 +23,10 @@ void luaH_set (Hash *t, const TObject *key, const TObject *val); | |||
23 | int luaH_pos (const Hash *t, const TObject *r); | 23 | int luaH_pos (const Hash *t, const TObject *r); |
24 | void luaH_setint (Hash *t, int key, const TObject *val); | 24 | void luaH_setint (Hash *t, int key, const TObject *val); |
25 | const TObject *luaH_getint (const Hash *t, int key); | 25 | const TObject *luaH_getint (const Hash *t, int key); |
26 | unsigned long luaH_hash (const TObject *key); /* exported only for debugging */ | 26 | unsigned long luaH_hash (const TObject *key); |
27 | |||
28 | /* exported only for debugging */ | ||
29 | Node *luaH_mainposition (const Hash *t, const TObject *key); | ||
27 | 30 | ||
28 | 31 | ||
29 | #endif | 32 | #endif |