diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-08-25 17:40:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-08-25 17:40:20 -0300 |
commit | 05545816057cfdc54bb58199388a2d8878ae5542 (patch) | |
tree | 284864db2093d4eecb500249ac1791149388266e | |
parent | c815c2f0eb7a4ac01d4f664f3db44c199ee4e211 (diff) | |
download | lua-05545816057cfdc54bb58199388a2d8878ae5542.tar.gz lua-05545816057cfdc54bb58199388a2d8878ae5542.tar.bz2 lua-05545816057cfdc54bb58199388a2d8878ae5542.zip |
Opcode in dumps is stored properly aligned
Diffstat (limited to '')
-rw-r--r-- | ldump.c | 14 | ||||
-rw-r--r-- | lundump.c | 17 |
2 files changed, 30 insertions, 1 deletions
@@ -26,6 +26,7 @@ typedef struct { | |||
26 | lua_State *L; | 26 | lua_State *L; |
27 | lua_Writer writer; | 27 | lua_Writer writer; |
28 | void *data; | 28 | void *data; |
29 | lu_mem offset; /* current position relative to beginning of dump */ | ||
29 | int strip; | 30 | int strip; |
30 | int status; | 31 | int status; |
31 | Table *h; /* table to track saved strings */ | 32 | Table *h; /* table to track saved strings */ |
@@ -47,6 +48,17 @@ static void dumpBlock (DumpState *D, const void *b, size_t size) { | |||
47 | lua_unlock(D->L); | 48 | lua_unlock(D->L); |
48 | D->status = (*D->writer)(D->L, b, size, D->data); | 49 | D->status = (*D->writer)(D->L, b, size, D->data); |
49 | lua_lock(D->L); | 50 | lua_lock(D->L); |
51 | D->offset += size; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | |||
56 | static void dumpAlign (DumpState *D, int align) { | ||
57 | int padding = align - (D->offset % align); | ||
58 | if (padding < align) { /* apd == align means no padding */ | ||
59 | static lua_Integer paddingContent = 0; | ||
60 | dumpBlock(D, &paddingContent, padding); | ||
61 | lua_assert(D->offset % align == 0); | ||
50 | } | 62 | } |
51 | } | 63 | } |
52 | 64 | ||
@@ -126,6 +138,7 @@ static void dumpString (DumpState *D, TString *s) { | |||
126 | 138 | ||
127 | static void dumpCode (DumpState *D, const Proto *f) { | 139 | static void dumpCode (DumpState *D, const Proto *f) { |
128 | dumpInt(D, f->sizecode); | 140 | dumpInt(D, f->sizecode); |
141 | dumpAlign(D, sizeof(f->code[0])); | ||
129 | dumpVector(D, f->code, f->sizecode); | 142 | dumpVector(D, f->code, f->sizecode); |
130 | } | 143 | } |
131 | 144 | ||
@@ -242,6 +255,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | |||
242 | DumpState D; | 255 | DumpState D; |
243 | D.L = L; | 256 | D.L = L; |
244 | D.writer = w; | 257 | D.writer = w; |
258 | D.offset = 0; | ||
245 | D.data = data; | 259 | D.data = data; |
246 | D.strip = strip; | 260 | D.strip = strip; |
247 | D.status = 0; | 261 | D.status = 0; |
@@ -36,6 +36,7 @@ typedef struct { | |||
36 | ZIO *Z; | 36 | ZIO *Z; |
37 | const char *name; | 37 | const char *name; |
38 | Table *h; /* list for string reuse */ | 38 | Table *h; /* list for string reuse */ |
39 | lu_mem offset; /* current position relative to beginning of dump */ | ||
39 | lua_Integer nstr; /* number of strings in the list */ | 40 | lua_Integer nstr; /* number of strings in the list */ |
40 | } LoadState; | 41 | } LoadState; |
41 | 42 | ||
@@ -55,6 +56,17 @@ static l_noret error (LoadState *S, const char *why) { | |||
55 | static void loadBlock (LoadState *S, void *b, size_t size) { | 56 | static void loadBlock (LoadState *S, void *b, size_t size) { |
56 | if (luaZ_read(S->Z, b, size) != 0) | 57 | if (luaZ_read(S->Z, b, size) != 0) |
57 | error(S, "truncated chunk"); | 58 | error(S, "truncated chunk"); |
59 | S->offset += size; | ||
60 | } | ||
61 | |||
62 | |||
63 | static void loadAlign (LoadState *S, int align) { | ||
64 | int padding = align - (S->offset % align); | ||
65 | if (padding < align) { /* apd == align means no padding */ | ||
66 | lua_Integer paddingContent; | ||
67 | loadBlock(S, &paddingContent, padding); | ||
68 | lua_assert(S->offset % align == 0); | ||
69 | } | ||
58 | } | 70 | } |
59 | 71 | ||
60 | 72 | ||
@@ -65,6 +77,7 @@ static lu_byte loadByte (LoadState *S) { | |||
65 | int b = zgetc(S->Z); | 77 | int b = zgetc(S->Z); |
66 | if (b == EOZ) | 78 | if (b == EOZ) |
67 | error(S, "truncated chunk"); | 79 | error(S, "truncated chunk"); |
80 | S->offset++; | ||
68 | return cast_byte(b); | 81 | return cast_byte(b); |
69 | } | 82 | } |
70 | 83 | ||
@@ -158,6 +171,7 @@ static void loadCode (LoadState *S, Proto *f) { | |||
158 | int n = loadInt(S); | 171 | int n = loadInt(S); |
159 | f->code = luaM_newvectorchecked(S->L, n, Instruction); | 172 | f->code = luaM_newvectorchecked(S->L, n, Instruction); |
160 | f->sizecode = n; | 173 | f->sizecode = n; |
174 | loadAlign(S, sizeof(f->code[0])); | ||
161 | loadVector(S, f->code, n); | 175 | loadVector(S, f->code, n); |
162 | } | 176 | } |
163 | 177 | ||
@@ -321,7 +335,7 @@ static void checkHeader (LoadState *S) { | |||
321 | /* | 335 | /* |
322 | ** Load precompiled chunk. | 336 | ** Load precompiled chunk. |
323 | */ | 337 | */ |
324 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | 338 | LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name) { |
325 | LoadState S; | 339 | LoadState S; |
326 | LClosure *cl; | 340 | LClosure *cl; |
327 | if (*name == '@' || *name == '=') | 341 | if (*name == '@' || *name == '=') |
@@ -332,6 +346,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | |||
332 | S.name = name; | 346 | S.name = name; |
333 | S.L = L; | 347 | S.L = L; |
334 | S.Z = Z; | 348 | S.Z = Z; |
349 | S.offset = 1; /* fist byte was already read */ | ||
335 | checkHeader(&S); | 350 | checkHeader(&S); |
336 | cl = luaF_newLclosure(L, loadByte(&S)); | 351 | cl = luaF_newLclosure(L, loadByte(&S)); |
337 | setclLvalue2s(L, L->top.p, cl); | 352 | setclLvalue2s(L, L->top.p, cl); |