summaryrefslogtreecommitdiff
path: root/src/tree.c
diff options
context:
space:
mode:
authorLua Team <team@lua.org>1997-07-01 12:00:00 +0000
committerrepogen <>1997-07-01 12:00:00 +0000
commit4f8c5d0f284e1f4da717aea5008915f185cd2e05 (patch)
tree5671acf8a2cacf0c0524ce96d22959590a3aa5af /src/tree.c
parent47a298a24ad3a8202440051de5938618502302a0 (diff)
downloadlua-github-3.0.tar.gz
Lua 3.03.0
Diffstat (limited to 'src/tree.c')
-rw-r--r--src/tree.c118
1 files changed, 92 insertions, 26 deletions
diff --git a/src/tree.c b/src/tree.c
index 8fbe4200..6f3f2d44 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -3,17 +3,18 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp $";
+char *rcs_tree="$Id: tree.c,v 1.28 1997/06/11 14:24:40 roberto Exp $";
#include <string.h>
-#include "mem.h"
+#include "luamem.h"
#include "lua.h"
#include "tree.h"
#include "lex.h"
#include "hash.h"
#include "table.h"
+#include "fallback.h"
#define NUM_HASHS 64
@@ -28,23 +29,43 @@ static int initialized = 0;
static stringtable string_root[NUM_HASHS];
-static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}};
+static TaggedString EMPTY = {LUA_T_STRING, NULL, {{NOT_USED, NOT_USED}},
+ 0, 2, {0}};
-static unsigned long hash (char *str)
+static unsigned long hash (char *s, int tag)
{
- unsigned long h = 0;
- while (*str)
- h = ((h<<5)-h)^(unsigned char)*(str++);
+ unsigned long h;
+ if (tag != LUA_T_STRING)
+ h = (unsigned long)s;
+ else {
+ h = 0;
+ while (*s)
+ h = ((h<<5)-h)^(unsigned char)*(s++);
+ }
return h;
}
+
+static void luaI_inittree (void)
+{
+ int i;
+ for (i=0; i<NUM_HASHS; i++) {
+ string_root[i].size = 0;
+ string_root[i].nuse = 0;
+ string_root[i].hash = NULL;
+ }
+}
+
+
static void initialize (void)
{
initialized = 1;
+ luaI_inittree();
luaI_addReserved();
luaI_initsymbol();
luaI_initconstant();
+ luaI_initfallbacks();
}
@@ -58,8 +79,7 @@ static void grow (stringtable *tb)
/* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++)
- if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
- {
+ if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
int h = tb->hash[i]->hash%newsize;
while (newhash[h])
h = (h+1)%newsize;
@@ -71,10 +91,30 @@ static void grow (stringtable *tb)
tb->hash = newhash;
}
-static TaggedString *insert (char *str, stringtable *tb)
+
+static TaggedString *newone(char *buff, int tag, unsigned long h)
+{
+ TaggedString *ts;
+ if (tag == LUA_T_STRING) {
+ ts = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(buff));
+ strcpy(ts->str, buff);
+ ts->u.s.varindex = ts->u.s.constindex = NOT_USED;
+ ts->tag = LUA_T_STRING;
+ }
+ else {
+ ts = (TaggedString *)luaI_malloc(sizeof(TaggedString));
+ ts->u.v = buff;
+ ts->tag = tag == LUA_ANYTAG ? 0 : tag;
+ }
+ ts->marked = 0;
+ ts->hash = h;
+ return ts;
+}
+
+static TaggedString *insert (char *buff, int tag, stringtable *tb)
{
TaggedString *ts;
- unsigned long h = hash(str);
+ unsigned long h = hash(buff, tag);
int i;
int j = -1;
if ((Long)tb->nuse*3 >= (Long)tb->size*2)
@@ -84,12 +124,14 @@ static TaggedString *insert (char *str, stringtable *tb)
grow(tb);
}
i = h%tb->size;
- while (tb->hash[i])
+ while ((ts = tb->hash[i]) != NULL)
{
- if (tb->hash[i] == &EMPTY)
+ if (ts == &EMPTY)
j = i;
- else if (strcmp(str, tb->hash[i]->str) == 0)
- return tb->hash[i];
+ else if ((ts->tag == LUA_T_STRING) ?
+ (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) :
+ ((tag == ts->tag || tag == LUA_ANYTAG) && buff == ts->u.v))
+ return ts;
i = (i+1)%tb->size;
}
/* not found */
@@ -98,27 +140,49 @@ static TaggedString *insert (char *str, stringtable *tb)
i = j;
else
tb->nuse++;
- ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
- strcpy(ts->str, str);
- ts->marked = 0;
- ts->hash = h;
- ts->varindex = ts->constindex = NOT_USED;
+ ts = tb->hash[i] = newone(buff, tag, h);
return ts;
}
-TaggedString *lua_createstring (char *str)
+TaggedString *luaI_createudata (void *udata, int tag)
{
- return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
+ return insert(udata, tag, &string_root[(unsigned)udata%NUM_HASHS]);
+}
+
+TaggedString *lua_createstring (char *str)
+{
+ return insert(str, LUA_T_STRING, &string_root[(unsigned)str[0]%NUM_HASHS]);
+}
+
+
+void luaI_strcallIM (TaggedString *l)
+{
+ TObject o;
+ ttype(&o) = LUA_T_USERDATA;
+ for (; l; l=l->next) {
+ tsvalue(&o) = l;
+ luaI_gcIM(&o);
+ }
+}
+
+
+void luaI_strfree (TaggedString *l)
+{
+ while (l) {
+ TaggedString *next = l->next;
+ luaI_free(l);
+ l = next;
+ }
}
/*
** Garbage collection function.
-** This function traverse the string list freeing unindexed strings
*/
-Long lua_strcollector (void)
+TaggedString *luaI_strcollector (long *acum)
{
Long counter = 0;
+ TaggedString *frees = NULL;
int i;
for (i=0; i<NUM_HASHS; i++)
{
@@ -133,13 +197,15 @@ Long lua_strcollector (void)
t->marked = 0;
else
{
- luaI_free(t);
+ t->next = frees;
+ frees = t;
tb->hash[j] = &EMPTY;
counter++;
}
}
}
}
- return counter;
+ *acum += counter;
+ return frees;
}