Browse Source

Opcode in dumps is stored properly aligned

Roberto Ierusalimschy 1 year ago
parent
commit
0554581605
2 changed files with 30 additions and 1 deletions
  1. 14 0
      ldump.c
  2. 16 1
      lundump.c

+ 14 - 0
ldump.c

@@ -26,6 +26,7 @@ typedef struct {
   lua_State *L;
   lua_Writer writer;
   void *data;
+  lu_mem offset;  /* current position relative to beginning of dump */
   int strip;
   int status;
   Table *h;  /* table to track saved strings */
@@ -47,6 +48,17 @@ static void dumpBlock (DumpState *D, const void *b, size_t size) {
     lua_unlock(D->L);
     D->status = (*D->writer)(D->L, b, size, D->data);
     lua_lock(D->L);
+    D->offset += size;
+  }
+}
+
+
+static void dumpAlign (DumpState *D, int align) {
+  int padding = align - (D->offset % align);
+  if (padding < align) {  /* apd == align means no padding */
+    static lua_Integer paddingContent = 0;
+    dumpBlock(D, &paddingContent, padding);
+    lua_assert(D->offset % align == 0);
   }
 }
 
@@ -126,6 +138,7 @@ static void dumpString (DumpState *D, TString *s) {
 
 static void dumpCode (DumpState *D, const Proto *f) {
   dumpInt(D, f->sizecode);
+  dumpAlign(D, sizeof(f->code[0]));
   dumpVector(D, f->code, f->sizecode);
 }
 
@@ -242,6 +255,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
   DumpState D;
   D.L = L;
   D.writer = w;
+  D.offset = 0;
   D.data = data;
   D.strip = strip;
   D.status = 0;

+ 16 - 1
lundump.c

@@ -36,6 +36,7 @@ typedef struct {
   ZIO *Z;
   const char *name;
   Table *h;  /* list for string reuse */
+  lu_mem offset;  /* current position relative to beginning of dump */
   lua_Integer nstr;  /* number of strings in the list */
 } LoadState;
 
@@ -55,6 +56,17 @@ static l_noret error (LoadState *S, const char *why) {
 static void loadBlock (LoadState *S, void *b, size_t size) {
   if (luaZ_read(S->Z, b, size) != 0)
     error(S, "truncated chunk");
+  S->offset += size;
+}
+
+
+static void loadAlign (LoadState *S, int align) {
+  int padding = align - (S->offset % align);
+  if (padding < align) {  /* apd == align means no padding */
+    lua_Integer paddingContent;
+    loadBlock(S, &paddingContent, padding);
+    lua_assert(S->offset % align == 0);
+  }
 }
 
 
@@ -65,6 +77,7 @@ static lu_byte loadByte (LoadState *S) {
   int b = zgetc(S->Z);
   if (b == EOZ)
     error(S, "truncated chunk");
+  S->offset++;
   return cast_byte(b);
 }
 
@@ -158,6 +171,7 @@ static void loadCode (LoadState *S, Proto *f) {
   int n = loadInt(S);
   f->code = luaM_newvectorchecked(S->L, n, Instruction);
   f->sizecode = n;
+  loadAlign(S, sizeof(f->code[0]));
   loadVector(S, f->code, n);
 }
 
@@ -321,7 +335,7 @@ static void checkHeader (LoadState *S) {
 /*
 ** Load precompiled chunk.
 */
-LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
+LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name) {
   LoadState S;
   LClosure *cl;
   if (*name == '@' || *name == '=')
@@ -332,6 +346,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
     S.name = name;
   S.L = L;
   S.Z = Z;
+  S.offset = 1;  /* fist byte was already read */
   checkHeader(&S);
   cl = luaF_newLclosure(L, loadByte(&S));
   setclLvalue2s(L, L->top.p, cl);