1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: luac.c $
3*088332b5SXin Li ** Lua compiler (saves bytecodes to files; also lists bytecodes)
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li
7*088332b5SXin Li #define luac_c
8*088332b5SXin Li #define LUA_CORE
9*088332b5SXin Li
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li
12*088332b5SXin Li #include <ctype.h>
13*088332b5SXin Li #include <errno.h>
14*088332b5SXin Li #include <stdio.h>
15*088332b5SXin Li #include <stdlib.h>
16*088332b5SXin Li #include <string.h>
17*088332b5SXin Li
18*088332b5SXin Li #include "lua.h"
19*088332b5SXin Li #include "lauxlib.h"
20*088332b5SXin Li
21*088332b5SXin Li #include "ldebug.h"
22*088332b5SXin Li #include "lobject.h"
23*088332b5SXin Li #include "lopcodes.h"
24*088332b5SXin Li #include "lopnames.h"
25*088332b5SXin Li #include "lstate.h"
26*088332b5SXin Li #include "lundump.h"
27*088332b5SXin Li
28*088332b5SXin Li static void PrintFunction(const Proto* f, int full);
29*088332b5SXin Li #define luaU_print PrintFunction
30*088332b5SXin Li
31*088332b5SXin Li #define PROGNAME "luac" /* default program name */
32*088332b5SXin Li #define OUTPUT PROGNAME ".out" /* default output file */
33*088332b5SXin Li
34*088332b5SXin Li static int listing=0; /* list bytecodes? */
35*088332b5SXin Li static int dumping=1; /* dump bytecodes? */
36*088332b5SXin Li static int stripping=0; /* strip debug information? */
37*088332b5SXin Li static char Output[]={ OUTPUT }; /* default output file name */
38*088332b5SXin Li static const char* output=Output; /* actual output file name */
39*088332b5SXin Li static const char* progname=PROGNAME; /* actual program name */
40*088332b5SXin Li static TString **tmname;
41*088332b5SXin Li
fatal(const char * message)42*088332b5SXin Li static void fatal(const char* message)
43*088332b5SXin Li {
44*088332b5SXin Li fprintf(stderr,"%s: %s\n",progname,message);
45*088332b5SXin Li exit(EXIT_FAILURE);
46*088332b5SXin Li }
47*088332b5SXin Li
cannot(const char * what)48*088332b5SXin Li static void cannot(const char* what)
49*088332b5SXin Li {
50*088332b5SXin Li fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
51*088332b5SXin Li exit(EXIT_FAILURE);
52*088332b5SXin Li }
53*088332b5SXin Li
usage(const char * message)54*088332b5SXin Li static void usage(const char* message)
55*088332b5SXin Li {
56*088332b5SXin Li if (*message=='-')
57*088332b5SXin Li fprintf(stderr,"%s: unrecognized option '%s'\n",progname,message);
58*088332b5SXin Li else
59*088332b5SXin Li fprintf(stderr,"%s: %s\n",progname,message);
60*088332b5SXin Li fprintf(stderr,
61*088332b5SXin Li "usage: %s [options] [filenames]\n"
62*088332b5SXin Li "Available options are:\n"
63*088332b5SXin Li " -l list (use -l -l for full listing)\n"
64*088332b5SXin Li " -o name output to file 'name' (default is \"%s\")\n"
65*088332b5SXin Li " -p parse only\n"
66*088332b5SXin Li " -s strip debug information\n"
67*088332b5SXin Li " -v show version information\n"
68*088332b5SXin Li " -- stop handling options\n"
69*088332b5SXin Li " - stop handling options and process stdin\n"
70*088332b5SXin Li ,progname,Output);
71*088332b5SXin Li exit(EXIT_FAILURE);
72*088332b5SXin Li }
73*088332b5SXin Li
74*088332b5SXin Li #define IS(s) (strcmp(argv[i],s)==0)
75*088332b5SXin Li
doargs(int argc,char * argv[])76*088332b5SXin Li static int doargs(int argc, char* argv[])
77*088332b5SXin Li {
78*088332b5SXin Li int i;
79*088332b5SXin Li int version=0;
80*088332b5SXin Li if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
81*088332b5SXin Li for (i=1; i<argc; i++)
82*088332b5SXin Li {
83*088332b5SXin Li if (*argv[i]!='-') /* end of options; keep it */
84*088332b5SXin Li break;
85*088332b5SXin Li else if (IS("--")) /* end of options; skip it */
86*088332b5SXin Li {
87*088332b5SXin Li ++i;
88*088332b5SXin Li if (version) ++version;
89*088332b5SXin Li break;
90*088332b5SXin Li }
91*088332b5SXin Li else if (IS("-")) /* end of options; use stdin */
92*088332b5SXin Li break;
93*088332b5SXin Li else if (IS("-l")) /* list */
94*088332b5SXin Li ++listing;
95*088332b5SXin Li else if (IS("-o")) /* output file */
96*088332b5SXin Li {
97*088332b5SXin Li output=argv[++i];
98*088332b5SXin Li if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
99*088332b5SXin Li usage("'-o' needs argument");
100*088332b5SXin Li if (IS("-")) output=NULL;
101*088332b5SXin Li }
102*088332b5SXin Li else if (IS("-p")) /* parse only */
103*088332b5SXin Li dumping=0;
104*088332b5SXin Li else if (IS("-s")) /* strip debug information */
105*088332b5SXin Li stripping=1;
106*088332b5SXin Li else if (IS("-v")) /* show version */
107*088332b5SXin Li ++version;
108*088332b5SXin Li else /* unknown option */
109*088332b5SXin Li usage(argv[i]);
110*088332b5SXin Li }
111*088332b5SXin Li if (i==argc && (listing || !dumping))
112*088332b5SXin Li {
113*088332b5SXin Li dumping=0;
114*088332b5SXin Li argv[--i]=Output;
115*088332b5SXin Li }
116*088332b5SXin Li if (version)
117*088332b5SXin Li {
118*088332b5SXin Li printf("%s\n",LUA_COPYRIGHT);
119*088332b5SXin Li if (version==argc-1) exit(EXIT_SUCCESS);
120*088332b5SXin Li }
121*088332b5SXin Li return i;
122*088332b5SXin Li }
123*088332b5SXin Li
124*088332b5SXin Li #define FUNCTION "(function()end)();"
125*088332b5SXin Li
reader(lua_State * L,void * ud,size_t * size)126*088332b5SXin Li static const char* reader(lua_State* L, void* ud, size_t* size)
127*088332b5SXin Li {
128*088332b5SXin Li UNUSED(L);
129*088332b5SXin Li if ((*(int*)ud)--)
130*088332b5SXin Li {
131*088332b5SXin Li *size=sizeof(FUNCTION)-1;
132*088332b5SXin Li return FUNCTION;
133*088332b5SXin Li }
134*088332b5SXin Li else
135*088332b5SXin Li {
136*088332b5SXin Li *size=0;
137*088332b5SXin Li return NULL;
138*088332b5SXin Li }
139*088332b5SXin Li }
140*088332b5SXin Li
141*088332b5SXin Li #define toproto(L,i) getproto(s2v(L->top+(i)))
142*088332b5SXin Li
combine(lua_State * L,int n)143*088332b5SXin Li static const Proto* combine(lua_State* L, int n)
144*088332b5SXin Li {
145*088332b5SXin Li if (n==1)
146*088332b5SXin Li return toproto(L,-1);
147*088332b5SXin Li else
148*088332b5SXin Li {
149*088332b5SXin Li Proto* f;
150*088332b5SXin Li int i=n;
151*088332b5SXin Li if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
152*088332b5SXin Li f=toproto(L,-1);
153*088332b5SXin Li for (i=0; i<n; i++)
154*088332b5SXin Li {
155*088332b5SXin Li f->p[i]=toproto(L,i-n-1);
156*088332b5SXin Li if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
157*088332b5SXin Li }
158*088332b5SXin Li f->sizelineinfo=0;
159*088332b5SXin Li return f;
160*088332b5SXin Li }
161*088332b5SXin Li }
162*088332b5SXin Li
writer(lua_State * L,const void * p,size_t size,void * u)163*088332b5SXin Li static int writer(lua_State* L, const void* p, size_t size, void* u)
164*088332b5SXin Li {
165*088332b5SXin Li UNUSED(L);
166*088332b5SXin Li return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
167*088332b5SXin Li }
168*088332b5SXin Li
pmain(lua_State * L)169*088332b5SXin Li static int pmain(lua_State* L)
170*088332b5SXin Li {
171*088332b5SXin Li int argc=(int)lua_tointeger(L,1);
172*088332b5SXin Li char** argv=(char**)lua_touserdata(L,2);
173*088332b5SXin Li const Proto* f;
174*088332b5SXin Li int i;
175*088332b5SXin Li tmname=G(L)->tmname;
176*088332b5SXin Li if (!lua_checkstack(L,argc)) fatal("too many input files");
177*088332b5SXin Li for (i=0; i<argc; i++)
178*088332b5SXin Li {
179*088332b5SXin Li const char* filename=IS("-") ? NULL : argv[i];
180*088332b5SXin Li if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
181*088332b5SXin Li }
182*088332b5SXin Li f=combine(L,argc);
183*088332b5SXin Li if (listing) luaU_print(f,listing>1);
184*088332b5SXin Li if (dumping)
185*088332b5SXin Li {
186*088332b5SXin Li FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
187*088332b5SXin Li if (D==NULL) cannot("open");
188*088332b5SXin Li lua_lock(L);
189*088332b5SXin Li luaU_dump(L,f,writer,D,stripping);
190*088332b5SXin Li lua_unlock(L);
191*088332b5SXin Li if (ferror(D)) cannot("write");
192*088332b5SXin Li if (fclose(D)) cannot("close");
193*088332b5SXin Li }
194*088332b5SXin Li return 0;
195*088332b5SXin Li }
196*088332b5SXin Li
main(int argc,char * argv[])197*088332b5SXin Li int main(int argc, char* argv[])
198*088332b5SXin Li {
199*088332b5SXin Li lua_State* L;
200*088332b5SXin Li int i=doargs(argc,argv);
201*088332b5SXin Li argc-=i; argv+=i;
202*088332b5SXin Li if (argc<=0) usage("no input files given");
203*088332b5SXin Li L=luaL_newstate();
204*088332b5SXin Li if (L==NULL) fatal("cannot create state: not enough memory");
205*088332b5SXin Li lua_pushcfunction(L,&pmain);
206*088332b5SXin Li lua_pushinteger(L,argc);
207*088332b5SXin Li lua_pushlightuserdata(L,argv);
208*088332b5SXin Li if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
209*088332b5SXin Li lua_close(L);
210*088332b5SXin Li return EXIT_SUCCESS;
211*088332b5SXin Li }
212*088332b5SXin Li
213*088332b5SXin Li /*
214*088332b5SXin Li ** print bytecodes
215*088332b5SXin Li */
216*088332b5SXin Li
217*088332b5SXin Li #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
218*088332b5SXin Li #define VOID(p) ((const void*)(p))
219*088332b5SXin Li #define eventname(i) (getstr(tmname[i]))
220*088332b5SXin Li
PrintString(const TString * ts)221*088332b5SXin Li static void PrintString(const TString* ts)
222*088332b5SXin Li {
223*088332b5SXin Li const char* s=getstr(ts);
224*088332b5SXin Li size_t i,n=tsslen(ts);
225*088332b5SXin Li printf("\"");
226*088332b5SXin Li for (i=0; i<n; i++)
227*088332b5SXin Li {
228*088332b5SXin Li int c=(int)(unsigned char)s[i];
229*088332b5SXin Li switch (c)
230*088332b5SXin Li {
231*088332b5SXin Li case '"':
232*088332b5SXin Li printf("\\\"");
233*088332b5SXin Li break;
234*088332b5SXin Li case '\\':
235*088332b5SXin Li printf("\\\\");
236*088332b5SXin Li break;
237*088332b5SXin Li case '\a':
238*088332b5SXin Li printf("\\a");
239*088332b5SXin Li break;
240*088332b5SXin Li case '\b':
241*088332b5SXin Li printf("\\b");
242*088332b5SXin Li break;
243*088332b5SXin Li case '\f':
244*088332b5SXin Li printf("\\f");
245*088332b5SXin Li break;
246*088332b5SXin Li case '\n':
247*088332b5SXin Li printf("\\n");
248*088332b5SXin Li break;
249*088332b5SXin Li case '\r':
250*088332b5SXin Li printf("\\r");
251*088332b5SXin Li break;
252*088332b5SXin Li case '\t':
253*088332b5SXin Li printf("\\t");
254*088332b5SXin Li break;
255*088332b5SXin Li case '\v':
256*088332b5SXin Li printf("\\v");
257*088332b5SXin Li break;
258*088332b5SXin Li default:
259*088332b5SXin Li if (isprint(c)) printf("%c",c); else printf("\\%03d",c);
260*088332b5SXin Li break;
261*088332b5SXin Li }
262*088332b5SXin Li }
263*088332b5SXin Li printf("\"");
264*088332b5SXin Li }
265*088332b5SXin Li
PrintType(const Proto * f,int i)266*088332b5SXin Li static void PrintType(const Proto* f, int i)
267*088332b5SXin Li {
268*088332b5SXin Li const TValue* o=&f->k[i];
269*088332b5SXin Li switch (ttypetag(o))
270*088332b5SXin Li {
271*088332b5SXin Li case LUA_VNIL:
272*088332b5SXin Li printf("N");
273*088332b5SXin Li break;
274*088332b5SXin Li case LUA_VFALSE:
275*088332b5SXin Li case LUA_VTRUE:
276*088332b5SXin Li printf("B");
277*088332b5SXin Li break;
278*088332b5SXin Li case LUA_VNUMFLT:
279*088332b5SXin Li printf("F");
280*088332b5SXin Li break;
281*088332b5SXin Li case LUA_VNUMINT:
282*088332b5SXin Li printf("I");
283*088332b5SXin Li break;
284*088332b5SXin Li case LUA_VSHRSTR:
285*088332b5SXin Li case LUA_VLNGSTR:
286*088332b5SXin Li printf("S");
287*088332b5SXin Li break;
288*088332b5SXin Li default: /* cannot happen */
289*088332b5SXin Li printf("?%d",ttypetag(o));
290*088332b5SXin Li break;
291*088332b5SXin Li }
292*088332b5SXin Li printf("\t");
293*088332b5SXin Li }
294*088332b5SXin Li
PrintConstant(const Proto * f,int i)295*088332b5SXin Li static void PrintConstant(const Proto* f, int i)
296*088332b5SXin Li {
297*088332b5SXin Li const TValue* o=&f->k[i];
298*088332b5SXin Li switch (ttypetag(o))
299*088332b5SXin Li {
300*088332b5SXin Li case LUA_VNIL:
301*088332b5SXin Li printf("nil");
302*088332b5SXin Li break;
303*088332b5SXin Li case LUA_VFALSE:
304*088332b5SXin Li printf("false");
305*088332b5SXin Li break;
306*088332b5SXin Li case LUA_VTRUE:
307*088332b5SXin Li printf("true");
308*088332b5SXin Li break;
309*088332b5SXin Li case LUA_VNUMFLT:
310*088332b5SXin Li {
311*088332b5SXin Li char buff[100];
312*088332b5SXin Li sprintf(buff,LUA_NUMBER_FMT,fltvalue(o));
313*088332b5SXin Li printf("%s",buff);
314*088332b5SXin Li if (buff[strspn(buff,"-0123456789")]=='\0') printf(".0");
315*088332b5SXin Li break;
316*088332b5SXin Li }
317*088332b5SXin Li case LUA_VNUMINT:
318*088332b5SXin Li printf(LUA_INTEGER_FMT,ivalue(o));
319*088332b5SXin Li break;
320*088332b5SXin Li case LUA_VSHRSTR:
321*088332b5SXin Li case LUA_VLNGSTR:
322*088332b5SXin Li PrintString(tsvalue(o));
323*088332b5SXin Li break;
324*088332b5SXin Li default: /* cannot happen */
325*088332b5SXin Li printf("?%d",ttypetag(o));
326*088332b5SXin Li break;
327*088332b5SXin Li }
328*088332b5SXin Li }
329*088332b5SXin Li
330*088332b5SXin Li #define COMMENT "\t; "
331*088332b5SXin Li #define EXTRAARG GETARG_Ax(code[pc+1])
332*088332b5SXin Li #define EXTRAARGC (EXTRAARG*(MAXARG_C+1))
333*088332b5SXin Li #define ISK (isk ? "k" : "")
334*088332b5SXin Li
PrintCode(const Proto * f)335*088332b5SXin Li static void PrintCode(const Proto* f)
336*088332b5SXin Li {
337*088332b5SXin Li const Instruction* code=f->code;
338*088332b5SXin Li int pc,n=f->sizecode;
339*088332b5SXin Li for (pc=0; pc<n; pc++)
340*088332b5SXin Li {
341*088332b5SXin Li Instruction i=code[pc];
342*088332b5SXin Li OpCode o=GET_OPCODE(i);
343*088332b5SXin Li int a=GETARG_A(i);
344*088332b5SXin Li int b=GETARG_B(i);
345*088332b5SXin Li int c=GETARG_C(i);
346*088332b5SXin Li int ax=GETARG_Ax(i);
347*088332b5SXin Li int bx=GETARG_Bx(i);
348*088332b5SXin Li int sb=GETARG_sB(i);
349*088332b5SXin Li int sc=GETARG_sC(i);
350*088332b5SXin Li int sbx=GETARG_sBx(i);
351*088332b5SXin Li int isk=GETARG_k(i);
352*088332b5SXin Li int line=luaG_getfuncline(f,pc);
353*088332b5SXin Li printf("\t%d\t",pc+1);
354*088332b5SXin Li if (line>0) printf("[%d]\t",line); else printf("[-]\t");
355*088332b5SXin Li printf("%-9s\t",opnames[o]);
356*088332b5SXin Li switch (o)
357*088332b5SXin Li {
358*088332b5SXin Li case OP_MOVE:
359*088332b5SXin Li printf("%d %d",a,b);
360*088332b5SXin Li break;
361*088332b5SXin Li case OP_LOADI:
362*088332b5SXin Li printf("%d %d",a,sbx);
363*088332b5SXin Li break;
364*088332b5SXin Li case OP_LOADF:
365*088332b5SXin Li printf("%d %d",a,sbx);
366*088332b5SXin Li break;
367*088332b5SXin Li case OP_LOADK:
368*088332b5SXin Li printf("%d %d",a,bx);
369*088332b5SXin Li printf(COMMENT); PrintConstant(f,bx);
370*088332b5SXin Li break;
371*088332b5SXin Li case OP_LOADKX:
372*088332b5SXin Li printf("%d",a);
373*088332b5SXin Li printf(COMMENT); PrintConstant(f,EXTRAARG);
374*088332b5SXin Li break;
375*088332b5SXin Li case OP_LOADFALSE:
376*088332b5SXin Li printf("%d",a);
377*088332b5SXin Li break;
378*088332b5SXin Li case OP_LFALSESKIP:
379*088332b5SXin Li printf("%d",a);
380*088332b5SXin Li break;
381*088332b5SXin Li case OP_LOADTRUE:
382*088332b5SXin Li printf("%d",a);
383*088332b5SXin Li break;
384*088332b5SXin Li case OP_LOADNIL:
385*088332b5SXin Li printf("%d %d",a,b);
386*088332b5SXin Li printf(COMMENT "%d out",b+1);
387*088332b5SXin Li break;
388*088332b5SXin Li case OP_GETUPVAL:
389*088332b5SXin Li printf("%d %d",a,b);
390*088332b5SXin Li printf(COMMENT "%s",UPVALNAME(b));
391*088332b5SXin Li break;
392*088332b5SXin Li case OP_SETUPVAL:
393*088332b5SXin Li printf("%d %d",a,b);
394*088332b5SXin Li printf(COMMENT "%s",UPVALNAME(b));
395*088332b5SXin Li break;
396*088332b5SXin Li case OP_GETTABUP:
397*088332b5SXin Li printf("%d %d %d",a,b,c);
398*088332b5SXin Li printf(COMMENT "%s",UPVALNAME(b));
399*088332b5SXin Li printf(" "); PrintConstant(f,c);
400*088332b5SXin Li break;
401*088332b5SXin Li case OP_GETTABLE:
402*088332b5SXin Li printf("%d %d %d",a,b,c);
403*088332b5SXin Li break;
404*088332b5SXin Li case OP_GETI:
405*088332b5SXin Li printf("%d %d %d",a,b,c);
406*088332b5SXin Li break;
407*088332b5SXin Li case OP_GETFIELD:
408*088332b5SXin Li printf("%d %d %d",a,b,c);
409*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
410*088332b5SXin Li break;
411*088332b5SXin Li case OP_SETTABUP:
412*088332b5SXin Li printf("%d %d %d%s",a,b,c,ISK);
413*088332b5SXin Li printf(COMMENT "%s",UPVALNAME(a));
414*088332b5SXin Li printf(" "); PrintConstant(f,b);
415*088332b5SXin Li if (isk) { printf(" "); PrintConstant(f,c); }
416*088332b5SXin Li break;
417*088332b5SXin Li case OP_SETTABLE:
418*088332b5SXin Li printf("%d %d %d%s",a,b,c,ISK);
419*088332b5SXin Li if (isk) { printf(COMMENT); PrintConstant(f,c); }
420*088332b5SXin Li break;
421*088332b5SXin Li case OP_SETI:
422*088332b5SXin Li printf("%d %d %d%s",a,b,c,ISK);
423*088332b5SXin Li if (isk) { printf(COMMENT); PrintConstant(f,c); }
424*088332b5SXin Li break;
425*088332b5SXin Li case OP_SETFIELD:
426*088332b5SXin Li printf("%d %d %d%s",a,b,c,ISK);
427*088332b5SXin Li printf(COMMENT); PrintConstant(f,b);
428*088332b5SXin Li if (isk) { printf(" "); PrintConstant(f,c); }
429*088332b5SXin Li break;
430*088332b5SXin Li case OP_NEWTABLE:
431*088332b5SXin Li printf("%d %d %d",a,b,c);
432*088332b5SXin Li printf(COMMENT "%d",c+EXTRAARGC);
433*088332b5SXin Li break;
434*088332b5SXin Li case OP_SELF:
435*088332b5SXin Li printf("%d %d %d%s",a,b,c,ISK);
436*088332b5SXin Li if (isk) { printf(COMMENT); PrintConstant(f,c); }
437*088332b5SXin Li break;
438*088332b5SXin Li case OP_ADDI:
439*088332b5SXin Li printf("%d %d %d",a,b,sc);
440*088332b5SXin Li break;
441*088332b5SXin Li case OP_ADDK:
442*088332b5SXin Li printf("%d %d %d",a,b,c);
443*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
444*088332b5SXin Li break;
445*088332b5SXin Li case OP_SUBK:
446*088332b5SXin Li printf("%d %d %d",a,b,c);
447*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
448*088332b5SXin Li break;
449*088332b5SXin Li case OP_MULK:
450*088332b5SXin Li printf("%d %d %d",a,b,c);
451*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
452*088332b5SXin Li break;
453*088332b5SXin Li case OP_MODK:
454*088332b5SXin Li printf("%d %d %d",a,b,c);
455*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
456*088332b5SXin Li break;
457*088332b5SXin Li case OP_POWK:
458*088332b5SXin Li printf("%d %d %d",a,b,c);
459*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
460*088332b5SXin Li break;
461*088332b5SXin Li case OP_DIVK:
462*088332b5SXin Li printf("%d %d %d",a,b,c);
463*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
464*088332b5SXin Li break;
465*088332b5SXin Li case OP_IDIVK:
466*088332b5SXin Li printf("%d %d %d",a,b,c);
467*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
468*088332b5SXin Li break;
469*088332b5SXin Li case OP_BANDK:
470*088332b5SXin Li printf("%d %d %d",a,b,c);
471*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
472*088332b5SXin Li break;
473*088332b5SXin Li case OP_BORK:
474*088332b5SXin Li printf("%d %d %d",a,b,c);
475*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
476*088332b5SXin Li break;
477*088332b5SXin Li case OP_BXORK:
478*088332b5SXin Li printf("%d %d %d",a,b,c);
479*088332b5SXin Li printf(COMMENT); PrintConstant(f,c);
480*088332b5SXin Li break;
481*088332b5SXin Li case OP_SHRI:
482*088332b5SXin Li printf("%d %d %d",a,b,sc);
483*088332b5SXin Li break;
484*088332b5SXin Li case OP_SHLI:
485*088332b5SXin Li printf("%d %d %d",a,b,sc);
486*088332b5SXin Li break;
487*088332b5SXin Li case OP_ADD:
488*088332b5SXin Li printf("%d %d %d",a,b,c);
489*088332b5SXin Li break;
490*088332b5SXin Li case OP_SUB:
491*088332b5SXin Li printf("%d %d %d",a,b,c);
492*088332b5SXin Li break;
493*088332b5SXin Li case OP_MUL:
494*088332b5SXin Li printf("%d %d %d",a,b,c);
495*088332b5SXin Li break;
496*088332b5SXin Li case OP_MOD:
497*088332b5SXin Li printf("%d %d %d",a,b,c);
498*088332b5SXin Li break;
499*088332b5SXin Li case OP_POW:
500*088332b5SXin Li printf("%d %d %d",a,b,c);
501*088332b5SXin Li break;
502*088332b5SXin Li case OP_DIV:
503*088332b5SXin Li printf("%d %d %d",a,b,c);
504*088332b5SXin Li break;
505*088332b5SXin Li case OP_IDIV:
506*088332b5SXin Li printf("%d %d %d",a,b,c);
507*088332b5SXin Li break;
508*088332b5SXin Li case OP_BAND:
509*088332b5SXin Li printf("%d %d %d",a,b,c);
510*088332b5SXin Li break;
511*088332b5SXin Li case OP_BOR:
512*088332b5SXin Li printf("%d %d %d",a,b,c);
513*088332b5SXin Li break;
514*088332b5SXin Li case OP_BXOR:
515*088332b5SXin Li printf("%d %d %d",a,b,c);
516*088332b5SXin Li break;
517*088332b5SXin Li case OP_SHL:
518*088332b5SXin Li printf("%d %d %d",a,b,c);
519*088332b5SXin Li break;
520*088332b5SXin Li case OP_SHR:
521*088332b5SXin Li printf("%d %d %d",a,b,c);
522*088332b5SXin Li break;
523*088332b5SXin Li case OP_MMBIN:
524*088332b5SXin Li printf("%d %d %d",a,b,c);
525*088332b5SXin Li printf(COMMENT "%s",eventname(c));
526*088332b5SXin Li break;
527*088332b5SXin Li case OP_MMBINI:
528*088332b5SXin Li printf("%d %d %d %d",a,sb,c,isk);
529*088332b5SXin Li printf(COMMENT "%s",eventname(c));
530*088332b5SXin Li if (isk) printf(" flip");
531*088332b5SXin Li break;
532*088332b5SXin Li case OP_MMBINK:
533*088332b5SXin Li printf("%d %d %d %d",a,b,c,isk);
534*088332b5SXin Li printf(COMMENT "%s ",eventname(c)); PrintConstant(f,b);
535*088332b5SXin Li if (isk) printf(" flip");
536*088332b5SXin Li break;
537*088332b5SXin Li case OP_UNM:
538*088332b5SXin Li printf("%d %d",a,b);
539*088332b5SXin Li break;
540*088332b5SXin Li case OP_BNOT:
541*088332b5SXin Li printf("%d %d",a,b);
542*088332b5SXin Li break;
543*088332b5SXin Li case OP_NOT:
544*088332b5SXin Li printf("%d %d",a,b);
545*088332b5SXin Li break;
546*088332b5SXin Li case OP_LEN:
547*088332b5SXin Li printf("%d %d",a,b);
548*088332b5SXin Li break;
549*088332b5SXin Li case OP_CONCAT:
550*088332b5SXin Li printf("%d %d",a,b);
551*088332b5SXin Li break;
552*088332b5SXin Li case OP_CLOSE:
553*088332b5SXin Li printf("%d",a);
554*088332b5SXin Li break;
555*088332b5SXin Li case OP_TBC:
556*088332b5SXin Li printf("%d",a);
557*088332b5SXin Li break;
558*088332b5SXin Li case OP_JMP:
559*088332b5SXin Li printf("%d",GETARG_sJ(i));
560*088332b5SXin Li printf(COMMENT "to %d",GETARG_sJ(i)+pc+2);
561*088332b5SXin Li break;
562*088332b5SXin Li case OP_EQ:
563*088332b5SXin Li printf("%d %d %d",a,b,isk);
564*088332b5SXin Li break;
565*088332b5SXin Li case OP_LT:
566*088332b5SXin Li printf("%d %d %d",a,b,isk);
567*088332b5SXin Li break;
568*088332b5SXin Li case OP_LE:
569*088332b5SXin Li printf("%d %d %d",a,b,isk);
570*088332b5SXin Li break;
571*088332b5SXin Li case OP_EQK:
572*088332b5SXin Li printf("%d %d %d",a,b,isk);
573*088332b5SXin Li printf(COMMENT); PrintConstant(f,b);
574*088332b5SXin Li break;
575*088332b5SXin Li case OP_EQI:
576*088332b5SXin Li printf("%d %d %d",a,sb,isk);
577*088332b5SXin Li break;
578*088332b5SXin Li case OP_LTI:
579*088332b5SXin Li printf("%d %d %d",a,sb,isk);
580*088332b5SXin Li break;
581*088332b5SXin Li case OP_LEI:
582*088332b5SXin Li printf("%d %d %d",a,sb,isk);
583*088332b5SXin Li break;
584*088332b5SXin Li case OP_GTI:
585*088332b5SXin Li printf("%d %d %d",a,sb,isk);
586*088332b5SXin Li break;
587*088332b5SXin Li case OP_GEI:
588*088332b5SXin Li printf("%d %d %d",a,sb,isk);
589*088332b5SXin Li break;
590*088332b5SXin Li case OP_TEST:
591*088332b5SXin Li printf("%d %d",a,isk);
592*088332b5SXin Li break;
593*088332b5SXin Li case OP_TESTSET:
594*088332b5SXin Li printf("%d %d %d",a,b,isk);
595*088332b5SXin Li break;
596*088332b5SXin Li case OP_CALL:
597*088332b5SXin Li printf("%d %d %d",a,b,c);
598*088332b5SXin Li printf(COMMENT);
599*088332b5SXin Li if (b==0) printf("all in "); else printf("%d in ",b-1);
600*088332b5SXin Li if (c==0) printf("all out"); else printf("%d out",c-1);
601*088332b5SXin Li break;
602*088332b5SXin Li case OP_TAILCALL:
603*088332b5SXin Li printf("%d %d %d",a,b,c);
604*088332b5SXin Li printf(COMMENT "%d in",b-1);
605*088332b5SXin Li break;
606*088332b5SXin Li case OP_RETURN:
607*088332b5SXin Li printf("%d %d %d",a,b,c);
608*088332b5SXin Li printf(COMMENT);
609*088332b5SXin Li if (b==0) printf("all out"); else printf("%d out",b-1);
610*088332b5SXin Li break;
611*088332b5SXin Li case OP_RETURN0:
612*088332b5SXin Li break;
613*088332b5SXin Li case OP_RETURN1:
614*088332b5SXin Li printf("%d",a);
615*088332b5SXin Li break;
616*088332b5SXin Li case OP_FORLOOP:
617*088332b5SXin Li printf("%d %d",a,bx);
618*088332b5SXin Li printf(COMMENT "to %d",pc-bx+2);
619*088332b5SXin Li break;
620*088332b5SXin Li case OP_FORPREP:
621*088332b5SXin Li printf("%d %d",a,bx);
622*088332b5SXin Li printf(COMMENT "to %d",pc+bx+2);
623*088332b5SXin Li break;
624*088332b5SXin Li case OP_TFORPREP:
625*088332b5SXin Li printf("%d %d",a,bx);
626*088332b5SXin Li printf(COMMENT "to %d",pc+bx+2);
627*088332b5SXin Li break;
628*088332b5SXin Li case OP_TFORCALL:
629*088332b5SXin Li printf("%d %d",a,c);
630*088332b5SXin Li break;
631*088332b5SXin Li case OP_TFORLOOP:
632*088332b5SXin Li printf("%d %d",a,bx);
633*088332b5SXin Li printf(COMMENT "to %d",pc-bx+2);
634*088332b5SXin Li break;
635*088332b5SXin Li case OP_SETLIST:
636*088332b5SXin Li printf("%d %d %d",a,b,c);
637*088332b5SXin Li if (isk) printf(COMMENT "%d",c+EXTRAARGC);
638*088332b5SXin Li break;
639*088332b5SXin Li case OP_CLOSURE:
640*088332b5SXin Li printf("%d %d",a,bx);
641*088332b5SXin Li printf(COMMENT "%p",VOID(f->p[bx]));
642*088332b5SXin Li break;
643*088332b5SXin Li case OP_VARARG:
644*088332b5SXin Li printf("%d %d",a,c);
645*088332b5SXin Li printf(COMMENT);
646*088332b5SXin Li if (c==0) printf("all out"); else printf("%d out",c-1);
647*088332b5SXin Li break;
648*088332b5SXin Li case OP_VARARGPREP:
649*088332b5SXin Li printf("%d",a);
650*088332b5SXin Li break;
651*088332b5SXin Li case OP_EXTRAARG:
652*088332b5SXin Li printf("%d",ax);
653*088332b5SXin Li break;
654*088332b5SXin Li #if 0
655*088332b5SXin Li default:
656*088332b5SXin Li printf("%d %d %d",a,b,c);
657*088332b5SXin Li printf(COMMENT "not handled");
658*088332b5SXin Li break;
659*088332b5SXin Li #endif
660*088332b5SXin Li }
661*088332b5SXin Li printf("\n");
662*088332b5SXin Li }
663*088332b5SXin Li }
664*088332b5SXin Li
665*088332b5SXin Li
666*088332b5SXin Li #define SS(x) ((x==1)?"":"s")
667*088332b5SXin Li #define S(x) (int)(x),SS(x)
668*088332b5SXin Li
PrintHeader(const Proto * f)669*088332b5SXin Li static void PrintHeader(const Proto* f)
670*088332b5SXin Li {
671*088332b5SXin Li const char* s=f->source ? getstr(f->source) : "=?";
672*088332b5SXin Li if (*s=='@' || *s=='=')
673*088332b5SXin Li s++;
674*088332b5SXin Li else if (*s==LUA_SIGNATURE[0])
675*088332b5SXin Li s="(bstring)";
676*088332b5SXin Li else
677*088332b5SXin Li s="(string)";
678*088332b5SXin Li printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
679*088332b5SXin Li (f->linedefined==0)?"main":"function",s,
680*088332b5SXin Li f->linedefined,f->lastlinedefined,
681*088332b5SXin Li S(f->sizecode),VOID(f));
682*088332b5SXin Li printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
683*088332b5SXin Li (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
684*088332b5SXin Li S(f->maxstacksize),S(f->sizeupvalues));
685*088332b5SXin Li printf("%d local%s, %d constant%s, %d function%s\n",
686*088332b5SXin Li S(f->sizelocvars),S(f->sizek),S(f->sizep));
687*088332b5SXin Li }
688*088332b5SXin Li
PrintDebug(const Proto * f)689*088332b5SXin Li static void PrintDebug(const Proto* f)
690*088332b5SXin Li {
691*088332b5SXin Li int i,n;
692*088332b5SXin Li n=f->sizek;
693*088332b5SXin Li printf("constants (%d) for %p:\n",n,VOID(f));
694*088332b5SXin Li for (i=0; i<n; i++)
695*088332b5SXin Li {
696*088332b5SXin Li printf("\t%d\t",i);
697*088332b5SXin Li PrintType(f,i);
698*088332b5SXin Li PrintConstant(f,i);
699*088332b5SXin Li printf("\n");
700*088332b5SXin Li }
701*088332b5SXin Li n=f->sizelocvars;
702*088332b5SXin Li printf("locals (%d) for %p:\n",n,VOID(f));
703*088332b5SXin Li for (i=0; i<n; i++)
704*088332b5SXin Li {
705*088332b5SXin Li printf("\t%d\t%s\t%d\t%d\n",
706*088332b5SXin Li i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
707*088332b5SXin Li }
708*088332b5SXin Li n=f->sizeupvalues;
709*088332b5SXin Li printf("upvalues (%d) for %p:\n",n,VOID(f));
710*088332b5SXin Li for (i=0; i<n; i++)
711*088332b5SXin Li {
712*088332b5SXin Li printf("\t%d\t%s\t%d\t%d\n",
713*088332b5SXin Li i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
714*088332b5SXin Li }
715*088332b5SXin Li }
716*088332b5SXin Li
PrintFunction(const Proto * f,int full)717*088332b5SXin Li static void PrintFunction(const Proto* f, int full)
718*088332b5SXin Li {
719*088332b5SXin Li int i,n=f->sizep;
720*088332b5SXin Li PrintHeader(f);
721*088332b5SXin Li PrintCode(f);
722*088332b5SXin Li if (full) PrintDebug(f);
723*088332b5SXin Li for (i=0; i<n; i++) PrintFunction(f->p[i],full);
724*088332b5SXin Li }
725