** Load a nullable string into slot 'sl' from prototype 'p'. The ** assignment to the slot and the barrier must be performed before any ** possible GC activity, to anchor the string. (Both 'loadVector' and ** 'luaH_setint' can call the GC.) */
| 143 | ** 'luaH_setint' can call the GC.) |
| 144 | */ |
| 145 | static void loadString (LoadState *S, Proto *p, TString **sl) { |
| 146 | lua_State *L = S->L; |
| 147 | TString *ts; |
| 148 | TValue sv; |
| 149 | size_t size = loadSize(S); |
| 150 | if (size == 0) { /* previously saved string? */ |
| 151 | lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED); /* get its index */ |
| 152 | TValue stv; |
| 153 | if (idx == 0) { /* no string? */ |
| 154 | lua_assert(*sl == NULL); /* must be prefilled */ |
| 155 | return; |
| 156 | } |
| 157 | if (novariant(luaH_getint(S->h, l_castU2S(idx), &stv)) != LUA_TSTRING) |
| 158 | error(S, "invalid string index"); |
| 159 | *sl = ts = tsvalue(&stv); /* get its value */ |
| 160 | luaC_objbarrier(L, p, ts); |
| 161 | return; /* do not save it again */ |
| 162 | } |
| 163 | else if ((size -= 1) <= LUAI_MAXSHORTLEN) { /* short string? */ |
| 164 | char buff[LUAI_MAXSHORTLEN + 1]; /* extra space for '\0' */ |
| 165 | loadVector(S, buff, size + 1); /* load string into buffer */ |
| 166 | *sl = ts = luaS_newlstr(L, buff, size); /* create string */ |
| 167 | luaC_objbarrier(L, p, ts); |
| 168 | } |
| 169 | else if (S->fixed) { /* for a fixed buffer, use a fixed string */ |
| 170 | const char *s = getaddr(S, size + 1, char); /* get content address */ |
| 171 | *sl = ts = luaS_newextlstr(L, s, size, NULL, NULL); |
| 172 | luaC_objbarrier(L, p, ts); |
| 173 | } |
| 174 | else { /* create internal copy */ |
| 175 | *sl = ts = luaS_createlngstrobj(L, size); /* create string */ |
| 176 | luaC_objbarrier(L, p, ts); |
| 177 | loadVector(S, getlngstr(ts), size + 1); /* load directly in final place */ |
| 178 | } |
| 179 | /* add string to list of saved strings */ |
| 180 | S->nstr++; |
| 181 | setsvalue(L, &sv, ts); |
| 182 | luaH_setint(L, S->h, l_castU2S(S->nstr), &sv); |
| 183 | luaC_objbarrierback(L, obj2gco(S->h), ts); |
| 184 | } |
| 185 | |
| 186 | |
| 187 | static void loadCode (LoadState *S, Proto *f) { |
no test coverage detected