invariant tests over tables performed externally, through a built-in
function (when DEBUG is ion).
This commit is contained in:
29
lbuiltin.c
29
lbuiltin.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.67 1999/10/14 19:13:31 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.68 1999/10/19 13:33:22 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -68,7 +68,7 @@ static real getnarg (const Hash *a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Hash *gethash (int arg) {
|
static Hash *gettable (int arg) {
|
||||||
return avalue(luaA_Address(luaL_tablearg(arg)));
|
return avalue(luaA_Address(luaL_tablearg(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +285,7 @@ static void luaB_dofile (void) {
|
|||||||
|
|
||||||
static void luaB_call (void) {
|
static void luaB_call (void) {
|
||||||
lua_Object f = luaL_nonnullarg(1);
|
lua_Object f = luaL_nonnullarg(1);
|
||||||
const Hash *arg = gethash(2);
|
const Hash *arg = gettable(2);
|
||||||
const char *options = luaL_opt_string(3, "");
|
const char *options = luaL_opt_string(3, "");
|
||||||
lua_Object err = lua_getparam(4);
|
lua_Object err = lua_getparam(4);
|
||||||
int narg = (int)getnarg(arg);
|
int narg = (int)getnarg(arg);
|
||||||
@@ -335,7 +335,7 @@ static void luaB_nextvar (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_next (void) {
|
static void luaB_next (void) {
|
||||||
const Hash *a = gethash(1);
|
const Hash *a = gettable(1);
|
||||||
const TObject *k = luaA_Address(luaL_nonnullarg(2));
|
const TObject *k = luaA_Address(luaL_nonnullarg(2));
|
||||||
int i; /* will get first element after `i' */
|
int i; /* will get first element after `i' */
|
||||||
if (ttype(k) == LUA_T_NIL)
|
if (ttype(k) == LUA_T_NIL)
|
||||||
@@ -406,7 +406,7 @@ static void luaB_assert (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_foreachi (void) {
|
static void luaB_foreachi (void) {
|
||||||
const Hash *t = gethash(1);
|
const Hash *t = gettable(1);
|
||||||
int i;
|
int i;
|
||||||
int n = (int)getnarg(t);
|
int n = (int)getnarg(t);
|
||||||
TObject f;
|
TObject f;
|
||||||
@@ -428,7 +428,7 @@ static void luaB_foreachi (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_foreach (void) {
|
static void luaB_foreach (void) {
|
||||||
const Hash *a = gethash(1);
|
const Hash *a = gettable(1);
|
||||||
int i;
|
int i;
|
||||||
TObject f; /* see comment in 'foreachi' */
|
TObject f; /* see comment in 'foreachi' */
|
||||||
f = *luaA_Address(luaL_functionarg(2));
|
f = *luaA_Address(luaL_functionarg(2));
|
||||||
@@ -472,12 +472,12 @@ static void luaB_foreachvar (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_getn (void) {
|
static void luaB_getn (void) {
|
||||||
lua_pushnumber(getnarg(gethash(1)));
|
lua_pushnumber(getnarg(gettable(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaB_tinsert (void) {
|
static void luaB_tinsert (void) {
|
||||||
Hash *a = gethash(1);
|
Hash *a = gettable(1);
|
||||||
lua_Object v = lua_getparam(3);
|
lua_Object v = lua_getparam(3);
|
||||||
int n = (int)getnarg(a);
|
int n = (int)getnarg(a);
|
||||||
int pos;
|
int pos;
|
||||||
@@ -495,7 +495,7 @@ static void luaB_tinsert (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_tremove (void) {
|
static void luaB_tremove (void) {
|
||||||
Hash *a = gethash(1);
|
Hash *a = gettable(1);
|
||||||
int n = (int)getnarg(a);
|
int n = (int)getnarg(a);
|
||||||
int pos = luaL_opt_int(2, n);
|
int pos = luaL_opt_int(2, n);
|
||||||
if (n <= 0) return; /* table is "empty" */
|
if (n <= 0) return; /* table is "empty" */
|
||||||
@@ -583,7 +583,7 @@ static void auxsort (Hash *a, int l, int u, lua_Object f) {
|
|||||||
|
|
||||||
static void luaB_sort (void) {
|
static void luaB_sort (void) {
|
||||||
lua_Object t = lua_getparam(1);
|
lua_Object t = lua_getparam(1);
|
||||||
Hash *a = gethash(1);
|
Hash *a = gettable(1);
|
||||||
int n = (int)getnarg(a);
|
int n = (int)getnarg(a);
|
||||||
lua_Object func = lua_getparam(2);
|
lua_Object func = lua_getparam(2);
|
||||||
luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
|
luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
|
||||||
@@ -616,8 +616,14 @@ static void mem_query (void) {
|
|||||||
|
|
||||||
static void hash_query (void) {
|
static void hash_query (void) {
|
||||||
const TObject *o = luaA_Address(luaL_nonnullarg(1));
|
const TObject *o = luaA_Address(luaL_nonnullarg(1));
|
||||||
|
if (lua_getparam(2) == LUA_NOOBJECT) {
|
||||||
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "string expected");
|
luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "string expected");
|
||||||
lua_pushnumber(tsvalue(o)->hash);
|
lua_pushnumber(tsvalue(o)->hash);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const Hash *t = avalue(luaA_Address(luaL_tablearg(2)));
|
||||||
|
lua_pushnumber(luaH_mainposition(t, o) - t->node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -631,7 +637,8 @@ static void table_query (void) {
|
|||||||
else if (i < t->size) {
|
else if (i < t->size) {
|
||||||
luaA_pushobject(&t->node[i].key);
|
luaA_pushobject(&t->node[i].key);
|
||||||
luaA_pushobject(&t->node[i].val);
|
luaA_pushobject(&t->node[i].val);
|
||||||
lua_pushnumber(t->node[i].next == NULL ? 0 : t->node[i].next - t->node);
|
if (t->node[i].next)
|
||||||
|
lua_pushnumber(t->node[i].next - t->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
ltable.c
45
ltable.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 1.26 1999/10/14 19:13:31 roberto Exp roberto $
|
** $Id: ltable.c,v 1.27 1999/10/19 13:33:22 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
** returns the `main' position of an element in a table (that is, the index
|
** returns the `main' position of an element in a table (that is, the index
|
||||||
** of its hash value)
|
** of its hash value)
|
||||||
*/
|
*/
|
||||||
static Node *luaH_mainposition (const Hash *t, const TObject *key) {
|
Node *luaH_mainposition (const Hash *t, const TObject *key) {
|
||||||
unsigned long h;
|
unsigned long h;
|
||||||
switch (ttype(key)) {
|
switch (ttype(key)) {
|
||||||
case LUA_T_NUMBER:
|
case LUA_T_NUMBER:
|
||||||
@@ -90,7 +90,7 @@ static Node *hashnodecreate (int nhash) {
|
|||||||
Node *v = luaM_newvector(nhash, Node);
|
Node *v = luaM_newvector(nhash, Node);
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<nhash; i++) {
|
for (i=0; i<nhash; i++) {
|
||||||
ttype(key(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL;
|
ttype(&v[i].key) = ttype(&v[i].val) = LUA_T_NIL;
|
||||||
v[i].next = NULL;
|
v[i].next = NULL;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
@@ -129,48 +129,13 @@ static int newsize (const Hash *t) {
|
|||||||
int realuse = 0;
|
int realuse = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<size; i++) {
|
for (i=0; i<size; i++) {
|
||||||
if (ttype(val(v+i)) != LUA_T_NIL)
|
if (ttype(&v[i].val) != LUA_T_NIL)
|
||||||
realuse++;
|
realuse++;
|
||||||
}
|
}
|
||||||
return luaO_redimension(realuse*2);
|
return luaO_redimension(realuse*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
/* check invariant of a table */
|
|
||||||
static int listfind (const Node *m, const Node *n) {
|
|
||||||
do {
|
|
||||||
if (m==n) return 1;
|
|
||||||
m = m->next;
|
|
||||||
} while (m);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int check_invariant (const Hash *t, int filled) {
|
|
||||||
Node *n;
|
|
||||||
for (n=t->node; n<t->firstfree; n++) {
|
|
||||||
TObject *key = &n->key;
|
|
||||||
LUA_ASSERT(ttype(key) == LUA_T_NIL || n == luaH_mainposition(t, key),
|
|
||||||
"all elements before firstfree are empty or in their main positions");
|
|
||||||
}
|
|
||||||
if (!filled)
|
|
||||||
LUA_ASSERT(ttype(&(n++)->key) == LUA_T_NIL, "firstfree must be empty");
|
|
||||||
else
|
|
||||||
LUA_ASSERT(n == t->node, "table cannot have empty places");
|
|
||||||
for (; n<t->node+t->size; n++) {
|
|
||||||
TObject *key = &n->key;
|
|
||||||
Node *mp = luaH_mainposition(t, key);
|
|
||||||
LUA_ASSERT(ttype(key) != LUA_T_NIL,
|
|
||||||
"cannot exist empty elements after firstfree");
|
|
||||||
LUA_ASSERT(n == mp || luaH_mainposition(t, &mp->key) == mp,
|
|
||||||
"either an element or its colliding element is in its main position");
|
|
||||||
LUA_ASSERT(listfind(mp,n), "element is in its main position list");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** the rehash is done in two stages: first, we insert only the elements whose
|
** the rehash is done in two stages: first, we insert only the elements whose
|
||||||
** main position is free, to avoid needless collisions. In the second stage,
|
** main position is free, to avoid needless collisions. In the second stage,
|
||||||
@@ -180,7 +145,6 @@ static void rehash (Hash *t) {
|
|||||||
int oldsize = t->size;
|
int oldsize = t->size;
|
||||||
Node *nold = t->node;
|
Node *nold = t->node;
|
||||||
int i;
|
int i;
|
||||||
LUA_ASSERT(check_invariant(t, 1), "invalid table");
|
|
||||||
L->nblocks -= gcsize(oldsize);
|
L->nblocks -= gcsize(oldsize);
|
||||||
setnodevector(t, newsize(t)); /* create new array of nodes */
|
setnodevector(t, newsize(t)); /* create new array of nodes */
|
||||||
/* first loop; set only elements that can go in their main positions */
|
/* first loop; set only elements that can go in their main positions */
|
||||||
@@ -216,7 +180,6 @@ static void rehash (Hash *t) {
|
|||||||
} while (ttype(&t->firstfree->key) != LUA_T_NIL);
|
} while (ttype(&t->firstfree->key) != LUA_T_NIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LUA_ASSERT(check_invariant(t, 0), "invalid table");
|
|
||||||
luaM_free(nold); /* free old array */
|
luaM_free(nold); /* free old array */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
ltable.h
7
ltable.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.h,v 1.13 1999/10/04 17:51:04 roberto Exp roberto $
|
** $Id: ltable.h,v 1.14 1999/10/14 19:13:31 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -23,7 +23,10 @@ void luaH_set (Hash *t, const TObject *key, const TObject *val);
|
|||||||
int luaH_pos (const Hash *t, const TObject *r);
|
int luaH_pos (const Hash *t, const TObject *r);
|
||||||
void luaH_setint (Hash *t, int key, const TObject *val);
|
void luaH_setint (Hash *t, int key, const TObject *val);
|
||||||
const TObject *luaH_getint (const Hash *t, int key);
|
const TObject *luaH_getint (const Hash *t, int key);
|
||||||
unsigned long luaH_hash (const TObject *key); /* exported only for debugging */
|
unsigned long luaH_hash (const TObject *key);
|
||||||
|
|
||||||
|
/* exported only for debugging */
|
||||||
|
Node *luaH_mainposition (const Hash *t, const TObject *key);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user