aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-03-26 11:50:19 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-03-26 11:50:19 -0300
commit439236773b9d36208375bb8eed251bcd393f7b24 (patch)
tree6946da44c969c715c09b9d3170e99dfd898d7c54
parent2a2b64d6ac2ea7839dac41cc84be1c7a5a18bee7 (diff)
downloadlua-439236773b9d36208375bb8eed251bcd393f7b24.tar.gz
lua-439236773b9d36208375bb8eed251bcd393f7b24.tar.bz2
lua-439236773b9d36208375bb8eed251bcd393f7b24.zip
changes by lhf
-rw-r--r--lundump.c251
-rw-r--r--lundump.h42
2 files changed, 143 insertions, 150 deletions
diff --git a/lundump.c b/lundump.c
index 32d7359a..37a53977 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.4 1998/01/13 20:05:24 lhf Exp $ 2** $Id: lundump.c,v 1.7 1998/03/05 15:45:08 lhf Exp lhf $
3** load bytecodes from files 3** load bytecodes from files
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,15 +11,31 @@
11#include "lstring.h" 11#include "lstring.h"
12#include "lundump.h" 12#include "lundump.h"
13 13
14typedef struct { 14#define LoadBlock(b,size,Z) ezread(Z,b,size)
15 ZIO* Z; 15#define LoadNative(t,D) LoadBlock(&t,sizeof(t),D)
16 int SwapNumber; 16
17 int LoadFloat; 17/* LUA_NUMBER */
18} Sundump; 18/* if you change the definition of real, make sure you set ID_NUMBER
19* accordingly lundump.h, specially if sizeof(long)!=4.
20* for types other than the ones listed below, you'll have to write your own
21* dump and undump routines.
22*/
23
24#if ID_NUMBER==ID_REAL4
25 #define LoadNumber LoadFloat
26#elif ID_NUMBER==ID_REAL8
27 #define LoadNumber LoadDouble
28#elif ID_NUMBER==ID_INT4
29 #define LoadNumber LoadLong
30#elif ID_NUMBER==ID_NATIVE
31 #define LoadNumber LoadNative
32#else
33 #define LoadNumber LoadWhat
34#endif
19 35
20static void unexpectedEOZ(ZIO* Z) 36static void unexpectedEOZ(ZIO* Z)
21{ 37{
22 luaL_verror("unexpected end of binary file %s",Z->name); 38 luaL_verror("unexpected end of file in %s",zname(Z));
23} 39}
24 40
25static int ezgetc(ZIO* Z) 41static int ezgetc(ZIO* Z)
@@ -29,91 +45,77 @@ static int ezgetc(ZIO* Z)
29 return c; 45 return c;
30} 46}
31 47
32static int ezread(ZIO* Z, void* b, int n) 48static void ezread(ZIO* Z, void* b, int n)
33{ 49{
34 int r=zread(Z,b,n); 50 int r=zread(Z,b,n);
35 if (r!=0) unexpectedEOZ(Z); 51 if (r!=0) unexpectedEOZ(Z);
36 return r;
37} 52}
38 53
39static int LoadWord(ZIO* Z) 54static unsigned int LoadWord(ZIO* Z)
40{ 55{
41 int hi=ezgetc(Z); 56 unsigned int hi=ezgetc(Z);
42 int lo=ezgetc(Z); 57 unsigned int lo=ezgetc(Z);
43 return (hi<<8)|lo; 58 return (hi<<8)|lo;
44} 59}
45 60
46static void* LoadBlock(int size, ZIO* Z) 61static unsigned long LoadLong(ZIO* Z)
47{ 62{
48 void* b=luaM_malloc(size); 63 unsigned long hi=LoadWord(Z);
49 ezread(Z,b,size); 64 unsigned long lo=LoadWord(Z);
50 return b; 65 return (hi<<16)|lo;
51} 66}
52 67
53static int LoadSize(ZIO* Z) 68/* LUA_NUMBER */
69/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
70static float LoadFloat(ZIO* Z)
54{ 71{
55 int hi=LoadWord(Z); 72 long l=LoadLong(Z);
56 int lo=LoadWord(Z); 73 float f=*(float*)&l;
57 int s=(hi<<16)|lo; 74 return f;
58 if (hi!=0 && s==lo)
59 luaL_verror("code too long (%ld bytes)",(hi<<16)|(long)lo);
60 return s;
61} 75}
62 76
63static char* LoadString(ZIO* Z) 77/* LUA_NUMBER */
78/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
79static double LoadDouble(ZIO* Z)
64{ 80{
65 int size=LoadWord(Z); 81 long l[2];
66 if (size==0) 82 double f;
67 return NULL; 83 int x=1;
68 else 84 if (*(char*)&x==1) /* little-endian */
69 { 85 {
70 char* b=luaL_openspace(size); 86 l[1]=LoadLong(Z);
71 ezread(Z,b,size); 87 l[0]=LoadLong(Z);
72 return b;
73 } 88 }
89 else /* big-endian */
90 {
91 l[0]=LoadLong(Z);
92 l[1]=LoadLong(Z);
93 }
94 f=*(double*)l;
95 return f;
74} 96}
75 97
76static TaggedString* LoadTString(ZIO* Z) 98static Byte* LoadCode(ZIO* Z)
77{
78 char* s=LoadString(Z);
79 return (s==NULL) ? NULL : luaS_new(s);
80}
81
82static void SwapFloat(float* f)
83{
84 Byte* p=(Byte*)f;
85 Byte* q=p+sizeof(float)-1;
86 Byte t;
87 t=*p; *p++=*q; *q--=t;
88 t=*p; *p++=*q; *q--=t;
89}
90
91static void SwapDouble(double* f)
92{ 99{
93 Byte* p=(Byte*)f; 100 long size=LoadLong(Z);
94 Byte* q=p+sizeof(double)-1; 101 unsigned int s=size;
95 Byte t; 102 void* b;
96 t=*p; *p++=*q; *q--=t; 103 if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
97 t=*p; *p++=*q; *q--=t; 104 b=luaM_malloc(size);
98 t=*p; *p++=*q; *q--=t; 105 LoadBlock(b,size,Z);
99 t=*p; *p++=*q; *q--=t; 106 return b;
100} 107}
101 108
102static real LoadNumber(Sundump* S) 109static TaggedString* LoadTString(ZIO* Z)
103{ 110{
104 if (S->LoadFloat) 111 int size=LoadWord(Z);
105 { 112 if (size==0)
106 float f; 113 return NULL;
107 ezread(S->Z,&f,sizeof(f));
108 if (S->SwapNumber) SwapFloat(&f);
109 return f;
110 }
111 else 114 else
112 { 115 {
113 double f; 116 char* s=luaL_openspace(size);
114 ezread(S->Z,&f,sizeof(f)); 117 LoadBlock(s,size,Z);
115 if (S->SwapNumber) SwapDouble(&f); 118 return luaS_newlstr(s,size-1);
116 return f;
117 } 119 }
118} 120}
119 121
@@ -131,63 +133,51 @@ static void LoadLocals(TProtoFunc* tf, ZIO* Z)
131 tf->locvars[i].varname=NULL; 133 tf->locvars[i].varname=NULL;
132} 134}
133 135
134static void LoadConstants(TProtoFunc* tf, Sundump* S) 136static TProtoFunc* LoadFunction(ZIO* Z);
137
138static void LoadConstants(TProtoFunc* tf, ZIO* Z)
135{ 139{
136 int i,n=LoadWord(S->Z); 140 int i,n=LoadWord(Z);
137 tf->nconsts=n; 141 tf->nconsts=n;
138 if (n==0) return; 142 if (n==0) return;
139 tf->consts=luaM_newvector(n,TObject); 143 tf->consts=luaM_newvector(n,TObject);
140 for (i=0; i<n; i++) 144 for (i=0; i<n; i++)
141 { 145 {
142 TObject* o=tf->consts+i; 146 TObject* o=tf->consts+i;
143 int c=ezgetc(S->Z); 147 int c=ezgetc(Z);
144 switch (c) 148 switch (c)
145 { 149 {
146 case ID_NUM: 150 case ID_NUM:
147 ttype(o)=LUA_T_NUMBER; 151 ttype(o)=LUA_T_NUMBER;
148 nvalue(o)=LoadNumber(S); 152#if ID_NUMBER==ID_NATIVE
153 LoadNative(nvalue(o),Z)
154#else
155 nvalue(o)=LoadNumber(Z);
156#endif
149 break; 157 break;
150 case ID_STR: 158 case ID_STR:
151 ttype(o)=LUA_T_STRING; 159 ttype(o)=LUA_T_STRING;
152 tsvalue(o)=LoadTString(S->Z); 160 tsvalue(o)=LoadTString(Z);
153 break; 161 break;
154 case ID_FUN: 162 case ID_FUN:
155 ttype(o)=LUA_T_PROTO; 163 ttype(o)=LUA_T_PROTO;
156 tfvalue(o)=NULL; 164 tfvalue(o)=LoadFunction(Z);
157 break; 165 break;
158#ifdef DEBUG 166 default:
159 default: /* cannot happen */ 167 luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c);
160 luaL_verror("internal error in LoadConstants: "
161 "bad constant #%d type=%d ('%c')\n",i,c,c);
162 break; 168 break;
163#endif
164 } 169 }
165 } 170 }
166} 171}
167 172
168static TProtoFunc* LoadFunction(Sundump* S); 173static TProtoFunc* LoadFunction(ZIO* Z)
169
170static void LoadFunctions(TProtoFunc* tf, Sundump* S)
171{
172 while (zgetc(S->Z)==ID_FUNCTION)
173 {
174 int i=LoadWord(S->Z);
175 TProtoFunc* t=LoadFunction(S);
176 TObject* o=tf->consts+i;
177 tfvalue(o)=t;
178 }
179}
180
181static TProtoFunc* LoadFunction(Sundump* S)
182{ 174{
183 ZIO* Z=S->Z;
184 TProtoFunc* tf=luaF_newproto(); 175 TProtoFunc* tf=luaF_newproto();
185 tf->lineDefined=LoadWord(Z); 176 tf->lineDefined=LoadWord(Z);
186 tf->fileName=LoadTString(Z); 177 tf->fileName=LoadTString(Z);
187 tf->code=LoadBlock(LoadSize(Z),Z); 178 tf->code=LoadCode(Z);
188 LoadConstants(tf,S);
189 LoadLocals(tf,Z); 179 LoadLocals(tf,Z);
190 LoadFunctions(tf,S); 180 LoadConstants(tf,Z);
191 return tf; 181 return tf;
192} 182}
193 183
@@ -196,61 +186,42 @@ static void LoadSignature(ZIO* Z)
196 char* s=SIGNATURE; 186 char* s=SIGNATURE;
197 while (*s!=0 && ezgetc(Z)==*s) 187 while (*s!=0 && ezgetc(Z)==*s)
198 ++s; 188 ++s;
199 if (*s!=0) luaL_verror("bad signature in binary file %s",Z->name); 189 if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
200} 190}
201 191
202static void LoadHeader(Sundump* S) 192static void LoadHeader(ZIO* Z)
203{ 193{
204 ZIO* Z=S->Z; 194 int version,id,sizeofR;
205 int version,sizeofR; 195 real f=-TEST_NUMBER,tf=TEST_NUMBER;
206 LoadSignature(Z); 196 LoadSignature(Z);
207 version=ezgetc(Z); 197 version=ezgetc(Z);
208 if (version>VERSION) 198 if (version>VERSION)
209 luaL_verror( 199 luaL_verror(
210 "binary file %s too new: version=0x%02x; expected at most 0x%02x", 200 "%s too new: version=0x%02x; expected at most 0x%02x",
211 Z->name,version,VERSION); 201 zname(Z),version,VERSION);
212 if (version<0x31) /* major change in 3.1 */ 202 if (version<0x31) /* major change in 3.1 */
213 luaL_verror( 203 luaL_verror(
214 "binary file %s too old: version=0x%02x; expected at least 0x%02x", 204 "%s too old: version=0x%02x; expected at least 0x%02x",
215 Z->name,version,0x31); 205 zname(Z),version,0x31);
216 sizeofR=ezgetc(Z); /* test float representation */ 206 id=ezgetc(Z); /* test number representation */
217 if (sizeofR==sizeof(float)) 207 sizeofR=ezgetc(Z);
208 if (id!=ID_NUMBER || sizeofR!=sizeof(real))
218 { 209 {
219 float f,tf=TEST_FLOAT; 210 luaL_verror("unknown number representation in %s: "
220 ezread(Z,&f,sizeof(f)); 211 "read 0x%02x %d; expected 0x%02x %d",
221 if (f!=tf) 212 zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
222 {
223 SwapFloat(&f);
224 if (f!=tf)
225 luaL_verror("unknown float representation in binary file %s",Z->name);
226 S->SwapNumber=1;
227 }
228 S->LoadFloat=1;
229 } 213 }
230 else if (sizeofR==sizeof(double)) 214 f=LoadNumber(Z);
231 { 215 if (f!=tf)
232 double f,tf=TEST_FLOAT; 216 luaL_verror("unknown number representation in %s: "
233 ezread(Z,&f,sizeof(f)); 217 "read %g; expected %g", /* LUA_NUMBER */
234 if (f!=tf) 218 zname(Z),(double)f,(double)tf);
235 {
236 SwapDouble(&f);
237 if (f!=tf)
238 luaL_verror("unknown float representation in binary file %s",Z->name);
239 S->SwapNumber=1;
240 }
241 S->LoadFloat=0;
242 }
243 else
244 luaL_verror(
245 "floats in binary file %s have %d bytes; "
246 "expected %d (float) or %d (double)",
247 Z->name,sizeofR,sizeof(float),sizeof(double));
248} 219}
249 220
250static TProtoFunc* LoadChunk(Sundump* S) 221static TProtoFunc* LoadChunk(ZIO* Z)
251{ 222{
252 LoadHeader(S); 223 LoadHeader(Z);
253 return LoadFunction(S); 224 return LoadFunction(Z);
254} 225}
255 226
256/* 227/*
@@ -260,13 +231,9 @@ static TProtoFunc* LoadChunk(Sundump* S)
260TProtoFunc* luaU_undump1(ZIO* Z) 231TProtoFunc* luaU_undump1(ZIO* Z)
261{ 232{
262 int c=zgetc(Z); 233 int c=zgetc(Z);
263 Sundump S;
264 S.Z=Z;
265 S.SwapNumber=0;
266 S.LoadFloat=1;
267 if (c==ID_CHUNK) 234 if (c==ID_CHUNK)
268 return LoadChunk(&S); 235 return LoadChunk(Z);
269 else if (c!=EOZ) 236 else if (c!=EOZ)
270 luaL_verror("%s is not a lua binary file",Z->name); 237 luaL_verror("%s is not a Lua binary file",zname(Z));
271 return NULL; 238 return NULL;
272} 239}
diff --git a/lundump.h b/lundump.h
index ea9e975c..7e5b286c 100644
--- a/lundump.h
+++ b/lundump.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.h,v 1.4 1998/01/13 20:05:24 lhf Exp $ 2** $Id: lundump.h,v 1.5 1998/02/06 20:05:39 lhf Exp lhf $
3** load pre-compiled Lua chunks 3** load pre-compiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,18 +10,44 @@
10#include "lobject.h" 10#include "lobject.h"
11#include "lzio.h" 11#include "lzio.h"
12 12
13TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
14
15#define SIGNATURE "Lua"
16#define VERSION 0x31 /* last format change was in 3.1 */
17
18#define IsMain(f) (f->lineDefined==0)
19
13#define ID_CHUNK 27 /* ESC */ 20#define ID_CHUNK 27 /* ESC */
14#define ID_FUNCTION '#'
15#define ID_END '$'
16#define ID_NUM 'N' 21#define ID_NUM 'N'
17#define ID_STR 'S' 22#define ID_STR 'S'
18#define ID_FUN 'F' 23#define ID_FUN 'F'
19#define SIGNATURE "Lua"
20#define VERSION 0x31 /* last format change was in 3.1 */
21#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
22 24
23#define IsMain(f) (f->lineDefined==0) 25#define ID_INT4 'l'
26#define ID_REAL4 'f'
27#define ID_REAL8 'd'
28#define ID_NATIVE '?'
24 29
25TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */ 30/*
31* use a multiple of PI for testing number representation.
32* multiplying by 10E8 gives notrivial integer values.
33*/
34#define TEST_NUMBER 3.14159265358979323846E8
35
36/* LUA_NUMBER */
37/* if you change the definition of real, make sure you set ID_NUMBER
38* accordingly, specially if sizeof(long)!=4.
39* for types other than the ones listed below, you'll have to write your own
40* dump and undump routines.
41*/
42
43#if real==float
44 #define ID_NUMBER ID_REAL4
45#elif real==double
46 #define ID_NUMBER ID_REAL8
47#elif real==long
48 #define ID_NUMBER ID_INT4
49#else
50 #define ID_NUMBER ID_NATIVE
51#endif
26 52
27#endif 53#endif