aboutsummaryrefslogtreecommitdiff
path: root/lundump.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lundump.c87
1 files changed, 72 insertions, 15 deletions
diff --git a/lundump.c b/lundump.c
index e8d92a85..45708f96 100644
--- a/lundump.c
+++ b/lundump.c
@@ -21,6 +21,7 @@
21#include "lmem.h" 21#include "lmem.h"
22#include "lobject.h" 22#include "lobject.h"
23#include "lstring.h" 23#include "lstring.h"
24#include "ltable.h"
24#include "lundump.h" 25#include "lundump.h"
25#include "lzio.h" 26#include "lzio.h"
26 27
@@ -34,6 +35,10 @@ typedef struct {
34 lua_State *L; 35 lua_State *L;
35 ZIO *Z; 36 ZIO *Z;
36 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */
39 lu_mem offset; /* current position relative to beginning of dump */
40 lua_Integer nstr; /* number of strings in the list */
41 lu_byte fixed; /* dump is fixed in memory */
37} LoadState; 42} LoadState;
38 43
39 44
@@ -52,6 +57,27 @@ static l_noret error (LoadState *S, const char *why) {
52static void loadBlock (LoadState *S, void *b, size_t size) { 57static void loadBlock (LoadState *S, void *b, size_t size) {
53 if (luaZ_read(S->Z, b, size) != 0) 58 if (luaZ_read(S->Z, b, size) != 0)
54 error(S, "truncated chunk"); 59 error(S, "truncated chunk");
60 S->offset += size;
61}
62
63
64static void loadAlign (LoadState *S, int align) {
65 int padding = align - (S->offset % align);
66 if (padding < align) { /* apd == align means no padding */
67 lua_Integer paddingContent;
68 loadBlock(S, &paddingContent, padding);
69 lua_assert(S->offset % align == 0);
70 }
71}
72
73
74#define getaddr(S,n,t) cast(t *, getaddr_(S,n,sizeof(t)))
75
76static const void *getaddr_ (LoadState *S, int n, int sz) {
77 const void *block = luaZ_getaddr(S->Z, n * sz);
78 if (block == NULL)
79 error(S, "truncated fixed buffer");
80 return block;
55} 81}
56 82
57 83
@@ -62,6 +88,7 @@ static lu_byte loadByte (LoadState *S) {
62 int b = zgetc(S->Z); 88 int b = zgetc(S->Z);
63 if (b == EOZ) 89 if (b == EOZ)
64 error(S, "truncated chunk"); 90 error(S, "truncated chunk");
91 S->offset++;
65 return cast_byte(b); 92 return cast_byte(b);
66} 93}
67 94
@@ -110,10 +137,16 @@ static lua_Integer loadInteger (LoadState *S) {
110static TString *loadStringN (LoadState *S, Proto *p) { 137static TString *loadStringN (LoadState *S, Proto *p) {
111 lua_State *L = S->L; 138 lua_State *L = S->L;
112 TString *ts; 139 TString *ts;
140 TValue sv;
113 size_t size = loadSize(S); 141 size_t size = loadSize(S);
114 if (size == 0) /* no string? */ 142 if (size == 0) /* no string? */
115 return NULL; 143 return NULL;
116 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 144 else if (size == 1) { /* previously saved string? */
145 int idx = loadInt(S); /* get its index */
146 const TValue *stv = luaH_getint(S->h, idx);
147 return tsvalue(stv);
148 }
149 else if (size -= 2, size <= LUAI_MAXSHORTLEN) { /* short string? */
117 char buff[LUAI_MAXSHORTLEN]; 150 char buff[LUAI_MAXSHORTLEN];
118 loadVector(S, buff, size); /* load string into buffer */ 151 loadVector(S, buff, size); /* load string into buffer */
119 ts = luaS_newlstr(L, buff, size); /* create string */ 152 ts = luaS_newlstr(L, buff, size); /* create string */
@@ -126,6 +159,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
126 L->top.p--; /* pop string */ 159 L->top.p--; /* pop string */
127 } 160 }
128 luaC_objbarrier(L, p, ts); 161 luaC_objbarrier(L, p, ts);
162 S->nstr++; /* add string to list of saved strings */
163 setsvalue(L, &sv, ts);
164 luaH_setint(L, S->h, S->nstr, &sv);
165 luaC_objbarrierback(L, obj2gco(S->h), ts);
129 return ts; 166 return ts;
130} 167}
131 168
@@ -143,13 +180,20 @@ static TString *loadString (LoadState *S, Proto *p) {
143 180
144static void loadCode (LoadState *S, Proto *f) { 181static void loadCode (LoadState *S, Proto *f) {
145 int n = loadInt(S); 182 int n = loadInt(S);
146 f->code = luaM_newvectorchecked(S->L, n, Instruction); 183 loadAlign(S, sizeof(f->code[0]));
147 f->sizecode = n; 184 if (S->fixed) {
148 loadVector(S, f->code, n); 185 f->code = getaddr(S, n, Instruction);
186 f->sizecode = n;
187 }
188 else {
189 f->code = luaM_newvectorchecked(S->L, n, Instruction);
190 f->sizecode = n;
191 loadVector(S, f->code, n);
192 }
149} 193}
150 194
151 195
152static void loadFunction(LoadState *S, Proto *f, TString *psource); 196static void loadFunction(LoadState *S, Proto *f);
153 197
154 198
155static void loadConstants (LoadState *S, Proto *f) { 199static void loadConstants (LoadState *S, Proto *f) {
@@ -198,7 +242,7 @@ static void loadProtos (LoadState *S, Proto *f) {
198 for (i = 0; i < n; i++) { 242 for (i = 0; i < n; i++) {
199 f->p[i] = luaF_newproto(S->L); 243 f->p[i] = luaF_newproto(S->L);
200 luaC_objbarrier(S->L, f, f->p[i]); 244 luaC_objbarrier(S->L, f, f->p[i]);
201 loadFunction(S, f->p[i], f->source); 245 loadFunction(S, f->p[i]);
202 } 246 }
203} 247}
204 248
@@ -227,9 +271,15 @@ static void loadUpvalues (LoadState *S, Proto *f) {
227static void loadDebug (LoadState *S, Proto *f) { 271static void loadDebug (LoadState *S, Proto *f) {
228 int i, n; 272 int i, n;
229 n = loadInt(S); 273 n = loadInt(S);
230 f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); 274 if (S->fixed) {
231 f->sizelineinfo = n; 275 f->lineinfo = getaddr(S, n, ls_byte);
232 loadVector(S, f->lineinfo, n); 276 f->sizelineinfo = n;
277 }
278 else {
279 f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte);
280 f->sizelineinfo = n;
281 loadVector(S, f->lineinfo, n);
282 }
233 n = loadInt(S); 283 n = loadInt(S);
234 f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); 284 f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo);
235 f->sizeabslineinfo = n; 285 f->sizeabslineinfo = n;
@@ -255,14 +305,14 @@ static void loadDebug (LoadState *S, Proto *f) {
255} 305}
256 306
257 307
258static void loadFunction (LoadState *S, Proto *f, TString *psource) { 308static void loadFunction (LoadState *S, Proto *f) {
259 f->source = loadStringN(S, f); 309 f->source = loadStringN(S, f);
260 if (f->source == NULL) /* no source in dump? */
261 f->source = psource; /* reuse parent's source */
262 f->linedefined = loadInt(S); 310 f->linedefined = loadInt(S);
263 f->lastlinedefined = loadInt(S); 311 f->lastlinedefined = loadInt(S);
264 f->numparams = loadByte(S); 312 f->numparams = loadByte(S);
265 f->is_vararg = loadByte(S); 313 f->flag = loadByte(S) & PF_ISVARARG; /* get only the meaningful flags */
314 if (S->fixed)
315 f->flag |= PF_FIXED; /* signal that code is fixed */
266 f->maxstacksize = loadByte(S); 316 f->maxstacksize = loadByte(S);
267 loadCode(S, f); 317 loadCode(S, f);
268 loadConstants(S, f); 318 loadConstants(S, f);
@@ -310,7 +360,7 @@ static void checkHeader (LoadState *S) {
310/* 360/*
311** Load precompiled chunk. 361** Load precompiled chunk.
312*/ 362*/
313LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 363LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
314 LoadState S; 364 LoadState S;
315 LClosure *cl; 365 LClosure *cl;
316 if (*name == '@' || *name == '=') 366 if (*name == '@' || *name == '=')
@@ -321,15 +371,22 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
321 S.name = name; 371 S.name = name;
322 S.L = L; 372 S.L = L;
323 S.Z = Z; 373 S.Z = Z;
374 S.fixed = fixed;
375 S.offset = 1; /* fist byte was already read */
324 checkHeader(&S); 376 checkHeader(&S);
325 cl = luaF_newLclosure(L, loadByte(&S)); 377 cl = luaF_newLclosure(L, loadByte(&S));
326 setclLvalue2s(L, L->top.p, cl); 378 setclLvalue2s(L, L->top.p, cl);
327 luaD_inctop(L); 379 luaD_inctop(L);
380 S.h = luaH_new(L); /* create list of saved strings */
381 S.nstr = 0;
382 sethvalue2s(L, L->top.p, S.h); /* anchor it */
383 luaD_inctop(L);
328 cl->p = luaF_newproto(L); 384 cl->p = luaF_newproto(L);
329 luaC_objbarrier(L, cl, cl->p); 385 luaC_objbarrier(L, cl, cl->p);
330 loadFunction(&S, cl->p, NULL); 386 loadFunction(&S, cl->p);
331 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 387 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
332 luai_verifycode(L, cl->p); 388 luai_verifycode(L, cl->p);
389 L->top.p--; /* pop table */
333 return cl; 390 return cl;
334} 391}
335 392