aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-02-12 15:16:11 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-02-12 15:16:11 -0300
commitc8121ce34b39c6fd31899f4da91e26063c8af54f (patch)
tree5ce96fbe65d5f16f87c816f88bab2df25975ba5d
parent7360f8d0fd91344deb583ff76b8250a1883dcd4c (diff)
downloadlua-c8121ce34b39c6fd31899f4da91e26063c8af54f.tar.gz
lua-c8121ce34b39c6fd31899f4da91e26063c8af54f.tar.bz2
lua-c8121ce34b39c6fd31899f4da91e26063c8af54f.zip
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.
Diffstat (limited to '')
-rw-r--r--ldump.c35
-rw-r--r--lundump.c24
-rw-r--r--lundump.h15
3 files changed, 45 insertions, 29 deletions
diff --git a/ldump.c b/ldump.c
index b31e7bc7..34cfb576 100644
--- a/ldump.c
+++ b/ldump.c
@@ -30,7 +30,7 @@ typedef struct {
30 int strip; 30 int strip;
31 int status; 31 int status;
32 Table *h; /* table to track saved strings */ 32 Table *h; /* table to track saved strings */
33 lua_Integer nstr; /* counter to number saved strings */ 33 lua_Unsigned nstr; /* counter to number saved strings */
34} DumpState; 34} DumpState;
35 35
36 36
@@ -83,26 +83,27 @@ static void dumpByte (DumpState *D, int y) {
83 83
84 84
85/* 85/*
86** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6" 86** size for 'dumpVarint' buffer: each byte can store up to 7 bits.
87** rounds up the division.) 87** (The "+6" rounds up the division.)
88*/ 88*/
89#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7) 89#define DIBS ((sizeof(varint_t) * CHAR_BIT + 6) / 7)
90 90
91static void dumpSize (DumpState *D, size_t x) { 91/*
92** Dumps an unsigned integer using the MSB Varint encoding
93*/
94static void dumpVarint (DumpState *D, varint_t x) {
92 lu_byte buff[DIBS]; 95 lu_byte buff[DIBS];
93 int n = 0; 96 int n = 1;
94 do { 97 buff[DIBS - 1] = x & 0x7f; /* fill least-significant byte */
95 buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 98 while ((x >>= 7) != 0) /* fill other bytes in reverse order */
96 x >>= 7; 99 buff[DIBS - (++n)] = (x & 0x7f) | 0x80;
97 } while (x != 0);
98 buff[DIBS - 1] |= 0x80; /* mark last byte */
99 dumpVector(D, buff + DIBS - n, n); 100 dumpVector(D, buff + DIBS - n, n);
100} 101}
101 102
102 103
103static void dumpInt (DumpState *D, int x) { 104static void dumpInt (DumpState *D, int x) {
104 lua_assert(x >= 0); 105 lua_assert(x >= 0);
105 dumpSize(D, x); 106 dumpVarint(D, x);
106} 107}
107 108
108 109
@@ -125,22 +126,22 @@ static void dumpInteger (DumpState *D, lua_Integer x) {
125*/ 126*/
126static void dumpString (DumpState *D, TString *ts) { 127static void dumpString (DumpState *D, TString *ts) {
127 if (ts == NULL) 128 if (ts == NULL)
128 dumpSize(D, 0); 129 dumpVarint(D, 0);
129 else { 130 else {
130 TValue idx; 131 TValue idx;
131 if (luaH_getstr(D->h, ts, &idx) == HOK) { /* string already saved? */ 132 if (luaH_getstr(D->h, ts, &idx) == HOK) { /* string already saved? */
132 dumpSize(D, 1); /* reuse a saved string */ 133 dumpVarint(D, 1); /* reuse a saved string */
133 dumpInt(D, ivalue(&idx)); /* index of saved string */ 134 dumpVarint(D, l_castS2U(ivalue(&idx))); /* index of saved string */
134 } 135 }
135 else { /* must write and save the string */ 136 else { /* must write and save the string */
136 TValue key, value; /* to save the string in the hash */ 137 TValue key, value; /* to save the string in the hash */
137 size_t size; 138 size_t size;
138 const char *s = getlstr(ts, size); 139 const char *s = getlstr(ts, size);
139 dumpSize(D, size + 2); 140 dumpVarint(D, size + 2);
140 dumpVector(D, s, size + 1); /* include ending '\0' */ 141 dumpVector(D, s, size + 1); /* include ending '\0' */
141 D->nstr++; /* one more saved string */ 142 D->nstr++; /* one more saved string */
142 setsvalue(D->L, &key, ts); /* the string is the key */ 143 setsvalue(D->L, &key, ts); /* the string is the key */
143 setivalue(&value, D->nstr); /* its index is the value */ 144 setivalue(&value, l_castU2S(D->nstr)); /* its index is the value */
144 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */ 145 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */
145 /* integer value does not need barrier */ 146 /* integer value does not need barrier */
146 } 147 }
diff --git a/lundump.c b/lundump.c
index b33258b0..d485f266 100644
--- a/lundump.c
+++ b/lundump.c
@@ -37,7 +37,7 @@ typedef struct {
37 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */ 38 Table *h; /* list for string reuse */
39 size_t offset; /* current position relative to beginning of dump */ 39 size_t offset; /* current position relative to beginning of dump */
40 lua_Integer nstr; /* number of strings in the list */ 40 lua_Unsigned nstr; /* number of strings in the list */
41 lu_byte fixed; /* dump is fixed in memory */ 41 lu_byte fixed; /* dump is fixed in memory */
42} LoadState; 42} LoadState;
43 43
@@ -71,10 +71,9 @@ static void loadAlign (LoadState *S, int align) {
71} 71}
72 72
73 73
74#define getaddr(S,n,t) cast(t *, getaddr_(S,n,sizeof(t))) 74#define getaddr(S,n,t) cast(t *, getaddr_(S,(n) * sizeof(t)))
75 75
76static const void *getaddr_ (LoadState *S, int n, size_t sz) { 76static const void *getaddr_ (LoadState *S, size_t size) {
77 size_t size = n * sz;
78 const void *block = luaZ_getaddr(S->Z, size); 77 const void *block = luaZ_getaddr(S->Z, size);
79 S->offset += size; 78 S->offset += size;
80 if (block == NULL) 79 if (block == NULL)
@@ -95,8 +94,8 @@ static lu_byte loadByte (LoadState *S) {
95} 94}
96 95
97 96
98static size_t loadUnsigned (LoadState *S, size_t limit) { 97static varint_t loadVarint (LoadState *S, varint_t limit) {
99 size_t x = 0; 98 varint_t x = 0;
100 int b; 99 int b;
101 limit >>= 7; 100 limit >>= 7;
102 do { 101 do {
@@ -104,18 +103,18 @@ static size_t loadUnsigned (LoadState *S, size_t limit) {
104 if (x >= limit) 103 if (x >= limit)
105 error(S, "integer overflow"); 104 error(S, "integer overflow");
106 x = (x << 7) | (b & 0x7f); 105 x = (x << 7) | (b & 0x7f);
107 } while ((b & 0x80) == 0); 106 } while ((b & 0x80) != 0);
108 return x; 107 return x;
109} 108}
110 109
111 110
112static size_t loadSize (LoadState *S) { 111static size_t loadSize (LoadState *S) {
113 return loadUnsigned(S, MAX_SIZET); 112 return cast_sizet(loadVarint(S, MAX_SIZET));
114} 113}
115 114
116 115
117static int loadInt (LoadState *S) { 116static int loadInt (LoadState *S) {
118 return cast_int(loadUnsigned(S, INT_MAX)); 117 return cast_int(loadVarint(S, INT_MAX));
119} 118}
120 119
121 120
@@ -149,9 +148,10 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
149 return; 148 return;
150 } 149 }
151 else if (size == 1) { /* previously saved string? */ 150 else if (size == 1) { /* previously saved string? */
152 int idx = loadInt(S); /* get its index */ 151 /* get its index */
152 lua_Unsigned idx = cast(lua_Unsigned, loadVarint(S, LUA_MAXUNSIGNED));
153 TValue stv; 153 TValue stv;
154 luaH_getint(S->h, idx, &stv); 154 luaH_getint(S->h, l_castU2S(idx), &stv); /* get its value */
155 *sl = ts = tsvalue(&stv); 155 *sl = ts = tsvalue(&stv);
156 luaC_objbarrier(L, p, ts); 156 luaC_objbarrier(L, p, ts);
157 return; /* do not save it again */ 157 return; /* do not save it again */
@@ -175,7 +175,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
175 /* add string to list of saved strings */ 175 /* add string to list of saved strings */
176 S->nstr++; 176 S->nstr++;
177 setsvalue(L, &sv, ts); 177 setsvalue(L, &sv, ts);
178 luaH_setint(L, S->h, S->nstr, &sv); 178 luaH_setint(L, S->h, l_castU2S(S->nstr), &sv);
179 luaC_objbarrierback(L, obj2gco(S->h), ts); 179 luaC_objbarrierback(L, obj2gco(S->h), ts);
180} 180}
181 181
diff --git a/lundump.h b/lundump.h
index b10307e4..ff66d2e7 100644
--- a/lundump.h
+++ b/lundump.h
@@ -7,6 +7,8 @@
7#ifndef lundump_h 7#ifndef lundump_h
8#define lundump_h 8#define lundump_h
9 9
10#include <limits.h>
11
10#include "llimits.h" 12#include "llimits.h"
11#include "lobject.h" 13#include "lobject.h"
12#include "lzio.h" 14#include "lzio.h"
@@ -25,6 +27,19 @@
25 27
26#define LUAC_FORMAT 0 /* this is the official format */ 28#define LUAC_FORMAT 0 /* this is the official format */
27 29
30
31/*
32** Type to handle MSB Varint encoding: Try to get the largest unsigned
33** integer available. (It was enough to be the largest between size_t and
34** lua_Integer, but the C89 preprocessor knows nothing about size_t.)
35*/
36#if !defined(LUA_USE_C89) && defined(LLONG_MAX)
37typedef unsigned long long varint_t;
38#else
39typedef unsigned long varint_t;
40#endif
41
42
28/* load one chunk; from lundump.c */ 43/* load one chunk; from lundump.c */
29LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name, 44LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name,
30 int fixed); 45 int fixed);