2
0
Эх сурвалжийг харах

Revising code for Varint encoding in dumps

- Usign lua_Unsigned to count strings.
- Varint uses a type large enough both for size_t and lua_Unsigned.
- Most-Significant Bit 0 means last byte, to conform to common usage.
- (unrelated) Change in macro 'getaddr' so that multiplication is
  by constants.
Roberto Ierusalimschy 1 жил өмнө
parent
commit
c8121ce34b
3 өөрчлөгдсөн 45 нэмэгдсэн , 29 устгасан
  1. 18 17
      ldump.c
  2. 12 12
      lundump.c
  3. 15 0
      lundump.h

+ 18 - 17
ldump.c

@@ -30,7 +30,7 @@ typedef struct {
   int strip;
   int status;
   Table *h;  /* table to track saved strings */
-  lua_Integer nstr;  /* counter to number saved strings */
+  lua_Unsigned nstr;  /* counter to number saved strings */
 } DumpState;
 
 
@@ -83,26 +83,27 @@ static void dumpByte (DumpState *D, int y) {
 
 
 /*
-** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
-** rounds up the division.)
+** size for 'dumpVarint' buffer: each byte can store up to 7 bits.
+** (The "+6" rounds up the division.)
 */
-#define DIBS    ((sizeof(size_t) * CHAR_BIT + 6) / 7)
+#define DIBS    ((sizeof(varint_t) * CHAR_BIT + 6) / 7)
 
-static void dumpSize (DumpState *D, size_t x) {
+/*
+** Dumps an unsigned integer using the MSB Varint encoding
+*/
+static void dumpVarint (DumpState *D, varint_t x) {
   lu_byte buff[DIBS];
-  int n = 0;
-  do {
-    buff[DIBS - (++n)] = x & 0x7f;  /* fill buffer in reverse order */
-    x >>= 7;
-  } while (x != 0);
-  buff[DIBS - 1] |= 0x80;  /* mark last byte */
+  int n = 1;
+  buff[DIBS - 1] = x & 0x7f;  /* fill least-significant byte */
+  while ((x >>= 7) != 0)  /* fill other bytes in reverse order */
+    buff[DIBS - (++n)] = (x & 0x7f) | 0x80;
   dumpVector(D, buff + DIBS - n, n);
 }
 
 
 static void dumpInt (DumpState *D, int x) {
   lua_assert(x >= 0);
-  dumpSize(D, x);
+  dumpVarint(D, x);
 }
 
 
@@ -125,22 +126,22 @@ static void dumpInteger (DumpState *D, lua_Integer x) {
 */
 static void dumpString (DumpState *D, TString *ts) {
   if (ts == NULL)
-    dumpSize(D, 0);
+    dumpVarint(D, 0);
   else {
     TValue idx;
     if (luaH_getstr(D->h, ts, &idx) == HOK) {  /* string already saved? */
-      dumpSize(D, 1);  /* reuse a saved string */
-      dumpInt(D, ivalue(&idx));  /* index of saved string */
+      dumpVarint(D, 1);  /* reuse a saved string */
+      dumpVarint(D, l_castS2U(ivalue(&idx)));  /* index of saved string */
     }
     else {  /* must write and save the string */
       TValue key, value;  /* to save the string in the hash */
       size_t size;
       const char *s = getlstr(ts, size);
-      dumpSize(D, size + 2);
+      dumpVarint(D, size + 2);
       dumpVector(D, s, size + 1);  /* include ending '\0' */
       D->nstr++;  /* one more saved string */
       setsvalue(D->L, &key, ts);  /* the string is the key */
-      setivalue(&value, D->nstr);  /* its index is the value */
+      setivalue(&value, l_castU2S(D->nstr));  /* its index is the value */
       luaH_set(D->L, D->h, &key, &value);  /* h[ts] = nstr */
       /* integer value does not need barrier */
     }

+ 12 - 12
lundump.c

@@ -37,7 +37,7 @@ typedef struct {
   const char *name;
   Table *h;  /* list for string reuse */
   size_t offset;  /* current position relative to beginning of dump */
-  lua_Integer nstr;  /* number of strings in the list */
+  lua_Unsigned nstr;  /* number of strings in the list */
   lu_byte fixed;  /* dump is fixed in memory */
 } LoadState;
 
@@ -71,10 +71,9 @@ static void loadAlign (LoadState *S, int align) {
 }
 
 
-#define getaddr(S,n,t)	cast(t *, getaddr_(S,n,sizeof(t)))
+#define getaddr(S,n,t)	cast(t *, getaddr_(S,(n) * sizeof(t)))
 
-static const void *getaddr_ (LoadState *S, int n, size_t sz) {
-  size_t size = n * sz;
+static const void *getaddr_ (LoadState *S, size_t size) {
   const void *block = luaZ_getaddr(S->Z, size);
   S->offset += size;
   if (block == NULL)
@@ -95,8 +94,8 @@ static lu_byte loadByte (LoadState *S) {
 }
 
 
-static size_t loadUnsigned (LoadState *S, size_t limit) {
-  size_t x = 0;
+static varint_t loadVarint (LoadState *S, varint_t limit) {
+  varint_t x = 0;
   int b;
   limit >>= 7;
   do {
@@ -104,18 +103,18 @@ static size_t loadUnsigned (LoadState *S, size_t limit) {
     if (x >= limit)
       error(S, "integer overflow");
     x = (x << 7) | (b & 0x7f);
-  } while ((b & 0x80) == 0);
+  } while ((b & 0x80) != 0);
   return x;
 }
 
 
 static size_t loadSize (LoadState *S) {
-  return loadUnsigned(S, MAX_SIZET);
+  return cast_sizet(loadVarint(S, MAX_SIZET));
 }
 
 
 static int loadInt (LoadState *S) {
-  return cast_int(loadUnsigned(S, INT_MAX));
+  return cast_int(loadVarint(S, INT_MAX));
 }
 
 
@@ -149,9 +148,10 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
     return;
   }
   else if (size == 1) {  /* previously saved string? */
-    int idx = loadInt(S);  /* get its index */
+    /* get its index */
+    lua_Unsigned idx = cast(lua_Unsigned, loadVarint(S, LUA_MAXUNSIGNED));
     TValue stv;
-    luaH_getint(S->h, idx, &stv);
+    luaH_getint(S->h, l_castU2S(idx), &stv);  /* get its value */
     *sl = ts = tsvalue(&stv);
     luaC_objbarrier(L, p, ts);
     return;  /* do not save it again */
@@ -175,7 +175,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
   /* add string to list of saved strings */
   S->nstr++;
   setsvalue(L, &sv, ts);
-  luaH_setint(L, S->h, S->nstr, &sv);
+  luaH_setint(L, S->h, l_castU2S(S->nstr), &sv);
   luaC_objbarrierback(L, obj2gco(S->h), ts);
 }
 

+ 15 - 0
lundump.h

@@ -7,6 +7,8 @@
 #ifndef lundump_h
 #define lundump_h
 
+#include <limits.h>
+
 #include "llimits.h"
 #include "lobject.h"
 #include "lzio.h"
@@ -25,6 +27,19 @@
 
 #define LUAC_FORMAT	0	/* this is the official format */
 
+
+/*
+** Type to handle MSB Varint encoding: Try to get the largest unsigned
+** integer available. (It was enough to be the largest between size_t and
+** lua_Integer, but the C89 preprocessor knows nothing about size_t.)
+*/
+#if !defined(LUA_USE_C89) && defined(LLONG_MAX)
+typedef unsigned long long varint_t;
+#else
+typedef unsigned long varint_t;
+#endif
+
+
 /* load one chunk; from lundump.c */
 LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name,
                                                int fixed);