aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-02-12 15:32:40 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1996-02-12 15:32:40 -0300
commit41259bff31dbb904edfb8070006ccb15577f8f04 (patch)
tree664bf9cbe6394e9074435ecf2bd710712b4537c3
parentafaa98a666acd5f596b50f56bb288815838c096e (diff)
downloadlua-41259bff31dbb904edfb8070006ccb15577f8f04.tar.gz
lua-41259bff31dbb904edfb8070006ccb15577f8f04.tar.bz2
lua-41259bff31dbb904edfb8070006ccb15577f8f04.zip
BIG CHANGE: new data structure for constants, strings and globals, using
an array of hash tables for all them.
-rw-r--r--func.c4
-rw-r--r--func.h4
-rw-r--r--hash.c26
-rw-r--r--hash.h4
-rw-r--r--inout.c6
-rw-r--r--lex.c4
-rw-r--r--lua.stx14
-rw-r--r--opcode.c15
-rw-r--r--table.c26
-rw-r--r--table.h9
-rw-r--r--tree.c152
-rw-r--r--tree.h17
12 files changed, 146 insertions, 135 deletions
diff --git a/func.c b/func.c
index 616317d6..6a02c78d 100644
--- a/func.c
+++ b/func.c
@@ -97,7 +97,7 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
97/* 97/*
98** Stores information to know that variable has been declared in given line 98** Stores information to know that variable has been declared in given line
99*/ 99*/
100void luaI_registerlocalvar (TreeNode *varname, int line) 100void luaI_registerlocalvar (TaggedString *varname, int line)
101{ 101{
102 if (numcurrvars >= maxcurrvars) 102 if (numcurrvars >= maxcurrvars)
103 if (currvars == NULL) 103 if (currvars == NULL)
@@ -152,7 +152,7 @@ char *luaI_getlocalname (TFunc *func, int local_number, int line)
152 if (lv->varname) /* register */ 152 if (lv->varname) /* register */
153 { 153 {
154 if (++count == local_number) 154 if (++count == local_number)
155 varname = lv->varname->ts.str; 155 varname = lv->varname->str;
156 } 156 }
157 else /* unregister */ 157 else /* unregister */
158 if (--count < local_number) 158 if (--count < local_number)
diff --git a/func.h b/func.h
index b4c275ad..8208f114 100644
--- a/func.h
+++ b/func.h
@@ -6,7 +6,7 @@
6 6
7typedef struct LocVar 7typedef struct LocVar
8{ 8{
9 TreeNode *varname; /* NULL signals end of scope */ 9 TaggedString *varname; /* NULL signals end of scope */
10 int line; 10 int line;
11} LocVar; 11} LocVar;
12 12
@@ -30,7 +30,7 @@ void luaI_insertfunction (TFunc *f);
30 30
31void luaI_initTFunc (TFunc *f); 31void luaI_initTFunc (TFunc *f);
32 32
33void luaI_registerlocalvar (TreeNode *varname, int line); 33void luaI_registerlocalvar (TaggedString *varname, int line);
34void luaI_unregisterlocalvar (int line); 34void luaI_unregisterlocalvar (int line);
35void luaI_closelocalvars (TFunc *func); 35void luaI_closelocalvars (TFunc *func);
36char *luaI_getlocalname (TFunc *func, int local_number, int line); 36char *luaI_getlocalname (TFunc *func, int local_number, int line);
diff --git a/hash.c b/hash.c
index 82047f59..c3db2588 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
3** hash manager for lua 3** hash manager for lua
4*/ 4*/
5 5
6char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp roberto $"; 6char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp $";
7 7
8#include <string.h> 8#include <string.h>
9 9
@@ -13,7 +13,6 @@ char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp roberto $";
13#include "table.h" 13#include "table.h"
14#include "lua.h" 14#include "lua.h"
15 15
16#define streq(s1,s2) (s1 == s2 || (*(s1) == *(s2) && strcmp(s1,s2)==0))
17 16
18#define nhash(t) ((t)->nhash) 17#define nhash(t) ((t)->nhash)
19#define nuse(t) ((t)->nuse) 18#define nuse(t) ((t)->nuse)
@@ -24,19 +23,18 @@ char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp roberto $";
24#define val(n) (&(n)->val) 23#define val(n) (&(n)->val)
25 24
26 25
27#define REHASH_LIMIT 0.70 /* avoid more than this % full */ 26#define REHASH_LIMIT 0.70 /* avoid more than this % full */
28 27
29 28
30static Hash *listhead = NULL; 29static Hash *listhead = NULL;
31 30
32 31
33
34/* hash dimensions values */ 32/* hash dimensions values */
35static Word dimensions[] = 33static Word dimensions[] =
36 {3, 5, 7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, 34 {3, 5, 7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421,
37 12853, 25717, 51437, 65521, 0}; /* 65521 == last prime < MAX_WORD */ 35 12853, 25717, 51437, 65521, 0}; /* 65521 == last prime < MAX_WORD */
38 36
39static Word redimension (Word nhash) 37Word luaI_redimension (Word nhash)
40{ 38{
41 Word i; 39 Word i;
42 for (i=0; dimensions[i]!=0; i++) 40 for (i=0; dimensions[i]!=0; i++)
@@ -58,17 +56,7 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */
58 case LUA_T_NUMBER: 56 case LUA_T_NUMBER:
59 return (((Word)nvalue(ref))%nhash(t)); 57 return (((Word)nvalue(ref))%nhash(t));
60 case LUA_T_STRING: 58 case LUA_T_STRING:
61 { 59 return (Word)((tsvalue(ref)->hash)%nhash(t)); /* make it a valid index */
62 unsigned long h = tsvalue(ref)->hash;
63 if (h == 0)
64 {
65 char *name = svalue(ref);
66 while (*name)
67 h = ((h<<5)-h)^(unsigned char)*(name++);
68 tsvalue(ref)->hash = h;
69 }
70 return (Word)h%nhash(t); /* make it a valid index */
71 }
72 case LUA_T_FUNCTION: 60 case LUA_T_FUNCTION:
73 return (((IntPoint)ref->value.tf)%nhash(t)); 61 return (((IntPoint)ref->value.tf)%nhash(t));
74 case LUA_T_CFUNCTION: 62 case LUA_T_CFUNCTION:
@@ -87,7 +75,7 @@ int lua_equalObj (Object *t1, Object *t2)
87 { 75 {
88 case LUA_T_NIL: return 1; 76 case LUA_T_NIL: return 1;
89 case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); 77 case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
90 case LUA_T_STRING: return streq(svalue(t1), svalue(t2)); 78 case LUA_T_STRING: return svalue(t1) == svalue(t2);
91 case LUA_T_ARRAY: return avalue(t1) == avalue(t2); 79 case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
92 case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; 80 case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
93 case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); 81 case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
@@ -126,7 +114,7 @@ static Node *hashnodecreate (Word nhash)
126static Hash *hashcreate (Word nhash) 114static Hash *hashcreate (Word nhash)
127{ 115{
128 Hash *t = new(Hash); 116 Hash *t = new(Hash);
129 nhash = redimension((Word)((float)nhash/REHASH_LIMIT)); 117 nhash = luaI_redimension((Word)((float)nhash/REHASH_LIMIT));
130 nodevector(t) = hashnodecreate(nhash); 118 nodevector(t) = hashnodecreate(nhash);
131 nhash(t) = nhash; 119 nhash(t) = nhash;
132 nuse(t) = 0; 120 nuse(t) = 0;
@@ -237,7 +225,7 @@ static void rehash (Hash *t)
237 Word i; 225 Word i;
238 Word nold = nhash(t); 226 Word nold = nhash(t);
239 Node *vold = nodevector(t); 227 Node *vold = nodevector(t);
240 nhash(t) = redimension(nhash(t)); 228 nhash(t) = luaI_redimension(nhash(t));
241 nodevector(t) = hashnodecreate(nhash(t)); 229 nodevector(t) = hashnodecreate(nhash(t));
242 for (i=0; i<nold; i++) 230 for (i=0; i<nold; i++)
243 { 231 {
diff --git a/hash.h b/hash.h
index 8ef6ddf1..86660721 100644
--- a/hash.h
+++ b/hash.h
@@ -2,13 +2,14 @@
2** hash.h 2** hash.h
3** hash manager for lua 3** hash manager for lua
4** Luiz Henrique de Figueiredo - 17 Aug 90 4** Luiz Henrique de Figueiredo - 17 Aug 90
5** $Id: hash.h,v 2.8 1995/01/12 14:19:04 roberto Exp roberto $ 5** $Id: hash.h,v 2.9 1996/02/07 14:13:17 roberto Exp roberto $
6*/ 6*/
7 7
8#ifndef hash_h 8#ifndef hash_h
9#define hash_h 9#define hash_h
10 10
11#include "types.h" 11#include "types.h"
12#include "opcode.h"
12 13
13typedef struct node 14typedef struct node
14{ 15{
@@ -27,6 +28,7 @@ typedef struct Hash
27 28
28 29
29int lua_equalObj (Object *t1, Object *t2); 30int lua_equalObj (Object *t1, Object *t2);
31Word luaI_redimension (Word nhash);
30Hash *lua_createarray (Word nhash); 32Hash *lua_createarray (Word nhash);
31void lua_hashmark (Hash *h); 33void lua_hashmark (Hash *h);
32Long lua_hashcollector (void); 34Long lua_hashcollector (void);
diff --git a/inout.c b/inout.c
index a3100a4f..8ba4b6bb 100644
--- a/inout.c
+++ b/inout.c
@@ -5,7 +5,7 @@
5** Also provides some predefined lua functions. 5** Also provides some predefined lua functions.
6*/ 6*/
7 7
8char *rcs_inout="$Id: inout.c,v 2.28 1996/01/26 16:52:47 roberto Exp roberto $"; 8char *rcs_inout="$Id: inout.c,v 2.29 1996/02/07 14:13:47 roberto Exp roberto $";
9 9
10#include <stdio.h> 10#include <stdio.h>
11#include <stdlib.h> 11#include <stdlib.h>
@@ -68,7 +68,7 @@ int lua_openfile (char *fn)
68 if (fp == NULL) 68 if (fp == NULL)
69 return 1; 69 return 1;
70 lua_linenumber = 1; 70 lua_linenumber = 1;
71 lua_parsedfile = lua_constcreate(fn)->ts.str; 71 lua_parsedfile = lua_constcreate(fn)->str;
72 return 0; 72 return 0;
73} 73}
74 74
@@ -92,7 +92,7 @@ void lua_openstring (char *s)
92 lua_setinput (stringinput); 92 lua_setinput (stringinput);
93 st = s; 93 st = s;
94 lua_linenumber = 1; 94 lua_linenumber = 1;
95 lua_parsedfile = lua_constcreate("(string)")->ts.str; 95 lua_parsedfile = lua_constcreate("(string)")->str;
96} 96}
97 97
98/* 98/*
diff --git a/lex.c b/lex.c
index f499d7a6..0940359c 100644
--- a/lex.c
+++ b/lex.c
@@ -1,4 +1,4 @@
1char *rcs_lex = "$Id: lex.c,v 2.23 1996/02/07 14:14:40 roberto Exp roberto $"; 1char *rcs_lex = "$Id: lex.c,v 2.24 1996/02/09 19:35:23 roberto Exp roberto $";
2 2
3 3
4#include <ctype.h> 4#include <ctype.h>
@@ -287,7 +287,7 @@ int luaY_lex (void)
287 *yytextLast = 0; 287 *yytextLast = 0;
288 res = findReserved(yytext); 288 res = findReserved(yytext);
289 if (res) return res; 289 if (res) return res;
290 luaY_lval.pNode = lua_constcreate(yytext); 290 luaY_lval.pTStr = luaI_createfixedstring(yytext);
291 return NAME; 291 return NAME;
292 } 292 }
293 293
diff --git a/lua.stx b/lua.stx
index b48b7e76..f16630d3 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,6 +1,6 @@
1%{ 1%{
2 2
3char *rcs_luastx = "$Id: lua.stx,v 3.28 1996/02/05 13:26:01 roberto Exp roberto $"; 3char *rcs_luastx = "$Id: lua.stx,v 3.29 1996/02/07 18:10:27 roberto Exp roberto $";
4 4
5#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h> 6#include <stdlib.h>
@@ -45,7 +45,7 @@ static Long varbuffer[MAXVAR]; /* variables in an assignment list;
45static int nvarbuffer=0; /* number of variables at a list */ 45static int nvarbuffer=0; /* number of variables at a list */
46 46
47#define MAXLOCALS 32 47#define MAXLOCALS 32
48static TreeNode *localvar[MAXLOCALS]; /* store local variable names */ 48static TaggedString *localvar[MAXLOCALS]; /* store local variable names */
49static int nlocalvar=0; /* number of local variables */ 49static int nlocalvar=0; /* number of local variables */
50 50
51#define MAXFIELDS FIELDS_PER_FLUSH*2 51#define MAXFIELDS FIELDS_PER_FLUSH*2
@@ -151,7 +151,7 @@ static void flush_list (int m, int n)
151 code_byte(n); 151 code_byte(n);
152} 152}
153 153
154static void store_localvar (TreeNode *name, int n) 154static void store_localvar (TaggedString *name, int n)
155{ 155{
156 if (nlocalvar+n < MAXLOCALS) 156 if (nlocalvar+n < MAXLOCALS)
157 localvar[nlocalvar+n] = name; 157 localvar[nlocalvar+n] = name;
@@ -161,7 +161,7 @@ static void store_localvar (TreeNode *name, int n)
161 luaI_registerlocalvar(name, lua_linenumber); 161 luaI_registerlocalvar(name, lua_linenumber);
162} 162}
163 163
164static void add_localvar (TreeNode *name) 164static void add_localvar (TaggedString *name)
165{ 165{
166 store_localvar(name, 0); 166 store_localvar(name, 0);
167 nlocalvar++; 167 nlocalvar++;
@@ -202,7 +202,7 @@ static void code_number (float f)
202/* 202/*
203** Search a local name and if find return its index. If do not find return -1 203** Search a local name and if find return its index. If do not find return -1
204*/ 204*/
205static int lua_localname (TreeNode *n) 205static int lua_localname (TaggedString *n)
206{ 206{
207 int i; 207 int i;
208 for (i=nlocalvar-1; i >= 0; i--) 208 for (i=nlocalvar-1; i >= 0; i--)
@@ -420,7 +420,7 @@ void lua_parse (TFunc *tf)
420 Word vWord; 420 Word vWord;
421 Long vLong; 421 Long vLong;
422 TFunc *pFunc; 422 TFunc *pFunc;
423 TreeNode *pNode; 423 TaggedString *pTStr;
424} 424}
425 425
426%start functionlist 426%start functionlist
@@ -433,7 +433,7 @@ void lua_parse (TFunc *tf)
433%token FUNCTION 433%token FUNCTION
434%token <vFloat> NUMBER 434%token <vFloat> NUMBER
435%token <vWord> STRING 435%token <vWord> STRING
436%token <pNode> NAME 436%token <pTStr> NAME
437%token <vInt> DEBUG 437%token <vInt> DEBUG
438 438
439%type <vLong> PrepJump 439%type <vLong> PrepJump
diff --git a/opcode.c b/opcode.c
index 5999d7a6..2f77cad4 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 3.55 1996/02/07 18:10:27 roberto Exp roberto $"; 6char *rcs_opcode="$Id: opcode.c,v 3.56 1996/02/08 17:03:20 roberto Exp roberto $";
7 7
8#include <setjmp.h> 8#include <setjmp.h>
9#include <stdlib.h> 9#include <stdlib.h>
@@ -381,7 +381,7 @@ static void getglobal (Word n)
381 if (tag(top-1) == LUA_T_NIL) 381 if (tag(top-1) == LUA_T_NIL)
382 { /* must call getglobal fallback */ 382 { /* must call getglobal fallback */
383 tag(top-1) = LUA_T_STRING; 383 tag(top-1) = LUA_T_STRING;
384 tsvalue(top-1) = &lua_table[n].varname->ts; 384 tsvalue(top-1) = lua_table[n].varname;
385 callFB(FB_GETGLOBAL); 385 callFB(FB_GETGLOBAL);
386 } 386 }
387} 387}
@@ -792,17 +792,6 @@ void lua_pushstring (char *s)
792} 792}
793 793
794/* 794/*
795** Push an object (tag=string) on stack and register it on the constant table.
796*/
797void lua_pushliteral (char *s)
798{
799 Word ct = luaI_findconstantbyname(s); /* this call may change lua_constant */
800 tsvalue(top) = lua_constant[ct];
801 tag(top) = LUA_T_STRING;
802 incr_top;
803}
804
805/*
806** Push an object (tag=cfunction) to stack. 795** Push an object (tag=cfunction) to stack.
807*/ 796*/
808void lua_pushcfunction (lua_CFunction fn) 797void lua_pushcfunction (lua_CFunction fn)
diff --git a/table.c b/table.c
index 587d582d..29d877c2 100644
--- a/table.c
+++ b/table.c
@@ -3,7 +3,7 @@
3** Module to control static tables 3** Module to control static tables
4*/ 4*/
5 5
6char *rcs_table="$Id: table.c,v 2.43 1996/01/26 14:04:32 roberto Exp roberto $"; 6char *rcs_table="$Id: table.c,v 2.44 1996/01/26 18:03:19 roberto Exp $";
7 7
8/*#include <string.h>*/ 8/*#include <string.h>*/
9 9
@@ -85,7 +85,7 @@ void lua_initconstant (void)
85** Given a name, search it at symbol table and return its index. If not 85** Given a name, search it at symbol table and return its index. If not
86** found, allocate it. 86** found, allocate it.
87*/ 87*/
88Word luaI_findsymbol (TreeNode *t) 88Word luaI_findsymbol (TaggedString *t)
89{ 89{
90 if (lua_table == NULL) 90 if (lua_table == NULL)
91 lua_initsymbol(); 91 lua_initsymbol();
@@ -111,7 +111,7 @@ Word luaI_findsymbol (TreeNode *t)
111 111
112Word luaI_findsymbolbyname (char *name) 112Word luaI_findsymbolbyname (char *name)
113{ 113{
114 return luaI_findsymbol(lua_constcreate(name)); 114 return luaI_findsymbol(luaI_createfixedstring(name));
115} 115}
116 116
117 117
@@ -119,7 +119,7 @@ Word luaI_findsymbolbyname (char *name)
119** Given a tree node, check it is has a correspondent constant index. If not, 119** Given a tree node, check it is has a correspondent constant index. If not,
120** allocate it. 120** allocate it.
121*/ 121*/
122Word luaI_findconstant (TreeNode *t) 122Word luaI_findconstant (TaggedString *t)
123{ 123{
124 if (lua_constant == NULL) 124 if (lua_constant == NULL)
125 lua_initconstant(); 125 lua_initconstant();
@@ -135,7 +135,7 @@ Word luaI_findconstant (TreeNode *t)
135 lua_constant = growvector(lua_constant, lua_maxconstant, TaggedString *); 135 lua_constant = growvector(lua_constant, lua_maxconstant, TaggedString *);
136 } 136 }
137 t->constindex = lua_nconstant; 137 t->constindex = lua_nconstant;
138 lua_constant[lua_nconstant] = &(t->ts); 138 lua_constant[lua_nconstant] = t;
139 lua_nconstant++; 139 lua_nconstant++;
140 } 140 }
141 return t->constindex; 141 return t->constindex;
@@ -144,7 +144,13 @@ Word luaI_findconstant (TreeNode *t)
144 144
145Word luaI_findconstantbyname (char *name) 145Word luaI_findconstantbyname (char *name)
146{ 146{
147 return luaI_findconstant(lua_constcreate(name)); 147 return luaI_findconstant(luaI_createfixedstring(name));
148}
149
150TaggedString *lua_constcreate(char *name)
151{
152 int i = luaI_findconstantbyname(name);
153 return lua_constant[i];
148} 154}
149 155
150 156
@@ -156,7 +162,7 @@ static char *lua_travsymbol (int (*fn)(Object *))
156 Word i; 162 Word i;
157 for (i=0; i<lua_ntable; i++) 163 for (i=0; i<lua_ntable; i++)
158 if (fn(&s_object(i))) 164 if (fn(&s_object(i)))
159 return lua_table[i].varname->ts.str; 165 return lua_table[i].varname->str;
160 return NULL; 166 return NULL;
161} 167}
162 168
@@ -165,7 +171,7 @@ static char *lua_travsymbol (int (*fn)(Object *))
165** Mark an object if it is a string or a unmarked array. 171** Mark an object if it is a string or a unmarked array.
166*/ 172*/
167int lua_markobject (Object *o) 173int lua_markobject (Object *o)
168{ 174{/* if already marked, does not change mark value */
169 if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) 175 if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked)
170 tsvalue(o)->marked = 1; 176 tsvalue(o)->marked = 1;
171 else if (tag(o) == LUA_T_ARRAY) 177 else if (tag(o) == LUA_T_ARRAY)
@@ -235,10 +241,10 @@ static void lua_nextvar (void)
235 } 241 }
236 else 242 else
237 { 243 {
238 TreeNode *t = lua_table[next].varname; 244 TaggedString *t = lua_table[next].varname;
239 Object name; 245 Object name;
240 tag(&name) = LUA_T_STRING; 246 tag(&name) = LUA_T_STRING;
241 tsvalue(&name) = &(t->ts); 247 tsvalue(&name) = t;
242 luaI_pushobject(&name); 248 luaI_pushobject(&name);
243 luaI_pushobject(&s_object(next)); 249 luaI_pushobject(&s_object(next));
244 } 250 }
diff --git a/table.h b/table.h
index 10c89a92..37085fec 100644
--- a/table.h
+++ b/table.h
@@ -1,7 +1,7 @@
1/* 1/*
2** Module to control static tables 2** Module to control static tables
3** TeCGraf - PUC-Rio 3** TeCGraf - PUC-Rio
4** $Id: table.h,v 2.15 1996/01/26 18:03:19 roberto Exp roberto $ 4** $Id: table.h,v 2.16 1996/02/06 16:18:21 roberto Exp roberto $
5*/ 5*/
6 6
7#ifndef table_h 7#ifndef table_h
@@ -13,7 +13,7 @@
13typedef struct 13typedef struct
14{ 14{
15 Object object; 15 Object object;
16 TreeNode *varname; 16 TaggedString *varname;
17} Symbol; 17} Symbol;
18 18
19 19
@@ -22,9 +22,10 @@ extern TaggedString **lua_constant;
22 22
23void lua_initconstant (void); 23void lua_initconstant (void);
24Word luaI_findsymbolbyname (char *name); 24Word luaI_findsymbolbyname (char *name);
25Word luaI_findsymbol (TreeNode *t); 25Word luaI_findsymbol (TaggedString *t);
26Word luaI_findconstant (TreeNode *t); 26Word luaI_findconstant (TaggedString *t);
27Word luaI_findconstantbyname (char *name); 27Word luaI_findconstantbyname (char *name);
28TaggedString *lua_constcreate (char *str);
28int lua_markobject (Object *o); 29int lua_markobject (Object *o);
29Long luaI_collectgarbage (void); 30Long luaI_collectgarbage (void);
30void lua_pack (void); 31void lua_pack (void);
diff --git a/tree.c b/tree.c
index f511436a..3b82dc9a 100644
--- a/tree.c
+++ b/tree.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp roberto $"; 6char *rcs_tree="$Id: tree.c,v 1.15 1996/01/26 18:03:19 roberto Exp $";
7 7
8 8
9#include <string.h> 9#include <string.h>
@@ -11,68 +11,98 @@ char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp roberto $";
11#include "mem.h" 11#include "mem.h"
12#include "lua.h" 12#include "lua.h"
13#include "tree.h" 13#include "tree.h"
14#include "hash.h"
14#include "table.h" 15#include "table.h"
15 16
16 17
17#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) 18#define lua_streq(a,b) (a[0] == b[0] && strcmp(a,b) == 0)
18 19
20#define NUM_HASHS 64
19 21
20typedef struct StringNode { 22typedef struct {
21 struct StringNode *next; 23 int size;
22 TaggedString ts; 24 int nuse; /* number of elements (including EMPTYs) */
23} StringNode; 25 TaggedString **hash;
26} stringtable;
24 27
25static StringNode *string_root = NULL; 28static stringtable string_root[NUM_HASHS];
26 29
27static TreeNode *constant_root = NULL; 30static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 0, {0}};
28 31
29/* 32static unsigned long hash (char *str)
30** Insert a new constant/variable at the tree.
31*/
32static TreeNode *tree_create (TreeNode **node, char *str)
33{ 33{
34 if (*node == NULL) 34 unsigned long h = 0;
35 { 35 while (*str)
36 *node = (TreeNode *) luaI_malloc(sizeof(TreeNode)+strlen(str)); 36 h = ((h<<5)-h)^(unsigned char)*(str++);
37 (*node)->left = (*node)->right = NULL; 37 return h;
38 strcpy((*node)->ts.str, str);
39 (*node)->ts.marked = 0;
40 (*node)->ts.hash = 0;
41 (*node)->varindex = (*node)->constindex = NOT_USED;
42 return *node;
43 }
44 else
45 {
46 int c = lua_strcmp(str, (*node)->ts.str);
47 if (c < 0)
48 return tree_create(&(*node)->left, str);
49 else if (c > 0)
50 return tree_create(&(*node)->right, str);
51 else
52 return *node;
53 }
54} 38}
55 39
56TaggedString *lua_createstring (char *str) 40static void grow (stringtable *tb)
57{ 41{
58 StringNode *newString; 42 int newsize = luaI_redimension(tb->size);
59 if (str == NULL) return NULL; 43 TaggedString **newhash = newvector(newsize, TaggedString *);
60 lua_pack(); 44 int i;
61 newString = (StringNode *)luaI_malloc(sizeof(StringNode)+strlen(str)); 45 for (i=0; i<newsize; i++)
62 newString->ts.marked = 0; 46 newhash[i] = NULL;
63 newString->ts.hash = 0; 47 if (tb->size > 0)
64 strcpy(newString->ts.str, str); 48 { /* rehash */
65 newString->next = string_root; 49 tb->nuse = 0;
66 string_root = newString; 50 for (i=0; i<tb->size; i++)
67 return &(newString->ts); 51 if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
52 {
53 int h = tb->hash[i]->hash%newsize;
54 while (newhash[h])
55 h = (h+1)%newsize;
56 newhash[h] = tb->hash[i];
57 tb->nuse++;
58 }
59 luaI_free(tb->hash);
60 }
61 tb->size = newsize;
62 tb->hash = newhash;
68} 63}
69 64
65static TaggedString *insert (char *str, stringtable *tb)
66{
67 TaggedString *ts;
68 unsigned long h = hash(str);
69 int i;
70 int j = -1;
71 if ((Long)tb->nuse*3 >= (Long)tb->size*2)
72 grow(tb);
73 i = h%tb->size;
74 while (tb->hash[i])
75 {
76 if (tb->hash[i] == &EMPTY)
77 j = i;
78 else if (lua_streq(str, tb->hash[i]->str))
79 return tb->hash[i];
80 i = (i+1)%tb->size;
81 }
82 /* not found */
83 if (j != -1) /* is there an EMPTY space? */
84 i = j;
85 else
86 tb->nuse++;
87 ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
88 strcpy(ts->str, str);
89 ts->marked = 0;
90 ts->hash = h;
91 ts->varindex = ts->constindex = NOT_USED;
92 return ts;
93}
70 94
71TreeNode *lua_constcreate (char *str) 95TaggedString *lua_createstring (char *str)
72{ 96{
73 return tree_create(&constant_root, str); 97 return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
74} 98}
75 99
100TaggedString *luaI_createfixedstring (char *str)
101{
102 TaggedString *ts = lua_createstring(str);
103 ts->marked = 2; /* to avoid GC */
104 return ts;
105}
76 106
77/* 107/*
78** Garbage collection function. 108** Garbage collection function.
@@ -80,26 +110,28 @@ TreeNode *lua_constcreate (char *str)
80*/ 110*/
81Long lua_strcollector (void) 111Long lua_strcollector (void)
82{ 112{
83 StringNode *curr = string_root, *prev = NULL;
84 Long counter = 0; 113 Long counter = 0;
85 while (curr) 114 int i;
115 for (i=0; i<NUM_HASHS; i++)
86 { 116 {
87 StringNode *next = curr->next; 117 stringtable *tb = &string_root[i];
88 if (!curr->ts.marked) 118 int j;
89 { 119 for (j=0; j<tb->size; j++)
90 if (prev == NULL) string_root = next;
91 else prev->next = next;
92 luaI_free(curr);
93 ++counter;
94 }
95 else
96 { 120 {
97 curr->ts.marked = 0; 121 TaggedString *t = tb->hash[j];
98 prev = curr; 122 if (t != NULL && t != &EMPTY && t->marked != 2)
123 {
124 if (t->marked)
125 t->marked = 0;
126 else
127 {
128 luaI_free(t);
129 tb->hash[j] = &EMPTY;
130 counter++;
131 }
132 }
99 } 133 }
100 curr = next;
101 } 134 }
102 return counter; 135 return counter;
103} 136}
104 137
105
diff --git a/tree.h b/tree.h
index bf6eb27d..eb347ed4 100644
--- a/tree.h
+++ b/tree.h
@@ -1,7 +1,7 @@
1/* 1/*
2** tree.h 2** tree.h
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4** $Id: tree.h,v 1.10 1995/10/17 11:53:53 roberto Exp roberto $ 4** $Id: tree.h,v 1.11 1996/01/26 18:03:19 roberto Exp roberto $
5*/ 5*/
6 6
7#ifndef tree_h 7#ifndef tree_h
@@ -14,23 +14,16 @@
14 14
15typedef struct TaggedString 15typedef struct TaggedString
16{ 16{
17 unsigned short varindex; /* != NOT_USED if this is a symbol */
18 unsigned short constindex; /* != NOT_USED if this is a constant */
17 unsigned long hash; /* 0 if not initialized */ 19 unsigned long hash; /* 0 if not initialized */
18 char marked; /* for garbage collection */ 20 char marked; /* for garbage collection; 2 means "never collect" */
19 char str[1]; /* \0 byte already reserved */ 21 char str[1]; /* \0 byte already reserved */
20} TaggedString; 22} TaggedString;
21 23
22typedef struct TreeNode
23{
24 struct TreeNode *right;
25 struct TreeNode *left;
26 unsigned short varindex; /* != NOT_USED if this is a symbol */
27 unsigned short constindex; /* != NOT_USED if this is a constant */
28 TaggedString ts;
29} TreeNode;
30
31 24
32TaggedString *lua_createstring (char *str); 25TaggedString *lua_createstring (char *str);
33TreeNode *lua_constcreate (char *str); 26TaggedString *luaI_createfixedstring (char *str);
34Long lua_strcollector (void); 27Long lua_strcollector (void);
35 28
36#endif 29#endif