aboutsummaryrefslogtreecommitdiff
path: root/lstring.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstring.c')
-rw-r--r--lstring.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/lstring.c b/lstring.c
index a6e0ca4e..f18d2ff2 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 roberto Exp roberto $ 2** $Id: lstring.c,v 1.11 1998/01/28 16:50:33 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,7 +21,8 @@
21 21
22 22
23 23
24static TaggedString EMPTY = {{NULL, 2}, 0, 0L, {{LUA_T_NIL, {NULL}}}, {0}}; 24static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
25 {{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
25 26
26 27
27void luaS_init (void) 28void luaS_init (void)
@@ -36,20 +37,14 @@ void luaS_init (void)
36} 37}
37 38
38 39
39static unsigned long hash (char *s, int tag) 40static unsigned long hash_s (char *s, long l)
40{ 41{
41 unsigned long h; 42 unsigned long h = 0;
42 if (tag != LUA_T_STRING) 43 while (l--)
43 h = (unsigned long)s; 44 h = ((h<<5)-h)^(unsigned char)*(s++);
44 else {
45 h = 0;
46 while (*s)
47 h = ((h<<5)-h)^(unsigned char)*(s++);
48 }
49 return h; 45 return h;
50} 46}
51 47
52
53static int newsize (stringtable *tb) 48static int newsize (stringtable *tb)
54{ 49{
55 int size = tb->size; 50 int size = tb->size;
@@ -91,34 +86,67 @@ static void grow (stringtable *tb)
91} 86}
92 87
93 88
94static TaggedString *newone (char *buff, int tag, unsigned long h) 89static TaggedString *newone_s (char *str, long l, unsigned long h)
95{ 90{
96 TaggedString *ts; 91 TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
97 if (tag == LUA_T_STRING) { 92 memcpy(ts->str, str, l);
98 long l = strlen(buff); 93 ts->str[l] = 0; /* ending 0 */
99 ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); 94 ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */
100 strcpy(ts->str, buff); 95 ts->u.s.len = l;
101 ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */ 96 ts->constindex = 0;
102 ts->constindex = 0; 97 L->nblocks += gcsizestring(l);
103 L->nblocks += gcsizestring(l);
104 }
105 else {
106 ts = luaM_new(TaggedString);
107 ts->u.d.v = buff;
108 ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
109 ts->constindex = -1; /* tag -> this is a userdata */
110 L->nblocks++;
111 }
112 ts->head.marked = 0; 98 ts->head.marked = 0;
113 ts->head.next = (GCnode *)ts; /* signal it is in no list */ 99 ts->head.next = (GCnode *)ts; /* signal it is in no list */
114 ts->hash = h; 100 ts->hash = h;
115 return ts; 101 return ts;
116} 102}
117 103
118static TaggedString *insert (char *buff, int tag, stringtable *tb) 104static TaggedString *newone_u (char *buff, int tag, unsigned long h)
105{
106 TaggedString *ts = luaM_new(TaggedString);
107 ts->u.d.v = buff;
108 ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
109 ts->constindex = -1; /* tag -> this is a userdata */
110 L->nblocks++;
111 ts->head.marked = 0;
112 ts->head.next = (GCnode *)ts; /* signal it is in no list */
113 ts->hash = h;
114 return ts;
115}
116
117static TaggedString *insert_s (char *str, long l, stringtable *tb)
118{
119 TaggedString *ts;
120 unsigned long h = hash_s(str, l);
121 int size = tb->size;
122 int i;
123 int j = -1;
124 if ((long)tb->nuse*3 >= (long)size*2) {
125 grow(tb);
126 size = tb->size;
127 }
128 for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
129 if (ts == &EMPTY)
130 j = i;
131 else if (ts->constindex >= 0 &&
132 ts->u.s.len == l &&
133 (memcmp(str, ts->str, l) == 0))
134 return ts;
135 if (++i == size) i=0;
136 }
137 /* not found */
138 if (j != -1) /* is there an EMPTY space? */
139 i = j;
140 else
141 tb->nuse++;
142 ts = tb->hash[i] = newone_s(str, l, h);
143 return ts;
144}
145
146static TaggedString *insert_u (void *buff, int tag, stringtable *tb)
119{ 147{
120 TaggedString *ts; 148 TaggedString *ts;
121 unsigned long h = hash(buff, tag); 149 unsigned long h = (unsigned long)buff;
122 int size = tb->size; 150 int size = tb->size;
123 int i; 151 int i;
124 int j = -1; 152 int j = -1;
@@ -129,9 +157,9 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
129 for (i = h%size; (ts = tb->hash[i]) != NULL; ) { 157 for (i = h%size; (ts = tb->hash[i]) != NULL; ) {
130 if (ts == &EMPTY) 158 if (ts == &EMPTY)
131 j = i; 159 j = i;
132 else if ((ts->constindex >= 0) ? /* is a string? */ 160 else if (ts->constindex < 0 && /* is a udata? */
133 (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) : 161 (tag == ts->u.d.tag || tag == LUA_ANYTAG) &&
134 ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)) 162 buff == ts->u.d.v)
135 return ts; 163 return ts;
136 if (++i == size) i=0; 164 if (++i == size) i=0;
137 } 165 }
@@ -140,18 +168,24 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
140 i = j; 168 i = j;
141 else 169 else
142 tb->nuse++; 170 tb->nuse++;
143 ts = tb->hash[i] = newone(buff, tag, h); 171 ts = tb->hash[i] = newone_u(buff, tag, h);
144 return ts; 172 return ts;
145} 173}
146 174
147TaggedString *luaS_createudata (void *udata, int tag) 175TaggedString *luaS_createudata (void *udata, int tag)
148{ 176{
149 return insert(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); 177 return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]);
178}
179
180TaggedString *luaS_newlstr (char *str, long l)
181{
182 int i = (l==0)?0:(unsigned char)str[0];
183 return insert_s(str, l, &L->string_root[i%NUM_HASHS]);
150} 184}
151 185
152TaggedString *luaS_new (char *str) 186TaggedString *luaS_new (char *str)
153{ 187{
154 return insert(str, LUA_T_STRING, &L->string_root[(unsigned)str[0]%NUM_HASHS]); 188 return luaS_newlstr(str, strlen(str));
155} 189}
156 190
157TaggedString *luaS_newfixedstring (char *str) 191TaggedString *luaS_newfixedstring (char *str)
@@ -167,7 +201,7 @@ void luaS_free (TaggedString *l)
167{ 201{
168 while (l) { 202 while (l) {
169 TaggedString *next = (TaggedString *)l->head.next; 203 TaggedString *next = (TaggedString *)l->head.next;
170 L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str)); 204 L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
171 luaM_free(l); 205 luaM_free(l);
172 l = next; 206 l = next;
173 } 207 }
@@ -253,7 +287,7 @@ void luaS_freeall (void)
253 287
254void luaS_rawsetglobal (TaggedString *ts, TObject *newval) 288void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
255{ 289{
256 ts->u.globalval = *newval; 290 ts->u.s.globalval = *newval;
257 if (ts->head.next == (GCnode *)ts) { /* is not in list? */ 291 if (ts->head.next == (GCnode *)ts) { /* is not in list? */
258 ts->head.next = L->rootglobal.next; 292 ts->head.next = L->rootglobal.next;
259 L->rootglobal.next = (GCnode *)ts; 293 L->rootglobal.next = (GCnode *)ts;
@@ -265,7 +299,7 @@ char *luaS_travsymbol (int (*fn)(TObject *))
265{ 299{
266 TaggedString *g; 300 TaggedString *g;
267 for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) 301 for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
268 if (fn(&g->u.globalval)) 302 if (fn(&g->u.s.globalval))
269 return g->str; 303 return g->str;
270 return NULL; 304 return NULL;
271} 305}
@@ -274,6 +308,6 @@ char *luaS_travsymbol (int (*fn)(TObject *))
274int luaS_globaldefined (char *name) 308int luaS_globaldefined (char *name)
275{ 309{
276 TaggedString *ts = luaS_new(name); 310 TaggedString *ts = luaS_new(name);
277 return ts->u.globalval.ttype != LUA_T_NIL; 311 return ts->u.s.globalval.ttype != LUA_T_NIL;
278} 312}
279 313