aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-01-14 13:49:01 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-01-14 13:49:01 -0200
commit981fddea022b6cad7768223353b4e7386080c271 (patch)
treec596f191df4b59c85ea056fca3933ad1f14e984b
parent81b953f27e2c218e9d772cc5f653f541c451d516 (diff)
downloadlua-981fddea022b6cad7768223353b4e7386080c271.tar.gz
lua-981fddea022b6cad7768223353b4e7386080c271.tar.bz2
lua-981fddea022b6cad7768223353b4e7386080c271.zip
module to load bytecodes from files.v3.1-alpha
-rw-r--r--lundump.c272
-rw-r--r--lundump.h27
-rw-r--r--undump.c318
-rw-r--r--undump.h30
4 files changed, 299 insertions, 348 deletions
diff --git a/lundump.c b/lundump.c
new file mode 100644
index 00000000..32d7359a
--- /dev/null
+++ b/lundump.c
@@ -0,0 +1,272 @@
1/*
2** $Id: lundump.c,v 1.4 1998/01/13 20:05:24 lhf Exp $
3** load bytecodes from files
4** See Copyright Notice in lua.h
5*/
6
7#include <stdio.h>
8#include "lauxlib.h"
9#include "lfunc.h"
10#include "lmem.h"
11#include "lstring.h"
12#include "lundump.h"
13
14typedef struct {
15 ZIO* Z;
16 int SwapNumber;
17 int LoadFloat;
18} Sundump;
19
20static void unexpectedEOZ(ZIO* Z)
21{
22 luaL_verror("unexpected end of binary file %s",Z->name);
23}
24
25static int ezgetc(ZIO* Z)
26{
27 int c=zgetc(Z);
28 if (c==EOZ) unexpectedEOZ(Z);
29 return c;
30}
31
32static int ezread(ZIO* Z, void* b, int n)
33{
34 int r=zread(Z,b,n);
35 if (r!=0) unexpectedEOZ(Z);
36 return r;
37}
38
39static int LoadWord(ZIO* Z)
40{
41 int hi=ezgetc(Z);
42 int lo=ezgetc(Z);
43 return (hi<<8)|lo;
44}
45
46static void* LoadBlock(int size, ZIO* Z)
47{
48 void* b=luaM_malloc(size);
49 ezread(Z,b,size);
50 return b;
51}
52
53static int LoadSize(ZIO* Z)
54{
55 int hi=LoadWord(Z);
56 int lo=LoadWord(Z);
57 int s=(hi<<16)|lo;
58 if (hi!=0 && s==lo)
59 luaL_verror("code too long (%ld bytes)",(hi<<16)|(long)lo);
60 return s;
61}
62
63static char* LoadString(ZIO* Z)
64{
65 int size=LoadWord(Z);
66 if (size==0)
67 return NULL;
68 else
69 {
70 char* b=luaL_openspace(size);
71 ezread(Z,b,size);
72 return b;
73 }
74}
75
76static TaggedString* LoadTString(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{
93 Byte* p=(Byte*)f;
94 Byte* q=p+sizeof(double)-1;
95 Byte t;
96 t=*p; *p++=*q; *q--=t;
97 t=*p; *p++=*q; *q--=t;
98 t=*p; *p++=*q; *q--=t;
99 t=*p; *p++=*q; *q--=t;
100}
101
102static real LoadNumber(Sundump* S)
103{
104 if (S->LoadFloat)
105 {
106 float f;
107 ezread(S->Z,&f,sizeof(f));
108 if (S->SwapNumber) SwapFloat(&f);
109 return f;
110 }
111 else
112 {
113 double f;
114 ezread(S->Z,&f,sizeof(f));
115 if (S->SwapNumber) SwapDouble(&f);
116 return f;
117 }
118}
119
120static void LoadLocals(TProtoFunc* tf, ZIO* Z)
121{
122 int i,n=LoadWord(Z);
123 if (n==0) return;
124 tf->locvars=luaM_newvector(n+1,LocVar);
125 for (i=0; i<n; i++)
126 {
127 tf->locvars[i].line=LoadWord(Z);
128 tf->locvars[i].varname=LoadTString(Z);
129 }
130 tf->locvars[i].line=-1; /* flag end of vector */
131 tf->locvars[i].varname=NULL;
132}
133
134static void LoadConstants(TProtoFunc* tf, Sundump* S)
135{
136 int i,n=LoadWord(S->Z);
137 tf->nconsts=n;
138 if (n==0) return;
139 tf->consts=luaM_newvector(n,TObject);
140 for (i=0; i<n; i++)
141 {
142 TObject* o=tf->consts+i;
143 int c=ezgetc(S->Z);
144 switch (c)
145 {
146 case ID_NUM:
147 ttype(o)=LUA_T_NUMBER;
148 nvalue(o)=LoadNumber(S);
149 break;
150 case ID_STR:
151 ttype(o)=LUA_T_STRING;
152 tsvalue(o)=LoadTString(S->Z);
153 break;
154 case ID_FUN:
155 ttype(o)=LUA_T_PROTO;
156 tfvalue(o)=NULL;
157 break;
158#ifdef DEBUG
159 default: /* cannot happen */
160 luaL_verror("internal error in LoadConstants: "
161 "bad constant #%d type=%d ('%c')\n",i,c,c);
162 break;
163#endif
164 }
165 }
166}
167
168static TProtoFunc* LoadFunction(Sundump* S);
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{
183 ZIO* Z=S->Z;
184 TProtoFunc* tf=luaF_newproto();
185 tf->lineDefined=LoadWord(Z);
186 tf->fileName=LoadTString(Z);
187 tf->code=LoadBlock(LoadSize(Z),Z);
188 LoadConstants(tf,S);
189 LoadLocals(tf,Z);
190 LoadFunctions(tf,S);
191 return tf;
192}
193
194static void LoadSignature(ZIO* Z)
195{
196 char* s=SIGNATURE;
197 while (*s!=0 && ezgetc(Z)==*s)
198 ++s;
199 if (*s!=0) luaL_verror("bad signature in binary file %s",Z->name);
200}
201
202static void LoadHeader(Sundump* S)
203{
204 ZIO* Z=S->Z;
205 int version,sizeofR;
206 LoadSignature(Z);
207 version=ezgetc(Z);
208 if (version>VERSION)
209 luaL_verror(
210 "binary file %s too new: version=0x%02x; expected at most 0x%02x",
211 Z->name,version,VERSION);
212 if (version<0x31) /* major change in 3.1 */
213 luaL_verror(
214 "binary file %s too old: version=0x%02x; expected at least 0x%02x",
215 Z->name,version,0x31);
216 sizeofR=ezgetc(Z); /* test float representation */
217 if (sizeofR==sizeof(float))
218 {
219 float f,tf=TEST_FLOAT;
220 ezread(Z,&f,sizeof(f));
221 if (f!=tf)
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 }
230 else if (sizeofR==sizeof(double))
231 {
232 double f,tf=TEST_FLOAT;
233 ezread(Z,&f,sizeof(f));
234 if (f!=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}
249
250static TProtoFunc* LoadChunk(Sundump* S)
251{
252 LoadHeader(S);
253 return LoadFunction(S);
254}
255
256/*
257** load one chunk from a file or buffer
258** return main if ok and NULL at EOF
259*/
260TProtoFunc* luaU_undump1(ZIO* Z)
261{
262 int c=zgetc(Z);
263 Sundump S;
264 S.Z=Z;
265 S.SwapNumber=0;
266 S.LoadFloat=1;
267 if (c==ID_CHUNK)
268 return LoadChunk(&S);
269 else if (c!=EOZ)
270 luaL_verror("%s is not a lua binary file",Z->name);
271 return NULL;
272}
diff --git a/lundump.h b/lundump.h
new file mode 100644
index 00000000..ea9e975c
--- /dev/null
+++ b/lundump.h
@@ -0,0 +1,27 @@
1/*
2** $Id: lundump.h,v 1.4 1998/01/13 20:05:24 lhf Exp $
3** load pre-compiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lundump_h
8#define lundump_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13#define ID_CHUNK 27 /* ESC */
14#define ID_FUNCTION '#'
15#define ID_END '$'
16#define ID_NUM 'N'
17#define ID_STR 'S'
18#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
23#define IsMain(f) (f->lineDefined==0)
24
25TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
26
27#endif
diff --git a/undump.c b/undump.c
deleted file mode 100644
index 80f131de..00000000
--- a/undump.c
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2** undump.c
3** load bytecodes from files
4*/
5
6char* rcs_undump="$Id: undump.c,v 1.25 1997/07/29 19:44:02 roberto Exp roberto $";
7
8#include <stdio.h>
9#include <string.h>
10#include "auxlib.h"
11#include "opcode.h"
12#include "luamem.h"
13#include "table.h"
14#include "undump.h"
15#include "zio.h"
16
17static int swapword=0;
18static int swapfloat=0;
19static TFunc* Main=NULL; /* functions in a chunk */
20static TFunc* lastF=NULL;
21
22static void FixCode(Byte* code, Byte* end) /* swap words */
23{
24 Byte* p;
25 for (p=code; p!=end;)
26 {
27 int op=*p;
28 switch (op)
29 {
30 case PUSHNIL:
31 case PUSH0:
32 case PUSH1:
33 case PUSH2:
34 case PUSHLOCAL0:
35 case PUSHLOCAL1:
36 case PUSHLOCAL2:
37 case PUSHLOCAL3:
38 case PUSHLOCAL4:
39 case PUSHLOCAL5:
40 case PUSHLOCAL6:
41 case PUSHLOCAL7:
42 case PUSHLOCAL8:
43 case PUSHLOCAL9:
44 case PUSHINDEXED:
45 case STORELOCAL0:
46 case STORELOCAL1:
47 case STORELOCAL2:
48 case STORELOCAL3:
49 case STORELOCAL4:
50 case STORELOCAL5:
51 case STORELOCAL6:
52 case STORELOCAL7:
53 case STORELOCAL8:
54 case STORELOCAL9:
55 case STOREINDEXED0:
56 case ADJUST0:
57 case EQOP:
58 case LTOP:
59 case LEOP:
60 case GTOP:
61 case GEOP:
62 case ADDOP:
63 case SUBOP:
64 case MULTOP:
65 case DIVOP:
66 case POWOP:
67 case CONCOP:
68 case MINUSOP:
69 case NOTOP:
70 case RETCODE0:
71 p++;
72 break;
73 case PUSHBYTE:
74 case PUSHLOCAL:
75 case STORELOCAL:
76 case STOREINDEXED:
77 case STORELIST0:
78 case ADJUST:
79 case RETCODE:
80 case VARARGS:
81 case STOREMAP:
82 p+=2;
83 break;
84 case STORELIST:
85 case CALLFUNC:
86 p+=3;
87 break;
88 case PUSHWORD:
89 case PUSHSELF:
90 case CREATEARRAY:
91 case ONTJMP:
92 case ONFJMP:
93 case JMP:
94 case UPJMP:
95 case IFFJMP:
96 case IFFUPJMP:
97 case SETLINE:
98 case PUSHGLOBAL:
99 case STOREGLOBAL:
100 {
101 Byte t;
102 t=p[1]; p[1]=p[2]; p[2]=t;
103 p+=3;
104 break;
105 }
106 case STORERECORD:
107 {
108 int n=*++p;
109 p++;
110 while (n--)
111 {
112 Byte t;
113 t=p[0]; p[0]=p[1]; p[1]=t;
114 p+=2;
115 }
116 break;
117 }
118 default:
119 luaL_verror("corrupt binary file: bad opcode %d at %d\n",
120 op,(int)(p-code));
121 break;
122 }
123 }
124}
125
126static void Unthread(Byte* code, int i, int v)
127{
128 while (i!=0)
129 {
130 Word w;
131 Byte* p=code+i;
132 memcpy(&w,p,sizeof(w));
133 i=w; w=v;
134 memcpy(p,&w,sizeof(w));
135 }
136}
137
138static int LoadWord(ZIO* Z)
139{
140 Word w;
141 zread(Z,&w,sizeof(w));
142 if (swapword)
143 {
144 Byte* p=(Byte*)&w;
145 Byte t;
146 t=p[0]; p[0]=p[1]; p[1]=t;
147 }
148 return w;
149}
150
151static int LoadSize(ZIO* Z)
152{
153 Word hi=LoadWord(Z);
154 Word lo=LoadWord(Z);
155 int s=(hi<<16)|lo;
156 if ((Word)s != s) lua_error("code too long");
157 return s;
158}
159
160static void* LoadBlock(int size, ZIO* Z)
161{
162 void* b=luaI_malloc(size);
163 zread(Z,b,size);
164 return b;
165}
166
167static char* LoadString(ZIO* Z)
168{
169 int size=LoadWord(Z);
170 char *b=luaI_buffer(size);
171 zread(Z,b,size);
172 return b;
173}
174
175static char* LoadNewString(ZIO* Z)
176{
177 return LoadBlock(LoadWord(Z),Z);
178}
179
180static void LoadFunction(ZIO* Z)
181{
182 int size;
183 TFunc* tf=new(TFunc);
184 tf->next=NULL;
185 tf->locvars=NULL;
186 size=LoadSize(Z);
187 tf->lineDefined=LoadWord(Z);
188 if (IsMain(tf)) /* new main */
189 {
190 tf->fileName=LoadNewString(Z);
191 Main=lastF=tf;
192 }
193 else /* fix PUSHFUNCTION */
194 {
195 tf->marked=LoadWord(Z);
196 tf->fileName=Main->fileName;
197 memcpy(Main->code+tf->marked,&tf,sizeof(tf));
198 lastF=lastF->next=tf;
199 }
200 tf->code=LoadBlock(size,Z);
201 if (swapword || swapfloat) FixCode(tf->code,tf->code+size);
202 while (1) /* unthread */
203 {
204 int c=zgetc(Z);
205 if (c==ID_VAR) /* global var */
206 {
207 int i=LoadWord(Z);
208 char* s=LoadString(Z);
209 int v=luaI_findsymbolbyname(s);
210 Unthread(tf->code,i,v);
211 }
212 else if (c==ID_STR) /* constant string */
213 {
214 int i=LoadWord(Z);
215 char* s=LoadString(Z);
216 int v; /*=luaI_findconstantbyname(s); ??????? */
217 Unthread(tf->code,i,v);
218 }
219 else
220 {
221 zungetc(Z);
222 break;
223 }
224 }
225}
226
227static void LoadSignature(ZIO* Z)
228{
229 char* s=SIGNATURE;
230 while (*s!=0 && zgetc(Z)==*s)
231 ++s;
232 if (*s!=0) lua_error("cannot load binary file: bad signature");
233}
234
235static void LoadHeader(ZIO* Z)
236{
237 Word w,tw=TEST_WORD;
238 float f,tf=TEST_FLOAT;
239 int version;
240 LoadSignature(Z);
241 version=zgetc(Z);
242 if (version>0x23) /* after 2.5 */
243 {
244 int oldsizeofW=zgetc(Z);
245 int oldsizeofF=zgetc(Z);
246 int oldsizeofP=zgetc(Z);
247 if (oldsizeofW!=2)
248 luaL_verror(
249 "cannot load binary file created on machine with sizeof(Word)=%d; "
250 "expected 2",oldsizeofW);
251 if (oldsizeofF!=4)
252 luaL_verror(
253 "cannot load binary file created on machine with sizeof(float)=%d; "
254 "expected 4\nnot an IEEE machine?",oldsizeofF);
255 if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack? */
256 luaL_verror(
257 "cannot load binary file created on machine with sizeof(TFunc*)=%d; "
258 "expected %d",oldsizeofP,(int)sizeof(TFunc*));
259 }
260 zread(Z,&w,sizeof(w)); /* test word */
261 if (w!=tw)
262 {
263 swapword=1;
264 }
265 zread(Z,&f,sizeof(f)); /* test float */
266 if (f!=tf)
267 {
268 Byte* p=(Byte*)&f;
269 Byte t;
270 swapfloat=1;
271 t=p[0]; p[0]=p[3]; p[3]=t;
272 t=p[1]; p[1]=p[2]; p[2]=t;
273 if (f!=tf) /* TODO: try another perm? */
274 lua_error("cannot load binary file: unknown float representation");
275 }
276}
277
278static void LoadChunk(ZIO* Z)
279{
280 LoadHeader(Z);
281 while (1)
282 {
283 int c=zgetc(Z);
284 if (c==ID_FUN) LoadFunction(Z); else { zungetc(Z); break; }
285 }
286}
287
288/*
289** load one chunk from a file.
290** return list of functions found, headed by main, or NULL at EOF.
291*/
292TFunc* luaI_undump1(ZIO* Z)
293{
294 int c=zgetc(Z);
295 if (c==ID_CHUNK)
296 {
297 LoadChunk(Z);
298 return Main;
299 }
300 else if (c!=EOZ)
301 lua_error("not a lua binary file");
302 return NULL;
303}
304
305/*
306** load and run all chunks in a file
307*/
308int luaI_undump(ZIO* Z)
309{
310 TFunc* m;
311 while ((m=luaI_undump1(Z)))
312 {
313 int status=luaI_dorun(m);
314/* luaI_freefunc(m); ???*/
315 if (status!=0) return status;
316 }
317 return 0;
318}
diff --git a/undump.h b/undump.h
deleted file mode 100644
index 86da43af..00000000
--- a/undump.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2** undump.h
3** definitions for lua decompiler
4** $Id: undump.h,v 1.5 1997/06/16 16:50:22 roberto Exp roberto $
5*/
6
7#ifndef undump_h
8#define undump_h
9
10#include "func.h"
11#include "zio.h"
12
13#define IsMain(f) (f->lineDefined==0)
14
15/* definitions for chunk headers */
16
17#define ID_CHUNK 27 /* ESC */
18#define ID_FUN 'F'
19#define ID_VAR 'V'
20#define ID_STR 'S'
21#define SIGNATURE "Lua"
22#define VERSION 0x25 /* last format change was in 2.5 */
23#define TEST_WORD 0x1234 /* a word for testing byte ordering */
24#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
25
26
27TFunc* luaI_undump1(ZIO* Z);
28int luaI_undump(ZIO* Z); /* load all chunks */
29
30#endif