** Checks whether short string exists and reuses it or creates a new one. */
| 187 | ** Checks whether short string exists and reuses it or creates a new one. |
| 188 | */ |
| 189 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
| 190 | TString *ts; |
| 191 | global_State *g = G(L); |
| 192 | stringtable *tb = &g->strt; |
| 193 | unsigned int h = luaS_hash(str, l, g->seed); |
| 194 | TString **list = &tb->hash[lmod(h, tb->size)]; |
| 195 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
| 196 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
| 197 | if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { |
| 198 | /* found! */ |
| 199 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
| 200 | changewhite(ts); /* resurrect it */ |
| 201 | return ts; |
| 202 | } |
| 203 | } |
| 204 | /* else must create a new string */ |
| 205 | if (tb->nuse >= tb->size) { /* need to grow string table? */ |
| 206 | growstrtab(L, tb); |
| 207 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ |
| 208 | } |
| 209 | ts = createstrobj(L, l, LUA_VSHRSTR, h); |
| 210 | ts->shrlen = cast_byte(l); |
| 211 | memcpy(getshrstr(ts), str, l * sizeof(char)); |
| 212 | ts->u.hnext = *list; |
| 213 | *list = ts; |
| 214 | tb->nuse++; |
| 215 | return ts; |
| 216 | } |
| 217 | |
| 218 | |
| 219 | /* |
no test coverage detected