diff options
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 65 |
1 files changed, 17 insertions, 48 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.33 2000/03/10 14:38:10 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.34 2000/03/10 18:37:44 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 | */ |
@@ -62,11 +62,13 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
62 | TString *p = tb->hash[i]; | 62 | TString *p = tb->hash[i]; |
63 | while (p) { /* for each node in the list */ | 63 | while (p) { /* for each node in the list */ |
64 | TString *next = p->nexthash; /* save next */ | 64 | TString *next = p->nexthash; /* save next */ |
65 | int h = p->hash&(newsize-1); /* new position */ | 65 | unsigned long h = (p->constindex == -1) ? IntPoint(p->u.d.value) : |
66 | LUA_ASSERT(L, p->hash%newsize == (p->hash&(newsize-1)), | 66 | p->u.s.hash; |
67 | int h1 = h&(newsize-1); /* new position */ | ||
68 | LUA_ASSERT(L, h%newsize == (h&(newsize-1)), | ||
67 | "a&(x-1) == a%x, for x power of 2"); | 69 | "a&(x-1) == a%x, for x power of 2"); |
68 | p->nexthash = newhash[h]; /* chain it in new position */ | 70 | p->nexthash = newhash[h1]; /* chain it in new position */ |
69 | newhash[h] = p; | 71 | newhash[h1] = p; |
70 | p = next; | 72 | p = next; |
71 | } | 73 | } |
72 | } | 74 | } |
@@ -76,32 +78,29 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
76 | } | 78 | } |
77 | 79 | ||
78 | 80 | ||
79 | static TString *newone (lua_State *L, long l, unsigned long h) { | 81 | static TString *newone (lua_State *L, long l) { |
80 | TString *ts = (TString *)luaM_malloc(L, | 82 | TString *ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char)); |
81 | sizeof(TString)+l*sizeof(char)); | ||
82 | ts->marked = 0; | 83 | ts->marked = 0; |
83 | ts->nexthash = NULL; | 84 | ts->nexthash = NULL; |
84 | ts->hash = h; | ||
85 | return ts; | 85 | return ts; |
86 | } | 86 | } |
87 | 87 | ||
88 | 88 | ||
89 | static TString *newone_s (lua_State *L, const char *str, | 89 | static TString *newone_s (lua_State *L, const char *str, |
90 | long l, unsigned long h) { | 90 | long l, unsigned long h) { |
91 | TString *ts = newone(L, l, h); | 91 | TString *ts = newone(L, l); |
92 | memcpy(ts->str, str, l); | 92 | memcpy(ts->str, str, l); |
93 | ts->str[l] = 0; /* ending 0 */ | 93 | ts->str[l] = 0; /* ending 0 */ |
94 | ts->u.s.gv = NULL; /* no global value */ | ||
95 | ts->u.s.len = l; | 94 | ts->u.s.len = l; |
95 | ts->u.s.hash = h; | ||
96 | ts->constindex = 0; | 96 | ts->constindex = 0; |
97 | L->nblocks += gcsizestring(L, l); | 97 | L->nblocks += gcsizestring(L, l); |
98 | return ts; | 98 | return ts; |
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
102 | static TString *newone_u (lua_State *L, void *buff, | 102 | static TString *newone_u (lua_State *L, void *buff, int tag) { |
103 | int tag, unsigned long h) { | 103 | TString *ts = newone(L, 0); |
104 | TString *ts = newone(L, 0, h); | ||
105 | ts->u.d.value = buff; | 104 | ts->u.d.value = buff; |
106 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; | 105 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; |
107 | ts->constindex = -1; /* tag -> this is a userdata */ | 106 | ts->constindex = -1; /* tag -> this is a userdata */ |
@@ -141,7 +140,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, long l) { | |||
141 | ** so two '&' operations would be highly correlated | 140 | ** so two '&' operations would be highly correlated |
142 | */ | 141 | */ |
143 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { | 142 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { |
144 | unsigned long h = IntPoint(L, udata); | 143 | unsigned long h = IntPoint(udata); |
145 | stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; | 144 | stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; |
146 | int h1 = h&(tb->size-1); | 145 | int h1 = h&(tb->size-1); |
147 | TString *ts; | 146 | TString *ts; |
@@ -150,7 +149,7 @@ TString *luaS_createudata (lua_State *L, void *udata, int tag) { | |||
150 | return ts; | 149 | return ts; |
151 | } | 150 | } |
152 | /* not found */ | 151 | /* not found */ |
153 | ts = newone_u(L, udata, tag, h); | 152 | ts = newone_u(L, udata, tag); |
154 | newentry(L, tb, ts, h1); | 153 | newentry(L, tb, ts, h1); |
155 | return ts; | 154 | return ts; |
156 | } | 155 | } |
@@ -168,38 +167,8 @@ TString *luaS_newfixed (lua_State *L, const char *str) { | |||
168 | 167 | ||
169 | 168 | ||
170 | void luaS_free (lua_State *L, TString *t) { | 169 | void luaS_free (lua_State *L, TString *t) { |
171 | if (t->constindex == -1) /* is userdata? */ | 170 | L->nblocks -= (t->constindex == -1) ? gcsizeudata : |
172 | L->nblocks -= gcsizeudata; | 171 | gcsizestring(L, t->u.s.len); |
173 | else { /* is string */ | ||
174 | L->nblocks -= gcsizestring(L, t->u.s.len); | ||
175 | luaM_free(L, t->u.s.gv); | ||
176 | } | ||
177 | luaM_free(L, t); | 172 | luaM_free(L, t); |
178 | } | 173 | } |
179 | 174 | ||
180 | |||
181 | GlobalVar *luaS_assertglobal (lua_State *L, TString *ts) { | ||
182 | GlobalVar *gv = ts->u.s.gv; | ||
183 | if (!gv) { /* no global value yet? */ | ||
184 | gv = luaM_new(L, GlobalVar); | ||
185 | gv->value.ttype = TAG_NIL; /* initial value */ | ||
186 | gv->name = ts; | ||
187 | gv->next = L->rootglobal; /* chain in global list */ | ||
188 | L->rootglobal = gv; | ||
189 | ts->u.s.gv = gv; | ||
190 | } | ||
191 | return gv; | ||
192 | } | ||
193 | |||
194 | |||
195 | GlobalVar *luaS_assertglobalbyname (lua_State *L, const char *name) { | ||
196 | return luaS_assertglobal(L, luaS_new(L, name)); | ||
197 | } | ||
198 | |||
199 | |||
200 | int luaS_globaldefined (lua_State *L, const char *name) { | ||
201 | TString *ts = luaS_new(L, name); | ||
202 | return ts->u.s.gv && ts->u.s.gv->value.ttype != TAG_NIL; | ||
203 | } | ||
204 | |||
205 | |||