aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldump.c27
-rw-r--r--lundump.c21
-rw-r--r--testes/code.lua18
3 files changed, 48 insertions, 18 deletions
diff --git a/ldump.c b/ldump.c
index 79bb1dc9..a75b20d2 100644
--- a/ldump.c
+++ b/ldump.c
@@ -31,7 +31,7 @@ typedef struct {
31 int strip; 31 int strip;
32 int status; 32 int status;
33 Table *h; /* table to track saved strings */ 33 Table *h; /* table to track saved strings */
34 lua_Integer nstr; /* counter for counting saved strings */ 34 lua_Unsigned nstr; /* counter for counting saved strings */
35} DumpState; 35} DumpState;
36 36
37 37
@@ -87,12 +87,12 @@ static void dumpByte (DumpState *D, int y) {
87** size for 'dumpVarint' buffer: each byte can store up to 7 bits. 87** size for 'dumpVarint' buffer: each byte can store up to 7 bits.
88** (The "+6" rounds up the division.) 88** (The "+6" rounds up the division.)
89*/ 89*/
90#define DIBS ((l_numbits(size_t) + 6) / 7) 90#define DIBS ((l_numbits(lua_Unsigned) + 6) / 7)
91 91
92/* 92/*
93** Dumps an unsigned integer using the MSB Varint encoding 93** Dumps an unsigned integer using the MSB Varint encoding
94*/ 94*/
95static void dumpVarint (DumpState *D, size_t x) { 95static void dumpVarint (DumpState *D, lua_Unsigned x) {
96 lu_byte buff[DIBS]; 96 lu_byte buff[DIBS];
97 unsigned n = 1; 97 unsigned n = 1;
98 buff[DIBS - 1] = x & 0x7f; /* fill least-significant byte */ 98 buff[DIBS - 1] = x & 0x7f; /* fill least-significant byte */
@@ -103,12 +103,13 @@ static void dumpVarint (DumpState *D, size_t x) {
103 103
104 104
105static void dumpSize (DumpState *D, size_t sz) { 105static void dumpSize (DumpState *D, size_t sz) {
106 dumpVarint(D, sz); 106 dumpVarint(D, cast(lua_Unsigned, sz));
107} 107}
108 108
109
109static void dumpInt (DumpState *D, int x) { 110static void dumpInt (DumpState *D, int x) {
110 lua_assert(x >= 0); 111 lua_assert(x >= 0);
111 dumpVarint(D, cast_sizet(x)); 112 dumpVarint(D, cast_uint(x));
112} 113}
113 114
114 115
@@ -117,8 +118,16 @@ static void dumpNumber (DumpState *D, lua_Number x) {
117} 118}
118 119
119 120
121/*
122** Signed integers are coded to keep small values small. (Coding -1 as
123** 0xfff...fff would use too many bytes to save a quite common value.)
124** A non-negative x is coded as 2x; a negative x is coded as -2x - 1.
125** (0 => 0; -1 => 1; 1 => 2; -2 => 3; 2 => 4; ...)
126*/
120static void dumpInteger (DumpState *D, lua_Integer x) { 127static void dumpInteger (DumpState *D, lua_Integer x) {
121 dumpVar(D, x); 128 lua_Unsigned cx = (x >= 0) ? 2u * l_castS2U(x)
129 : (2u * ~l_castS2U(x)) + 1;
130 dumpVarint(D, cx);
122} 131}
123 132
124 133
@@ -136,8 +145,8 @@ static void dumpString (DumpState *D, TString *ts) {
136 TValue idx; 145 TValue idx;
137 int tag = luaH_getstr(D->h, ts, &idx); 146 int tag = luaH_getstr(D->h, ts, &idx);
138 if (!tagisempty(tag)) { /* string already saved? */ 147 if (!tagisempty(tag)) { /* string already saved? */
139 dumpSize(D, 1); /* reuse a saved string */ 148 dumpVarint(D, 1); /* reuse a saved string */
140 dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */ 149 dumpVarint(D, l_castS2U(ivalue(&idx))); /* index of saved string */
141 } 150 }
142 else { /* must write and save the string */ 151 else { /* must write and save the string */
143 TValue key, value; /* to save the string in the hash */ 152 TValue key, value; /* to save the string in the hash */
@@ -147,7 +156,7 @@ static void dumpString (DumpState *D, TString *ts) {
147 dumpVector(D, s, size + 1); /* include ending '\0' */ 156 dumpVector(D, s, size + 1); /* include ending '\0' */
148 D->nstr++; /* one more saved string */ 157 D->nstr++; /* one more saved string */
149 setsvalue(D->L, &key, ts); /* the string is the key */ 158 setsvalue(D->L, &key, ts); /* the string is the key */
150 setivalue(&value, D->nstr); /* its index is the value */ 159 setivalue(&value, l_castU2S(D->nstr)); /* its index is the value */
151 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */ 160 luaH_set(D->L, D->h, &key, &value); /* h[ts] = nstr */
152 /* integer value does not need barrier */ 161 /* integer value does not need barrier */
153 } 162 }
diff --git a/lundump.c b/lundump.c
index b69ec336..10528987 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
@@ -94,8 +94,8 @@ static lu_byte loadByte (LoadState *S) {
94} 94}
95 95
96 96
97static size_t loadVarint (LoadState *S, size_t limit) { 97static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
98 size_t x = 0; 98 lua_Unsigned x = 0;
99 int b; 99 int b;
100 limit >>= 7; 100 limit >>= 7;
101 do { 101 do {
@@ -127,9 +127,12 @@ static lua_Number loadNumber (LoadState *S) {
127 127
128 128
129static lua_Integer loadInteger (LoadState *S) { 129static lua_Integer loadInteger (LoadState *S) {
130 lua_Integer x; 130 lua_Unsigned cx = loadVarint(S, LUA_MAXUNSIGNED);
131 loadVar(S, x); 131 /* decode unsigned to signed */
132 return x; 132 if ((cx & 1) != 0)
133 return l_castU2S(~(cx >> 1));
134 else
135 return l_castU2S(cx >> 1);
133} 136}
134 137
135 138
@@ -149,9 +152,9 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
149 return; 152 return;
150 } 153 }
151 else if (size == 1) { /* previously saved string? */ 154 else if (size == 1) { /* previously saved string? */
152 lua_Integer idx = cast_st2S(loadSize(S)); /* get its index */ 155 lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED); /* get its index */
153 TValue stv; 156 TValue stv;
154 luaH_getint(S->h, idx, &stv); /* get its value */ 157 luaH_getint(S->h, l_castU2S(idx), &stv); /* get its value */
155 *sl = ts = tsvalue(&stv); 158 *sl = ts = tsvalue(&stv);
156 luaC_objbarrier(L, p, ts); 159 luaC_objbarrier(L, p, ts);
157 return; /* do not save it again */ 160 return; /* do not save it again */
@@ -175,7 +178,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
175 /* add string to list of saved strings */ 178 /* add string to list of saved strings */
176 S->nstr++; 179 S->nstr++;
177 setsvalue(L, &sv, ts); 180 setsvalue(L, &sv, ts);
178 luaH_setint(L, S->h, S->nstr, &sv); 181 luaH_setint(L, S->h, l_castU2S(S->nstr), &sv);
179 luaC_objbarrierback(L, obj2gco(S->h), ts); 182 luaC_objbarrierback(L, obj2gco(S->h), ts);
180} 183}
181 184
diff --git a/testes/code.lua b/testes/code.lua
index 633f4896..380ff70c 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -482,5 +482,23 @@ do -- basic check for SETLIST
482 assert(count == 1) 482 assert(count == 1)
483end 483end
484 484
485
486do print("testing code for integer limits")
487 local function checkints (n)
488 local source = string.format(
489 "local a = {[true] = 0X%x}; return a[true]", n)
490 local f = assert(load(source))
491 checkKlist(f, {n})
492 assert(f() == n)
493 f = load(string.dump(f))
494 assert(f() == n)
495 end
496
497 checkints(math.maxinteger)
498 checkints(math.mininteger)
499 checkints(-1)
500
501end
502
485print 'OK' 503print 'OK'
486 504