diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-10 13:33:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-10 13:33:20 -0300 |
commit | 330e51bed3159aa83dcc9cc559c22e7d84d37604 (patch) | |
tree | 8d11540f124fe432e12296c85091947161fb3886 | |
parent | 44b71ca81696dbec561c0172d1b81533f1c2153e (diff) | |
download | lua-330e51bed3159aa83dcc9cc559c22e7d84d37604.tar.gz lua-330e51bed3159aa83dcc9cc559c22e7d84d37604.tar.bz2 lua-330e51bed3159aa83dcc9cc559c22e7d84d37604.zip |
string hash uses one single hash table
-rw-r--r-- | lgc.c | 55 | ||||
-rw-r--r-- | lobject.h | 4 | ||||
-rw-r--r-- | lparser.c | 6 | ||||
-rw-r--r-- | lstate.h | 10 | ||||
-rw-r--r-- | lstring.c | 111 | ||||
-rw-r--r-- | lstring.h | 12 | ||||
-rw-r--r-- | ltests.c | 23 |
7 files changed, 90 insertions, 131 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.47 2000/04/14 18:12:35 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.48 2000/05/08 19:32:53 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -166,36 +166,41 @@ static void collecttable (lua_State *L) { | |||
166 | ** with limit=1, that means all unmarked elements; | 166 | ** with limit=1, that means all unmarked elements; |
167 | ** with limit=MAX_INT, that means all elements. | 167 | ** with limit=MAX_INT, that means all elements. |
168 | */ | 168 | */ |
169 | static void collectstring (lua_State *L, int limit) { | 169 | static void collectstringtab (lua_State *L, int limit, stringtable *tb) { |
170 | TObject o; /* to call userdata `gc' tag method */ | ||
171 | int i; | 170 | int i; |
171 | TObject o; /* to call userdata `gc' tag method */ | ||
172 | ttype(&o) = TAG_USERDATA; | 172 | ttype(&o) = TAG_USERDATA; |
173 | for (i=0; i<NUM_HASHS; i++) { /* for each hash table */ | 173 | for (i=0; i<tb->size; i++) { /* for each list */ |
174 | stringtable *tb = &L->string_root[i]; | 174 | TString **p = &tb->hash[i]; |
175 | int j; | 175 | TString *next; |
176 | for (j=0; j<tb->size; j++) { /* for each list */ | 176 | while ((next = *p) != NULL) { |
177 | TString **p = &tb->hash[j]; | 177 | if (next->marked >= limit) { |
178 | TString *next; | 178 | if (next->marked < FIXMARK) /* does not change FIXMARKs */ |
179 | while ((next = *p) != NULL) { | 179 | next->marked = 0; |
180 | if (next->marked >= limit) { | 180 | p = &next->nexthash; |
181 | if (next->marked < FIXMARK) /* does not change FIXMARKs */ | 181 | } |
182 | next->marked = 0; | 182 | else { /* collect */ |
183 | p = &next->nexthash; | 183 | if (tb == &L->strt) /* is string? */ |
184 | } | 184 | L->nblocks -= gcsizestring(L, next->u.s.len); |
185 | else { /* collect */ | 185 | else { |
186 | if (next->constindex == -1) { /* is userdata? */ | 186 | tsvalue(&o) = next; |
187 | tsvalue(&o) = next; | 187 | luaD_gcTM(L, &o); |
188 | luaD_gcTM(L, &o); | 188 | L->nblocks -= gcsizeudata; |
189 | } | ||
190 | *p = next->nexthash; | ||
191 | luaS_free(L, next); | ||
192 | tb->nuse--; | ||
193 | } | 189 | } |
190 | *p = next->nexthash; | ||
191 | tb->nuse--; | ||
192 | luaM_free(L, next); | ||
194 | } | 193 | } |
195 | } | 194 | } |
196 | if ((tb->nuse+1)*6 < tb->size) | ||
197 | luaS_resize(L, tb, tb->size/2); /* table is too big */ | ||
198 | } | 195 | } |
196 | if (tb->nuse < (tb->size/4) && tb->size > 10) | ||
197 | luaS_resize(L, tb, tb->size/2); /* table is too big */ | ||
198 | } | ||
199 | |||
200 | |||
201 | static void collectstring (lua_State *L, int limit) { | ||
202 | collectstringtab(L, limit, &L->strt); | ||
203 | collectstringtab(L, limit, &L->udt); | ||
199 | } | 204 | } |
200 | 205 | ||
201 | 206 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.62 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.63 2000/05/08 19:37:10 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -93,6 +93,7 @@ typedef struct TString { | |||
93 | struct { /* for strings */ | 93 | struct { /* for strings */ |
94 | unsigned long hash; | 94 | unsigned long hash; |
95 | long len; | 95 | long len; |
96 | int constindex; /* hint to reuse constants */ | ||
96 | } s; | 97 | } s; |
97 | struct { /* for userdata */ | 98 | struct { /* for userdata */ |
98 | int tag; | 99 | int tag; |
@@ -100,7 +101,6 @@ typedef struct TString { | |||
100 | } d; | 101 | } d; |
101 | } u; | 102 | } u; |
102 | struct TString *nexthash; /* chain for hash table */ | 103 | struct TString *nexthash; /* chain for hash table */ |
103 | int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ | ||
104 | unsigned char marked; | 104 | unsigned char marked; |
105 | char str[1]; /* variable length string!! must be the last field! */ | 105 | char str[1]; /* variable length string!! must be the last field! */ |
106 | } TString; | 106 | } TString; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.83 2000/04/27 17:39:56 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.84 2000/05/08 18:46:34 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -139,13 +139,13 @@ static void check_END (LexState *ls, int who, int where) { | |||
139 | 139 | ||
140 | static int string_constant (FuncState *fs, TString *s) { | 140 | static int string_constant (FuncState *fs, TString *s) { |
141 | Proto *f = fs->f; | 141 | Proto *f = fs->f; |
142 | int c = s->constindex; | 142 | int c = s->u.s.constindex; |
143 | if (c >= f->nkstr || f->kstr[c] != s) { | 143 | if (c >= f->nkstr || f->kstr[c] != s) { |
144 | luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, | 144 | luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, |
145 | constantEM, MAXARG_U); | 145 | constantEM, MAXARG_U); |
146 | c = f->nkstr++; | 146 | c = f->nkstr++; |
147 | f->kstr[c] = s; | 147 | f->kstr[c] = s; |
148 | s->constindex = c; /* hint for next time */ | 148 | s->u.s.constindex = c; /* hint for next time */ |
149 | } | 149 | } |
150 | return c; | 150 | return c; |
151 | } | 151 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.31 2000/03/30 17:19:48 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.32 2000/05/08 19:32:53 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -42,7 +42,7 @@ struct C_Lua_Stack { | |||
42 | 42 | ||
43 | typedef struct stringtable { | 43 | typedef struct stringtable { |
44 | int size; | 44 | int size; |
45 | int nuse; /* number of elements */ | 45 | long nuse; /* number of elements */ |
46 | TString **hash; | 46 | TString **hash; |
47 | } stringtable; | 47 | } stringtable; |
48 | 48 | ||
@@ -66,7 +66,8 @@ struct lua_State { | |||
66 | Proto *rootproto; /* list of all prototypes */ | 66 | Proto *rootproto; /* list of all prototypes */ |
67 | Closure *rootcl; /* list of all closures */ | 67 | Closure *rootcl; /* list of all closures */ |
68 | Hash *roottable; /* list of all tables */ | 68 | Hash *roottable; /* list of all tables */ |
69 | stringtable *string_root; /* array of hash tables for strings and udata */ | 69 | stringtable strt; /* hash table for strings */ |
70 | stringtable udt; /* hash table for udata */ | ||
70 | Hash *gt; /* table for globals */ | 71 | Hash *gt; /* table for globals */ |
71 | struct IM *IMtable; /* table for tag methods */ | 72 | struct IM *IMtable; /* table for tag methods */ |
72 | int last_tag; /* last used tag in IMtable */ | 73 | int last_tag; /* last used tag in IMtable */ |
@@ -82,8 +83,5 @@ struct lua_State { | |||
82 | }; | 83 | }; |
83 | 84 | ||
84 | 85 | ||
85 | |||
86 | |||
87 | |||
88 | #endif | 86 | #endif |
89 | 87 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.34 2000/03/10 18:37:44 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.35 2000/05/08 19:32:53 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 | */ |
@@ -17,30 +17,20 @@ | |||
17 | 17 | ||
18 | 18 | ||
19 | 19 | ||
20 | #define gcsizestring(L, l) numblocks(L, 0, sizeof(TString)+l) | ||
21 | #define gcsizeudata gcsizestring(L, 0) | ||
22 | |||
23 | |||
24 | |||
25 | void luaS_init (lua_State *L) { | 20 | void luaS_init (lua_State *L) { |
26 | int i; | 21 | L->strt.size = L->udt.size = 1; |
27 | L->string_root = luaM_newvector(L, NUM_HASHS, stringtable); | 22 | L->strt.nuse = L->udt.nuse = 0; |
28 | for (i=0; i<NUM_HASHS; i++) { | 23 | L->strt.hash = luaM_newvector(L, 1, TString *); |
29 | L->string_root[i].size = 1; | 24 | L->udt.hash = luaM_newvector(L, 1, TString *); |
30 | L->string_root[i].nuse = 0; | 25 | L->strt.hash[0] = L->udt.hash[0] = NULL; |
31 | L->string_root[i].hash = luaM_newvector(L, 1, TString *);; | ||
32 | L->string_root[i].hash[0] = NULL; | ||
33 | } | ||
34 | } | 26 | } |
35 | 27 | ||
36 | 28 | ||
37 | void luaS_freeall (lua_State *L) { | 29 | void luaS_freeall (lua_State *L) { |
38 | int i; | 30 | LUA_ASSERT(L, L->strt.nuse==0, "non-empty string table"); |
39 | for (i=0; i<NUM_HASHS; i++) { | 31 | luaM_free(L, L->strt.hash); |
40 | LUA_ASSERT(L, L->string_root[i].nuse==0, "non-empty string table"); | 32 | LUA_ASSERT(L, L->udt.nuse==0, "non-empty udata table"); |
41 | luaM_free(L, L->string_root[i].hash); | 33 | luaM_free(L, L->udt.hash); |
42 | } | ||
43 | luaM_free(L, L->string_root); | ||
44 | } | 34 | } |
45 | 35 | ||
46 | 36 | ||
@@ -62,8 +52,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
62 | TString *p = tb->hash[i]; | 52 | TString *p = tb->hash[i]; |
63 | while (p) { /* for each node in the list */ | 53 | while (p) { /* for each node in the list */ |
64 | TString *next = p->nexthash; /* save next */ | 54 | TString *next = p->nexthash; /* save next */ |
65 | unsigned long h = (p->constindex == -1) ? IntPoint(p->u.d.value) : | 55 | unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value); |
66 | p->u.s.hash; | ||
67 | int h1 = h&(newsize-1); /* new position */ | 56 | int h1 = h&(newsize-1); /* new position */ |
68 | LUA_ASSERT(L, h%newsize == (h&(newsize-1)), | 57 | LUA_ASSERT(L, h%newsize == (h&(newsize-1)), |
69 | "a&(x-1) == a%x, for x power of 2"); | 58 | "a&(x-1) == a%x, for x power of 2"); |
@@ -78,79 +67,55 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
78 | } | 67 | } |
79 | 68 | ||
80 | 69 | ||
81 | static TString *newone (lua_State *L, long l) { | ||
82 | TString *ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char)); | ||
83 | ts->marked = 0; | ||
84 | ts->nexthash = NULL; | ||
85 | return ts; | ||
86 | } | ||
87 | |||
88 | |||
89 | static TString *newone_s (lua_State *L, const char *str, | ||
90 | long l, unsigned long h) { | ||
91 | TString *ts = newone(L, l); | ||
92 | memcpy(ts->str, str, l); | ||
93 | ts->str[l] = 0; /* ending 0 */ | ||
94 | ts->u.s.len = l; | ||
95 | ts->u.s.hash = h; | ||
96 | ts->constindex = 0; | ||
97 | L->nblocks += gcsizestring(L, l); | ||
98 | return ts; | ||
99 | } | ||
100 | |||
101 | |||
102 | static TString *newone_u (lua_State *L, void *buff, int tag) { | ||
103 | TString *ts = newone(L, 0); | ||
104 | ts->u.d.value = buff; | ||
105 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; | ||
106 | ts->constindex = -1; /* tag -> this is a userdata */ | ||
107 | L->nblocks += gcsizeudata; | ||
108 | return ts; | ||
109 | } | ||
110 | |||
111 | |||
112 | static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { | 70 | static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { |
113 | ts->nexthash = tb->hash[h]; /* chain new entry */ | 71 | ts->nexthash = tb->hash[h]; /* chain new entry */ |
114 | tb->hash[h] = ts; | 72 | tb->hash[h] = ts; |
115 | tb->nuse++; | 73 | tb->nuse++; |
116 | if (tb->nuse > tb->size) /* too crowded? */ | 74 | if (tb->nuse > tb->size && tb->size < MAX_INT/2) /* too crowded? */ |
117 | luaS_resize(L, tb, tb->size*2); | 75 | luaS_resize(L, tb, tb->size*2); |
118 | } | 76 | } |
119 | 77 | ||
120 | 78 | ||
79 | |||
121 | TString *luaS_newlstr (lua_State *L, const char *str, long l) { | 80 | TString *luaS_newlstr (lua_State *L, const char *str, long l) { |
122 | unsigned long h = hash_s(str, l); | 81 | unsigned long h = hash_s(str, l); |
123 | stringtable *tb = &L->string_root[(l==0) ? 0 : | 82 | int h1 = h&(L->strt.size-1); |
124 | ((unsigned int)(str[0]+str[l-1]))&(NUM_HASHSTR-1)]; | ||
125 | int h1 = h&(tb->size-1); | ||
126 | TString *ts; | 83 | TString *ts; |
127 | for (ts = tb->hash[h1]; ts; ts = ts->nexthash) { | 84 | for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) { |
128 | if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) | 85 | if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) |
129 | return ts; | 86 | return ts; |
130 | } | 87 | } |
131 | /* not found */ | 88 | /* not found */ |
132 | ts = newone_s(L, str, l, h); /* create new entry */ | 89 | ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char)); |
133 | newentry(L, tb, ts, h1); /* insert it on table */ | 90 | ts->marked = 0; |
91 | ts->nexthash = NULL; | ||
92 | ts->u.s.len = l; | ||
93 | ts->u.s.hash = h; | ||
94 | ts->u.s.constindex = 0; | ||
95 | memcpy(ts->str, str, l); | ||
96 | ts->str[l] = 0; /* ending 0 */ | ||
97 | L->nblocks += gcsizestring(L, l); | ||
98 | newentry(L, &L->strt, ts, h1); /* insert it on table */ | ||
134 | return ts; | 99 | return ts; |
135 | } | 100 | } |
136 | 101 | ||
137 | 102 | ||
138 | /* | ||
139 | ** uses '%' for one hashing with userdata because addresses are too regular, | ||
140 | ** so two '&' operations would be highly correlated | ||
141 | */ | ||
142 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { | 103 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { |
143 | unsigned long h = IntPoint(udata); | 104 | unsigned long h = IntPoint(udata); |
144 | stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; | 105 | int h1 = h&(L->udt.size-1); |
145 | int h1 = h&(tb->size-1); | ||
146 | TString *ts; | 106 | TString *ts; |
147 | for (ts = tb->hash[h1]; ts; ts = ts->nexthash) { | 107 | for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) { |
148 | if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) | 108 | if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) |
149 | return ts; | 109 | return ts; |
150 | } | 110 | } |
151 | /* not found */ | 111 | /* not found */ |
152 | ts = newone_u(L, udata, tag); | 112 | ts = luaM_new(L, TString); |
153 | newentry(L, tb, ts, h1); | 113 | ts->marked = 0; |
114 | ts->nexthash = NULL; | ||
115 | ts->u.d.value = udata; | ||
116 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; | ||
117 | L->nblocks += gcsizeudata; | ||
118 | newentry(L, &L->udt, ts, h1); /* insert it on table */ | ||
154 | return ts; | 119 | return ts; |
155 | } | 120 | } |
156 | 121 | ||
@@ -159,16 +124,10 @@ TString *luaS_new (lua_State *L, const char *str) { | |||
159 | return luaS_newlstr(L, str, strlen(str)); | 124 | return luaS_newlstr(L, str, strlen(str)); |
160 | } | 125 | } |
161 | 126 | ||
127 | |||
162 | TString *luaS_newfixed (lua_State *L, const char *str) { | 128 | TString *luaS_newfixed (lua_State *L, const char *str) { |
163 | TString *ts = luaS_new(L, str); | 129 | TString *ts = luaS_new(L, str); |
164 | if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */ | 130 | if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */ |
165 | return ts; | 131 | return ts; |
166 | } | 132 | } |
167 | 133 | ||
168 | |||
169 | void luaS_free (lua_State *L, TString *t) { | ||
170 | L->nblocks -= (t->constindex == -1) ? gcsizeudata : | ||
171 | gcsizestring(L, t->u.s.len); | ||
172 | luaM_free(L, t); | ||
173 | } | ||
174 | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.18 2000/03/10 18:37:44 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.19 2000/05/08 19:32:53 roberto Exp roberto $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -12,11 +12,6 @@ | |||
12 | #include "lstate.h" | 12 | #include "lstate.h" |
13 | 13 | ||
14 | 14 | ||
15 | #define NUM_HASHSTR 32 | ||
16 | #define NUM_HASHUDATA 31 | ||
17 | #define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA) | ||
18 | |||
19 | |||
20 | /* | 15 | /* |
21 | ** any TString with mark>=FIXMARK is never collected. | 16 | ** any TString with mark>=FIXMARK is never collected. |
22 | ** Marks>=RESERVEDMARK are used to identify reserved words. | 17 | ** Marks>=RESERVEDMARK are used to identify reserved words. |
@@ -25,11 +20,14 @@ | |||
25 | #define RESERVEDMARK 3 | 20 | #define RESERVEDMARK 3 |
26 | 21 | ||
27 | 22 | ||
23 | #define gcsizestring(L, l) numblocks(L, 0, sizeof(TString)+l) | ||
24 | #define gcsizeudata gcsizestring(L, 0) | ||
25 | |||
26 | |||
28 | void luaS_init (lua_State *L); | 27 | void luaS_init (lua_State *L); |
29 | void luaS_resize (lua_State *L, stringtable *tb, int newsize); | 28 | void luaS_resize (lua_State *L, stringtable *tb, int newsize); |
30 | TString *luaS_createudata (lua_State *L, void *udata, int tag); | 29 | TString *luaS_createudata (lua_State *L, void *udata, int tag); |
31 | void luaS_freeall (lua_State *L); | 30 | void luaS_freeall (lua_State *L); |
32 | void luaS_free (lua_State *L, TString *ts); | ||
33 | TString *luaS_newlstr (lua_State *L, const char *str, long l); | 31 | TString *luaS_newlstr (lua_State *L, const char *str, long l); |
34 | TString *luaS_new (lua_State *L, const char *str); | 32 | TString *luaS_new (lua_State *L, const char *str); |
35 | TString *luaS_newfixed (lua_State *L, const char *str); | 33 | TString *luaS_newfixed (lua_State *L, const char *str); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.16 2000/04/14 17:46:15 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.17 2000/05/08 19:32:53 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "lapi.h" | 15 | #include "lapi.h" |
16 | #include "lauxlib.h" | 16 | #include "lauxlib.h" |
17 | #include "ldo.h" | ||
17 | #include "lmem.h" | 18 | #include "lmem.h" |
18 | #include "lopcodes.h" | 19 | #include "lopcodes.h" |
19 | #include "lstate.h" | 20 | #include "lstate.h" |
@@ -193,24 +194,22 @@ static void table_query (lua_State *L) { | |||
193 | 194 | ||
194 | 195 | ||
195 | static void string_query (lua_State *L) { | 196 | static void string_query (lua_State *L) { |
196 | int h = luaL_check_int(L, 1) - 1; | 197 | stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt; |
197 | int s = luaL_opt_int(L, 2, 0) - 1; | 198 | int s = luaL_opt_int(L, 2, 0) - 1; |
198 | if (s==-1) { | 199 | if (s==-1) { |
199 | if (h < NUM_HASHS) { | 200 | lua_pushnumber(L, tb->nuse); |
200 | lua_pushnumber(L, L->string_root[h].nuse); | 201 | lua_pushnumber(L, tb->size); |
201 | lua_pushnumber(L, L->string_root[h].size); | ||
202 | } | ||
203 | } | 202 | } |
204 | else { | 203 | else if (s < tb->size) { |
205 | TString *ts = L->string_root[h].hash[s]; | 204 | TString *ts; |
206 | for (ts = L->string_root[h].hash[s]; ts; ts = ts->nexthash) { | 205 | for (ts = tb->hash[s]; ts; ts = ts->nexthash) { |
207 | if (ts->constindex == -1) lua_pushstring(L, "<USERDATA>"); | 206 | ttype(L->top) = TAG_STRING; |
208 | else lua_pushstring(L, ts->str); | 207 | tsvalue(L->top) = ts; |
208 | incr_top; | ||
209 | } | 209 | } |
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | |||
214 | /* | 213 | /* |
215 | ** {====================================================== | 214 | ** {====================================================== |
216 | ** function to test the API with C. It interprets a kind of "assembler" | 215 | ** function to test the API with C. It interprets a kind of "assembler" |