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