aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-26 08:53:40 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-26 08:53:40 -0200
commit5a48255c9f75dea0799c1a3b55b9df11b2a666fb (patch)
treec3a1f3158f3f07e69f99ea7a61004f7dea52aaa3
parentbbab974717f9802066f56b939d4f053acc865f24 (diff)
downloadlua-5a48255c9f75dea0799c1a3b55b9df11b2a666fb.tar.gz
lua-5a48255c9f75dea0799c1a3b55b9df11b2a666fb.tar.bz2
lua-5a48255c9f75dea0799c1a3b55b9df11b2a666fb.zip
invariant tests over tables performed externally, through a built-in
function (when DEBUG is ion).
-rw-r--r--lbuiltin.c33
-rw-r--r--ltable.c45
-rw-r--r--ltable.h7
3 files changed, 29 insertions, 56 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index c37d4eb0..c5fd233f 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -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
71static Hash *gethash (int arg) { 71static 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
286static void luaB_call (void) { 286static 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
337static void luaB_next (void) { 337static 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
408static void luaB_foreachi (void) { 408static 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
430static void luaB_foreach (void) { 430static 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
474static void luaB_getn (void) { 474static void luaB_getn (void) {
475 lua_pushnumber(getnarg(gethash(1))); 475 lua_pushnumber(getnarg(gettable(1)));
476} 476}
477 477
478 478
479static void luaB_tinsert (void) { 479static 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
497static void luaB_tremove (void) { 497static 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
584static void luaB_sort (void) { 584static 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
617static void hash_query (void) { 617static 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
diff --git a/ltable.c b/ltable.c
index 947f1813..e16fe5da 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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*/
41static Node *luaH_mainposition (const Hash *t, const TObject *key) { 41Node *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 */
141static 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
149static 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
diff --git a/ltable.h b/ltable.h
index 219574b9..e1d567f0 100644
--- a/ltable.h
+++ b/ltable.h
@@ -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);
23int luaH_pos (const Hash *t, const TObject *r); 23int luaH_pos (const Hash *t, const TObject *r);
24void luaH_setint (Hash *t, int key, const TObject *val); 24void luaH_setint (Hash *t, int key, const TObject *val);
25const TObject *luaH_getint (const Hash *t, int key); 25const TObject *luaH_getint (const Hash *t, int key);
26unsigned long luaH_hash (const TObject *key); /* exported only for debugging */ 26unsigned long luaH_hash (const TObject *key);
27
28/* exported only for debugging */
29Node *luaH_mainposition (const Hash *t, const TObject *key);
27 30
28 31
29#endif 32#endif