diff options
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 72 |
1 files changed, 35 insertions, 37 deletions
@@ -132,57 +132,49 @@ static lua_Integer loadInteger (LoadState *S) { | |||
132 | 132 | ||
133 | 133 | ||
134 | /* | 134 | /* |
135 | ** Load a nullable string into prototype 'p'. | 135 | ** Load a nullable string into slot 'sl' from prototype 'p'. The |
136 | ** assignment to the slot and the barrier must be performed before any | ||
137 | ** possible GC activity, to anchor the string. (Both 'loadVector' and | ||
138 | ** 'luaH_setint' can call the GC.) | ||
136 | */ | 139 | */ |
137 | static TString *loadStringN (LoadState *S, Proto *p) { | 140 | static void loadString (LoadState *S, Proto *p, TString **sl) { |
138 | lua_State *L = S->L; | 141 | lua_State *L = S->L; |
139 | TString *ts; | 142 | TString *ts; |
140 | TValue sv; | 143 | TValue sv; |
141 | size_t size = loadSize(S); | 144 | size_t size = loadSize(S); |
142 | if (size == 0) /* no string? */ | 145 | if (size == 0) { /* no string? */ |
143 | return NULL; | 146 | *sl = NULL; |
147 | return; | ||
148 | } | ||
144 | else if (size == 1) { /* previously saved string? */ | 149 | else if (size == 1) { /* previously saved string? */ |
145 | int idx = loadInt(S); /* get its index */ | 150 | int idx = loadInt(S); /* get its index */ |
146 | TValue stv; | 151 | TValue stv; |
147 | luaH_getint(S->h, idx, &stv); | 152 | luaH_getint(S->h, idx, &stv); |
148 | return tsvalue(&stv); | 153 | *sl = ts = tsvalue(&stv); |
154 | luaC_objbarrier(L, p, ts); | ||
155 | return; | ||
149 | } | 156 | } |
150 | else if ((size -= 2) <= LUAI_MAXSHORTLEN) { /* short string? */ | 157 | else if ((size -= 2) <= LUAI_MAXSHORTLEN) { /* short string? */ |
151 | char buff[LUAI_MAXSHORTLEN + 1]; /* extra space for '\0' */ | 158 | char buff[LUAI_MAXSHORTLEN + 1]; /* extra space for '\0' */ |
152 | loadVector(S, buff, size + 1); /* load string into buffer */ | 159 | loadVector(S, buff, size + 1); /* load string into buffer */ |
153 | ts = luaS_newlstr(L, buff, size); /* create string */ | 160 | *sl = ts = luaS_newlstr(L, buff, size); /* create string */ |
161 | luaC_objbarrier(L, p, ts); | ||
154 | } | 162 | } |
155 | else { /* long string */ | 163 | else if (S->fixed) { /* for a fixed buffer, use a fixed string */ |
156 | if (S->fixed) { /* for a fixed buffer, use a fixed string */ | 164 | const char *s = getaddr(S, size + 1, char); /* get content address */ |
157 | const char *s = getaddr(S, size + 1, char); /* get content address */ | 165 | *sl = ts = luaS_newextlstr(L, s, size, NULL, NULL); |
158 | ts = luaS_newextlstr(L, s, size, NULL, NULL); | 166 | luaC_objbarrier(L, p, ts); |
159 | } | 167 | } |
160 | else { /* create internal copy */ | 168 | else { /* create internal copy */ |
161 | ts = luaS_createlngstrobj(L, size); /* create string */ | 169 | *sl = ts = luaS_createlngstrobj(L, size); /* create string */ |
162 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ | 170 | luaC_objbarrier(L, p, ts); |
163 | luaD_inctop(L); | 171 | loadVector(S, getlngstr(ts), size); /* load directly in final place */ |
164 | loadVector(S, getlngstr(ts), size); /* load directly in final place */ | 172 | loadByte(S); /* skip ending '\0' */ |
165 | loadByte(S); /* skip ending '\0' */ | ||
166 | L->top.p--; /* pop string */ | ||
167 | } | ||
168 | } | 173 | } |
169 | luaC_objbarrier(L, p, ts); | ||
170 | S->nstr++; /* add string to list of saved strings */ | 174 | S->nstr++; /* add string to list of saved strings */ |
171 | setsvalue(L, &sv, ts); | 175 | setsvalue(L, &sv, ts); |
172 | luaH_setint(L, S->h, S->nstr, &sv); | 176 | luaH_setint(L, S->h, S->nstr, &sv); |
173 | luaC_objbarrierback(L, obj2gco(S->h), ts); | 177 | luaC_objbarrierback(L, obj2gco(S->h), ts); |
174 | return ts; | ||
175 | } | ||
176 | |||
177 | |||
178 | /* | ||
179 | ** Load a non-nullable string into prototype 'p'. | ||
180 | */ | ||
181 | static TString *loadString (LoadState *S, Proto *p) { | ||
182 | TString *st = loadStringN(S, p); | ||
183 | if (st == NULL) | ||
184 | error(S, "bad format for constant string"); | ||
185 | return st; | ||
186 | } | 178 | } |
187 | 179 | ||
188 | 180 | ||
@@ -231,9 +223,15 @@ static void loadConstants (LoadState *S, Proto *f) { | |||
231 | setivalue(o, loadInteger(S)); | 223 | setivalue(o, loadInteger(S)); |
232 | break; | 224 | break; |
233 | case LUA_VSHRSTR: | 225 | case LUA_VSHRSTR: |
234 | case LUA_VLNGSTR: | 226 | case LUA_VLNGSTR: { |
235 | setsvalue2n(S->L, o, loadString(S, f)); | 227 | lua_assert(f->source == NULL); |
228 | loadString(S, f, &f->source); /* use 'source' to anchor string */ | ||
229 | if (f->source == NULL) | ||
230 | error(S, "bad format for constant string"); | ||
231 | setsvalue2n(S->L, o, f->source); /* save it in the right place */ | ||
232 | f->source = NULL; | ||
236 | break; | 233 | break; |
234 | } | ||
237 | default: lua_assert(0); | 235 | default: lua_assert(0); |
238 | } | 236 | } |
239 | } | 237 | } |
@@ -301,7 +299,7 @@ static void loadDebug (LoadState *S, Proto *f) { | |||
301 | for (i = 0; i < n; i++) | 299 | for (i = 0; i < n; i++) |
302 | f->locvars[i].varname = NULL; | 300 | f->locvars[i].varname = NULL; |
303 | for (i = 0; i < n; i++) { | 301 | for (i = 0; i < n; i++) { |
304 | f->locvars[i].varname = loadStringN(S, f); | 302 | loadString(S, f, &f->locvars[i].varname); |
305 | f->locvars[i].startpc = loadInt(S); | 303 | f->locvars[i].startpc = loadInt(S); |
306 | f->locvars[i].endpc = loadInt(S); | 304 | f->locvars[i].endpc = loadInt(S); |
307 | } | 305 | } |
@@ -309,12 +307,11 @@ static void loadDebug (LoadState *S, Proto *f) { | |||
309 | if (n != 0) /* does it have debug information? */ | 307 | if (n != 0) /* does it have debug information? */ |
310 | n = f->sizeupvalues; /* must be this many */ | 308 | n = f->sizeupvalues; /* must be this many */ |
311 | for (i = 0; i < n; i++) | 309 | for (i = 0; i < n; i++) |
312 | f->upvalues[i].name = loadStringN(S, f); | 310 | loadString(S, f, &f->upvalues[i].name); |
313 | } | 311 | } |
314 | 312 | ||
315 | 313 | ||
316 | static void loadFunction (LoadState *S, Proto *f) { | 314 | static void loadFunction (LoadState *S, Proto *f) { |
317 | f->source = loadStringN(S, f); | ||
318 | f->linedefined = loadInt(S); | 315 | f->linedefined = loadInt(S); |
319 | f->lastlinedefined = loadInt(S); | 316 | f->lastlinedefined = loadInt(S); |
320 | f->numparams = loadByte(S); | 317 | f->numparams = loadByte(S); |
@@ -326,6 +323,7 @@ static void loadFunction (LoadState *S, Proto *f) { | |||
326 | loadConstants(S, f); | 323 | loadConstants(S, f); |
327 | loadUpvalues(S, f); | 324 | loadUpvalues(S, f); |
328 | loadProtos(S, f); | 325 | loadProtos(S, f); |
326 | loadString(S, f, &f->source); | ||
329 | loadDebug(S, f); | 327 | loadDebug(S, f); |
330 | } | 328 | } |
331 | 329 | ||