aboutsummaryrefslogtreecommitdiff
path: root/undump.c
diff options
context:
space:
mode:
Diffstat (limited to 'undump.c')
-rw-r--r--undump.c318
1 files changed, 0 insertions, 318 deletions
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}