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