Imported from ../lua-3.0.tar.gz.
[lua.git] / src / luac / print.c
blobfb7bf8a7d52f78a135d3d7a81d785ea8ab246329
1 /*
2 ** print.c
3 ** print bytecodes
4 */
6 char* rcs_print="$Id: print.c,v 1.17 1997/06/25 17:07:28 lhf Exp $";
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "luac.h"
12 #include "print.h"
14 void LinkFunctions(TFunc* m)
16 static TFunc* lastF; /* list of functions seen in code */
17 Byte* code=m->code;
18 Byte* end=code+m->size;
19 Byte* p;
20 if (IsMain(m)) lastF=m;
21 for (p=code; p!=end;)
23 int op=*p;
24 int at=p-code+1;
25 switch (op)
27 case PUSHNIL:
28 case PUSH0:
29 case PUSH1:
30 case PUSH2:
31 case PUSHLOCAL0:
32 case PUSHLOCAL1:
33 case PUSHLOCAL2:
34 case PUSHLOCAL3:
35 case PUSHLOCAL4:
36 case PUSHLOCAL5:
37 case PUSHLOCAL6:
38 case PUSHLOCAL7:
39 case PUSHLOCAL8:
40 case PUSHLOCAL9:
41 case PUSHINDEXED:
42 case STORELOCAL0:
43 case STORELOCAL1:
44 case STORELOCAL2:
45 case STORELOCAL3:
46 case STORELOCAL4:
47 case STORELOCAL5:
48 case STORELOCAL6:
49 case STORELOCAL7:
50 case STORELOCAL8:
51 case STORELOCAL9:
52 case STOREINDEXED0:
53 case ADJUST0:
54 case EQOP:
55 case LTOP:
56 case LEOP:
57 case GTOP:
58 case GEOP:
59 case ADDOP:
60 case SUBOP:
61 case MULTOP:
62 case DIVOP:
63 case POWOP:
64 case CONCOP:
65 case MINUSOP:
66 case NOTOP:
67 case POP:
68 case RETCODE0:
69 p++;
70 break;
71 case PUSHBYTE:
72 case PUSHLOCAL:
73 case STORELOCAL:
74 case STOREINDEXED:
75 case STORELIST0:
76 case ADJUST:
77 case RETCODE:
78 case VARARGS:
79 case STOREMAP:
80 p+=2;
81 break;
82 case PUSHWORD:
83 case PUSHSTRING:
84 case PUSHGLOBAL:
85 case PUSHSELF:
86 case STOREGLOBAL:
87 case CREATEARRAY:
88 case ONTJMP:
89 case ONFJMP:
90 case JMP:
91 case UPJMP:
92 case IFFJMP:
93 case IFFUPJMP:
94 case CALLFUNC:
95 case SETLINE:
96 case STORELIST:
97 p+=3;
98 break;
99 case PUSHFLOAT:
100 p+=5; /* assumes sizeof(float)==4 */
101 break;
102 case PUSHFUNCTION:
104 TFunc* tf;
105 p++;
106 get_code(tf,p);
107 tf->marked=at;
108 tf->next=NULL; /* TODO: remove? */
109 lastF=lastF->next=tf;
110 break;
112 case STORERECORD:
114 int n=*++p;
115 p+=2*n+1;
116 break;
118 default: /* cannot happen */
119 fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code));
120 exit(1);
121 break;
126 #define LocStr(i) luaI_getlocalname(tf,i+1,line)
128 static void PrintCode(TFunc* tf)
130 Byte* code=tf->code;
131 Byte* end=code+tf->size;
132 Byte* p;
133 int line=0;
134 for (p=code; p!=end;)
136 int op=*p;
137 if (op>=NOPCODES)
139 fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code));
140 exit(1);
142 printf("%6d\t%s",(int)(p-code),OpCodeName[op]);
143 switch (op)
145 case PUSHNIL:
146 case PUSH0:
147 case PUSH1:
148 case PUSH2:
149 case PUSHINDEXED:
150 case STOREINDEXED0:
151 case ADJUST0:
152 case EQOP:
153 case LTOP:
154 case LEOP:
155 case GTOP:
156 case GEOP:
157 case ADDOP:
158 case SUBOP:
159 case MULTOP:
160 case DIVOP:
161 case POWOP:
162 case CONCOP:
163 case MINUSOP:
164 case NOTOP:
165 case POP:
166 case RETCODE0:
167 p++;
168 break;
169 case PUSHLOCAL0:
170 case PUSHLOCAL1:
171 case PUSHLOCAL2:
172 case PUSHLOCAL3:
173 case PUSHLOCAL4:
174 case PUSHLOCAL5:
175 case PUSHLOCAL6:
176 case PUSHLOCAL7:
177 case PUSHLOCAL8:
178 case PUSHLOCAL9:
180 int i=op-PUSHLOCAL0;
181 if (tf->locvars) printf("\t\t; %s",LocStr(i));
182 p++;
183 break;
185 case STORELOCAL0:
186 case STORELOCAL1:
187 case STORELOCAL2:
188 case STORELOCAL3:
189 case STORELOCAL4:
190 case STORELOCAL5:
191 case STORELOCAL6:
192 case STORELOCAL7:
193 case STORELOCAL8:
194 case STORELOCAL9:
196 int i=op-STORELOCAL0;
197 if (tf->locvars) printf("\t\t; %s",LocStr(i));
198 p++;
199 break;
201 case PUSHLOCAL:
202 case STORELOCAL:
204 int i=*(p+1);
205 if (tf->locvars) printf("\t%d\t; %s",i,LocStr(i));
206 p+=2;
207 break;
209 case PUSHBYTE:
210 case STOREINDEXED:
211 case STORELIST0:
212 case ADJUST:
213 case RETCODE:
214 case VARARGS:
215 case STOREMAP:
216 printf("\t%d",*(p+1));
217 p+=2;
218 break;
219 case PUSHWORD:
220 case CREATEARRAY:
221 case SETLINE:
223 Word w;
224 p++;
225 get_word(w,p);
226 printf("\t%d",w);
227 if (op==SETLINE) line=w;
228 break;
230 case ONTJMP:
231 case ONFJMP:
232 case JMP:
233 case IFFJMP:
234 { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */
235 Word w;
236 p++;
237 get_word(w,p);
238 printf("\t%d\t\t; to %d",w,(int)(p-code)+w);
239 break;
241 case UPJMP:
242 case IFFUPJMP:
243 { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */
244 Word w;
245 p++;
246 get_word(w,p);
247 printf("\t%d\t\t; to %d",w,(int)(p-code)-w);
248 break;
250 case PUSHFLOAT:
252 float f;
253 p++;
254 get_float(f,p);
255 printf("\t%g",f);
256 break;
258 case PUSHSELF:
259 case PUSHSTRING:
261 Word w;
262 p++;
263 get_word(w,p);
264 printf("\t%d\t; \"%s\"",w,StrStr(w));
265 break;
267 case PUSHFUNCTION:
269 TFunc* tf;
270 p++;
271 get_code(tf,p);
272 printf("\t%p\t; \"%s\":%d",tf,tf->fileName,tf->lineDefined);
273 break;
275 case PUSHGLOBAL:
276 case STOREGLOBAL:
278 Word w;
279 p++;
280 get_word(w,p);
281 printf("\t%d\t; %s",w,VarStr(w));
282 break;
284 case STORELIST:
285 case CALLFUNC:
286 printf("\t%d %d",*(p+1),*(p+2));
287 p+=3;
288 break;
289 case STORERECORD:
291 int n=*++p;
292 printf("\t%d",n);
293 p++;
294 while (n--)
296 Word w;
297 printf("\n%6d\t FIELD",(int)(p-code));
298 get_word(w,p);
299 printf("\t%d\t; \"%s\"",w,StrStr(w));
301 break;
303 default:
304 printf("\tcannot happen: opcode=%d\n",*p);
305 fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code));
306 exit(1);
307 break;
309 printf("\n");
313 #undef LocStr
315 static void PrintLocals(LocVar* v, int n)
317 int i=0;
318 if (v==NULL || v->varname==NULL) return;
319 if (n>0)
321 printf("parameters:");
322 for (i=0; i<n; v++,i++) printf(" %s[%d@%d]",v->varname->str,i,v->line);
323 printf("\n");
325 if (v->varname!=NULL)
327 printf("locals:");
328 for (; v->line>=0; v++)
330 if (v->varname==NULL)
331 #if 0
332 printf(" %s[%d@%d]","*",--i,v->line);
333 #else
334 --i;
335 #endif
336 else
337 printf(" %s[%d@%d]",v->varname->str,i++,v->line);
339 printf("\n");
343 void PrintFunction(TFunc* tf, TFunc* Main)
345 int n=0;
346 if (IsMain(tf))
347 printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf);
348 else
350 Byte* p;
351 p=tf->code; /* get number of parameters */
352 while (*p==SETLINE) p+=3;
353 if (*p==ADJUST) n=p[1];
354 p=Main->code+tf->marked+sizeof(TFunc*);
355 printf("\nfunction ");
356 switch (*p) /* try to get name */
358 case STOREGLOBAL:
360 Word w;
361 p++; get_word(w,p); printf("%s defined at ",VarStr(w));
362 break;
364 case STOREINDEXED0: /* try method definition */
366 if (p[-11]==PUSHGLOBAL && p[-8]==PUSHSTRING)
368 Word w;
369 Byte* op=p;
370 int c=(tf->locvars && n>0 && strcmp(tf->locvars->varname->str,"self")==0)
371 ? ':' : '.';
372 p=op-11; p++; get_word(w,p); printf("%s%c",VarStr(w),c);
373 p=op-8; p++; get_word(w,p); printf("%s defined at ",StrStr(w));
375 break;
378 printf("\"%s\":%d (%d bytes at %p); used at main+%d\n",
379 tf->fileName,tf->lineDefined,tf->size,tf,tf->marked);
381 PrintLocals(tf->locvars,n);
382 PrintCode(tf);