diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-02-12 15:32:40 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-02-12 15:32:40 -0300 |
commit | 41259bff31dbb904edfb8070006ccb15577f8f04 (patch) | |
tree | 664bf9cbe6394e9074435ecf2bd710712b4537c3 | |
parent | afaa98a666acd5f596b50f56bb288815838c096e (diff) | |
download | lua-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.c | 4 | ||||
-rw-r--r-- | func.h | 4 | ||||
-rw-r--r-- | hash.c | 26 | ||||
-rw-r--r-- | hash.h | 4 | ||||
-rw-r--r-- | inout.c | 6 | ||||
-rw-r--r-- | lex.c | 4 | ||||
-rw-r--r-- | lua.stx | 14 | ||||
-rw-r--r-- | opcode.c | 15 | ||||
-rw-r--r-- | table.c | 26 | ||||
-rw-r--r-- | table.h | 9 | ||||
-rw-r--r-- | tree.c | 152 | ||||
-rw-r--r-- | tree.h | 17 |
12 files changed, 146 insertions, 135 deletions
@@ -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 | */ |
100 | void luaI_registerlocalvar (TreeNode *varname, int line) | 100 | void 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) |
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | typedef struct LocVar | 7 | typedef 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 | ||
31 | void luaI_initTFunc (TFunc *f); | 31 | void luaI_initTFunc (TFunc *f); |
32 | 32 | ||
33 | void luaI_registerlocalvar (TreeNode *varname, int line); | 33 | void luaI_registerlocalvar (TaggedString *varname, int line); |
34 | void luaI_unregisterlocalvar (int line); | 34 | void luaI_unregisterlocalvar (int line); |
35 | void luaI_closelocalvars (TFunc *func); | 35 | void luaI_closelocalvars (TFunc *func); |
36 | char *luaI_getlocalname (TFunc *func, int local_number, int line); | 36 | char *luaI_getlocalname (TFunc *func, int local_number, int line); |
@@ -3,7 +3,7 @@ | |||
3 | ** hash manager for lua | 3 | ** hash manager for lua |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp roberto $"; | 6 | char *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 | ||
30 | static Hash *listhead = NULL; | 29 | static Hash *listhead = NULL; |
31 | 30 | ||
32 | 31 | ||
33 | |||
34 | /* hash dimensions values */ | 32 | /* hash dimensions values */ |
35 | static Word dimensions[] = | 33 | static 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 | ||
39 | static Word redimension (Word nhash) | 37 | Word 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) | |||
126 | static Hash *hashcreate (Word nhash) | 114 | static 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 | { |
@@ -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 | ||
13 | typedef struct node | 14 | typedef struct node |
14 | { | 15 | { |
@@ -27,6 +28,7 @@ typedef struct Hash | |||
27 | 28 | ||
28 | 29 | ||
29 | int lua_equalObj (Object *t1, Object *t2); | 30 | int lua_equalObj (Object *t1, Object *t2); |
31 | Word luaI_redimension (Word nhash); | ||
30 | Hash *lua_createarray (Word nhash); | 32 | Hash *lua_createarray (Word nhash); |
31 | void lua_hashmark (Hash *h); | 33 | void lua_hashmark (Hash *h); |
32 | Long lua_hashcollector (void); | 34 | Long lua_hashcollector (void); |
@@ -5,7 +5,7 @@ | |||
5 | ** Also provides some predefined lua functions. | 5 | ** Also provides some predefined lua functions. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | char *rcs_inout="$Id: inout.c,v 2.28 1996/01/26 16:52:47 roberto Exp roberto $"; | 8 | char *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 | /* |
@@ -1,4 +1,4 @@ | |||
1 | char *rcs_lex = "$Id: lex.c,v 2.23 1996/02/07 14:14:40 roberto Exp roberto $"; | 1 | char *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 | ||
@@ -1,6 +1,6 @@ | |||
1 | %{ | 1 | %{ |
2 | 2 | ||
3 | char *rcs_luastx = "$Id: lua.stx,v 3.28 1996/02/05 13:26:01 roberto Exp roberto $"; | 3 | char *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; | |||
45 | static int nvarbuffer=0; /* number of variables at a list */ | 45 | static int nvarbuffer=0; /* number of variables at a list */ |
46 | 46 | ||
47 | #define MAXLOCALS 32 | 47 | #define MAXLOCALS 32 |
48 | static TreeNode *localvar[MAXLOCALS]; /* store local variable names */ | 48 | static TaggedString *localvar[MAXLOCALS]; /* store local variable names */ |
49 | static int nlocalvar=0; /* number of local variables */ | 49 | static 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 | ||
154 | static void store_localvar (TreeNode *name, int n) | 154 | static 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 | ||
164 | static void add_localvar (TreeNode *name) | 164 | static 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 | */ |
205 | static int lua_localname (TreeNode *n) | 205 | static 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 |
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 3.55 1996/02/07 18:10:27 roberto Exp roberto $"; | 6 | char *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 | */ | ||
797 | void 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 | */ |
808 | void lua_pushcfunction (lua_CFunction fn) | 797 | void lua_pushcfunction (lua_CFunction fn) |
@@ -3,7 +3,7 @@ | |||
3 | ** Module to control static tables | 3 | ** Module to control static tables |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_table="$Id: table.c,v 2.43 1996/01/26 14:04:32 roberto Exp roberto $"; | 6 | char *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 | */ |
88 | Word luaI_findsymbol (TreeNode *t) | 88 | Word 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 | ||
112 | Word luaI_findsymbolbyname (char *name) | 112 | Word 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 | */ |
122 | Word luaI_findconstant (TreeNode *t) | 122 | Word 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 | ||
145 | Word luaI_findconstantbyname (char *name) | 145 | Word luaI_findconstantbyname (char *name) |
146 | { | 146 | { |
147 | return luaI_findconstant(lua_constcreate(name)); | 147 | return luaI_findconstant(luaI_createfixedstring(name)); |
148 | } | ||
149 | |||
150 | TaggedString *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 | */ |
167 | int lua_markobject (Object *o) | 173 | int 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 | } |
@@ -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 @@ | |||
13 | typedef struct | 13 | typedef 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 | ||
23 | void lua_initconstant (void); | 23 | void lua_initconstant (void); |
24 | Word luaI_findsymbolbyname (char *name); | 24 | Word luaI_findsymbolbyname (char *name); |
25 | Word luaI_findsymbol (TreeNode *t); | 25 | Word luaI_findsymbol (TaggedString *t); |
26 | Word luaI_findconstant (TreeNode *t); | 26 | Word luaI_findconstant (TaggedString *t); |
27 | Word luaI_findconstantbyname (char *name); | 27 | Word luaI_findconstantbyname (char *name); |
28 | TaggedString *lua_constcreate (char *str); | ||
28 | int lua_markobject (Object *o); | 29 | int lua_markobject (Object *o); |
29 | Long luaI_collectgarbage (void); | 30 | Long luaI_collectgarbage (void); |
30 | void lua_pack (void); | 31 | void lua_pack (void); |
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp roberto $"; | 6 | char *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 | ||
20 | typedef struct StringNode { | 22 | typedef 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 | ||
25 | static StringNode *string_root = NULL; | 28 | static stringtable string_root[NUM_HASHS]; |
26 | 29 | ||
27 | static TreeNode *constant_root = NULL; | 30 | static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 0, {0}}; |
28 | 31 | ||
29 | /* | 32 | static unsigned long hash (char *str) |
30 | ** Insert a new constant/variable at the tree. | ||
31 | */ | ||
32 | static 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 | ||
56 | TaggedString *lua_createstring (char *str) | 40 | static 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 | ||
65 | static 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 | ||
71 | TreeNode *lua_constcreate (char *str) | 95 | TaggedString *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 | ||
100 | TaggedString *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 | */ |
81 | Long lua_strcollector (void) | 111 | Long 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 | |||
@@ -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 | ||
15 | typedef struct TaggedString | 15 | typedef 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 | ||
22 | typedef 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 | ||
32 | TaggedString *lua_createstring (char *str); | 25 | TaggedString *lua_createstring (char *str); |
33 | TreeNode *lua_constcreate (char *str); | 26 | TaggedString *luaI_createfixedstring (char *str); |
34 | Long lua_strcollector (void); | 27 | Long lua_strcollector (void); |
35 | 28 | ||
36 | #endif | 29 | #endif |