diff options
author | Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> | 1996-03-08 18:44:12 -0300 |
---|---|---|
committer | Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> | 1996-03-08 18:44:12 -0300 |
commit | 3cab7cd025d64838581a1469afc6597a797a1f67 (patch) | |
tree | 6685377bfc3d882db8b55eb3ad5414374544d5b6 /undump.c | |
parent | bb26efbbec457d43560d979af3255385d0db8226 (diff) | |
download | lua-3cab7cd025d64838581a1469afc6597a797a1f67.tar.gz lua-3cab7cd025d64838581a1469afc6597a797a1f67.tar.bz2 lua-3cab7cd025d64838581a1469afc6597a797a1f67.zip |
undump.c is now a module
panic is now lua_error
included swap.c
tries float permutation earlier
new functions: luaI_undump1 and luaI_undump
Diffstat (limited to 'undump.c')
-rw-r--r-- | undump.c | 192 |
1 files changed, 159 insertions, 33 deletions
@@ -3,24 +3,134 @@ | |||
3 | ** load bytecodes from files | 3 | ** load bytecodes from files |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char* rcs_undump="$Id: undump.c,v 1.9 1996/03/06 16:01:08 lhf Exp lhf $"; | 6 | char* rcs_undump="$Id: undump.c,v 1.10 1996/03/06 21:40:10 lhf Exp lhf $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include "luac.h" | 10 | #include "undump.h" |
11 | 11 | ||
12 | static int swapword=0; | 12 | static int swapword=0; |
13 | static int swapfloat=0; | 13 | static int swapfloat=0; |
14 | static TFunc* Main=NULL; /* functions in a chunk */ | ||
15 | static TFunc* lastF=NULL; | ||
14 | 16 | ||
15 | static void warn(char* s) /* TODO: remove */ | 17 | static void warn(char* s) /* TODO: remove */ |
16 | { | 18 | { |
17 | fprintf(stderr,"undump: %s\n",s); | 19 | fprintf(stderr,"undump: %s\n",s); |
18 | } | 20 | } |
19 | 21 | ||
20 | static void panic(char* s) /* TODO: remove */ | 22 | static void FixCode(Byte* code, Byte* end) /* swap words */ |
21 | { | 23 | { |
22 | warn(s); | 24 | Byte* p; |
23 | exit(1); | 25 | for (p=code; p!=end;) |
26 | { | ||
27 | OpCode op=(OpCode)*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 POP: | ||
71 | case RETCODE0: | ||
72 | p++; | ||
73 | break; | ||
74 | case PUSHBYTE: | ||
75 | case PUSHLOCAL: | ||
76 | case STORELOCAL: | ||
77 | case STOREINDEXED: | ||
78 | case STORELIST0: | ||
79 | case ADJUST: | ||
80 | case RETCODE: | ||
81 | p+=2; | ||
82 | break; | ||
83 | case STORELIST: | ||
84 | case CALLFUNC: | ||
85 | p+=3; | ||
86 | break; | ||
87 | case PUSHFUNCTION: | ||
88 | p+=5; | ||
89 | break; | ||
90 | case PUSHWORD: | ||
91 | case PUSHSELF: | ||
92 | case CREATEARRAY: | ||
93 | case ONTJMP: | ||
94 | case ONFJMP: | ||
95 | case JMP: | ||
96 | case UPJMP: | ||
97 | case IFFJMP: | ||
98 | case IFFUPJMP: | ||
99 | case SETLINE: | ||
100 | case PUSHSTRING: | ||
101 | case PUSHGLOBAL: | ||
102 | case STOREGLOBAL: | ||
103 | { | ||
104 | Byte t; | ||
105 | t=p[1]; p[1]=p[2]; p[2]=t; | ||
106 | p+=3; | ||
107 | break; | ||
108 | } | ||
109 | case PUSHFLOAT: | ||
110 | { | ||
111 | Byte t; | ||
112 | t=p[1]; p[1]=p[4]; p[4]=t; | ||
113 | t=p[2]; p[2]=p[3]; p[3]=t; | ||
114 | p+=5; | ||
115 | break; | ||
116 | } | ||
117 | case STORERECORD: | ||
118 | { | ||
119 | int n=*++p; | ||
120 | p++; | ||
121 | while (n--) | ||
122 | { | ||
123 | Byte t; | ||
124 | t=p[0]; p[0]=p[1]; p[1]=t; | ||
125 | p+=2; | ||
126 | } | ||
127 | break; | ||
128 | } | ||
129 | default: | ||
130 | lua_error("corrupt binary file"); | ||
131 | break; | ||
132 | } | ||
133 | } | ||
24 | } | 134 | } |
25 | 135 | ||
26 | static void Unthread(Byte* code, int i, int v) | 136 | static void Unthread(Byte* code, int i, int v) |
@@ -62,7 +172,7 @@ static int LoadSize(FILE* D) | |||
62 | Word hi=LoadWord(D); | 172 | Word hi=LoadWord(D); |
63 | Word lo=LoadWord(D); | 173 | Word lo=LoadWord(D); |
64 | int s=(hi<<16)|lo; | 174 | int s=(hi<<16)|lo; |
65 | if ((Word)s != s) panic("code too long"); | 175 | if ((Word)s != s) lua_error("code too long"); |
66 | return s; | 176 | return s; |
67 | } | 177 | } |
68 | 178 | ||
@@ -71,9 +181,6 @@ static char* LoadString(FILE* D) | |||
71 | return LoadBlock(LoadWord(D),D); | 181 | return LoadBlock(LoadWord(D),D); |
72 | } | 182 | } |
73 | 183 | ||
74 | static TFunc* Main=NULL; | ||
75 | static TFunc* lastF=NULL; | ||
76 | |||
77 | static void LoadFunction(FILE* D) | 184 | static void LoadFunction(FILE* D) |
78 | { | 185 | { |
79 | TFunc* tf=new(TFunc); | 186 | TFunc* tf=new(TFunc); |
@@ -132,7 +239,7 @@ static void LoadSignature(FILE* D) | |||
132 | char* s=SIGNATURE; | 239 | char* s=SIGNATURE; |
133 | while (*s!=0 && getc(D)==*s) | 240 | while (*s!=0 && getc(D)==*s) |
134 | ++s; | 241 | ++s; |
135 | if (*s!=0) panic("bad signature"); | 242 | if (*s!=0) lua_error("bad signature"); |
136 | } | 243 | } |
137 | 244 | ||
138 | static void LoadHeader(FILE* D) /* TODO: error handling */ | 245 | static void LoadHeader(FILE* D) /* TODO: error handling */ |
@@ -141,17 +248,24 @@ static void LoadHeader(FILE* D) /* TODO: error handling */ | |||
141 | float f,tf=TEST_FLOAT; | 248 | float f,tf=TEST_FLOAT; |
142 | LoadSignature(D); | 249 | LoadSignature(D); |
143 | getc(D); /* skip version */ | 250 | getc(D); /* skip version */ |
144 | fread(&w,sizeof(w),1,D); /* a word for testing byte ordering */ | 251 | fread(&w,sizeof(w),1,D); /* test word */ |
145 | if (w!=tw) | 252 | if (w!=tw) |
146 | { | 253 | { |
147 | swapword=1; | 254 | swapword=1; |
148 | warn("different byte order"); | 255 | warn("different byte order"); |
149 | } | 256 | } |
150 | fread(&f,sizeof(f),1,D); /* a float for testing byte ordering */ | 257 | fread(&f,sizeof(f),1,D); /* test float */ |
151 | if (f!=tf) | 258 | if (f!=tf) |
152 | { | 259 | { |
153 | swapfloat=1; /* TODO: only one test? */ | 260 | Byte* p=&f; /* TODO: need union? */ |
154 | if (f!=tf) warn("different float representation"); | 261 | Byte t; |
262 | swapfloat=1; | ||
263 | t=p[0]; p[0]=p[3]; p[3]=t; | ||
264 | t=p[1]; p[1]=p[2]; p[2]=t; | ||
265 | if (f!=tf) /* TODO: try another perm? */ | ||
266 | lua_error("different float representation"); | ||
267 | else | ||
268 | warn("different byte order in floats"); | ||
155 | } | 269 | } |
156 | } | 270 | } |
157 | 271 | ||
@@ -163,39 +277,51 @@ static void LoadChunk(FILE* D) | |||
163 | int c=getc(D); | 277 | int c=getc(D); |
164 | if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; } | 278 | if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; } |
165 | } | 279 | } |
166 | #if 1 | ||
167 | { /* TODO: run Main? */ | ||
168 | TFunc* tf; | ||
169 | for (tf=Main; tf!=NULL; tf=tf->next) | ||
170 | PrintFunction(tf); | ||
171 | } | ||
172 | #endif | ||
173 | } | 280 | } |
174 | 281 | ||
175 | void luaI_undump(FILE* D) | 282 | /* |
283 | ** load one chunk from a file. | ||
284 | ** return list of functions found, headed by main, or NULL at EOF. | ||
285 | */ | ||
286 | TFunc* luaI_undump1(FILE* D) | ||
176 | { | 287 | { |
177 | while (1) | 288 | while (1) |
178 | { | 289 | { |
179 | int c=getc(D); | 290 | int c=getc(D); |
180 | if (c==ID_CHUNK) | 291 | if (c==ID_CHUNK) |
292 | { | ||
181 | LoadChunk(D); | 293 | LoadChunk(D); |
294 | return Main; | ||
295 | } | ||
182 | else if (c==EOF) | 296 | else if (c==EOF) |
183 | break; | 297 | return NULL; |
184 | else | 298 | else |
185 | panic("not a lua binary file"); | 299 | lua_error("not a lua binary file"); |
186 | } | 300 | } |
187 | } | 301 | } |
188 | 302 | ||
189 | int main(int argc, char* argv[]) | 303 | /* |
304 | ** load and run all chunks in a file | ||
305 | */ | ||
306 | void luaI_undump(FILE* D) | ||
190 | { | 307 | { |
191 | char* fn=(argc>1)? argv[1] : "luac.out"; | 308 | TFunc* m; |
192 | FILE* f=freopen(fn,"rb",stdin); | 309 | while ((m=luaI_undump1(D))) |
193 | if (f==NULL) | ||
194 | { | 310 | { |
195 | fprintf(stderr,"undump: cannot open "); | 311 | #if 0 |
196 | perror(fn); | 312 | luaI_dorun(m); |
197 | exit(1); | 313 | luaI_freefunc(m); /* TODO: free others? */ |
314 | #endif | ||
198 | } | 315 | } |
199 | luaI_undump(stdin); | 316 | } |
200 | return 0; | 317 | |
318 | char* luaI_buffer(int n) | ||
319 | { | ||
320 | static int size=0; | ||
321 | static char* buffer=NULL; | ||
322 | if (buffer==NULL) | ||
323 | buffer=luaI_malloc(n); | ||
324 | else if (n>size) | ||
325 | buffer=luaI_realloc(buffer,size=n); | ||
326 | return buffer; | ||
201 | } | 327 | } |