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
| -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); |
