3 ** Lua compiler (saves bytecodes to files; also lists bytecodes)
4 ** See Copyright Notice in lua.h
28 static void PrintFunction(const Proto
* f
, int full
);
29 #define luaU_print PrintFunction
31 #define PROGNAME "luac" /* default program name */
32 #define OUTPUT PROGNAME ".out" /* default output file */
34 static int listing
=0; /* list bytecodes? */
35 static int dumping
=1; /* dump bytecodes? */
36 static int stripping
=0; /* strip debug information? */
37 static char Output
[]={ OUTPUT
}; /* default output file name */
38 static const char* output
=Output
; /* actual output file name */
39 static const char* progname
=PROGNAME
; /* actual program name */
40 static TString
**tmname
;
42 static void fatal(const char* message
)
44 fprintf(stderr
,"%s: %s\n",progname
,message
);
48 static void cannot(const char* what
)
50 fprintf(stderr
,"%s: cannot %s %s: %s\n",progname
,what
,output
,strerror(errno
));
54 static void usage(const char* message
)
57 fprintf(stderr
,"%s: unrecognized option '%s'\n",progname
,message
);
59 fprintf(stderr
,"%s: %s\n",progname
,message
);
61 "usage: %s [options] [filenames]\n"
62 "Available options are:\n"
63 " -l list (use -l -l for full listing)\n"
64 " -o name output to file 'name' (default is \"%s\")\n"
66 " -s strip debug information\n"
67 " -v show version information\n"
68 " -- stop handling options\n"
69 " - stop handling options and process stdin\n"
74 #define IS(s) (strcmp(argv[i],s)==0)
76 static int doargs(int argc
, char* argv
[])
80 if (argv
[0]!=NULL
&& *argv
[0]!=0) progname
=argv
[0];
81 for (i
=1; i
<argc
; i
++)
83 if (*argv
[i
]!='-') /* end of options; keep it */
85 else if (IS("--")) /* end of options; skip it */
88 if (version
) ++version
;
91 else if (IS("-")) /* end of options; use stdin */
93 else if (IS("-l")) /* list */
95 else if (IS("-o")) /* output file */
98 if (output
==NULL
|| *output
==0 || (*output
=='-' && output
[1]!=0))
99 usage("'-o' needs argument");
100 if (IS("-")) output
=NULL
;
102 else if (IS("-p")) /* parse only */
104 else if (IS("-s")) /* strip debug information */
106 else if (IS("-v")) /* show version */
108 else /* unknown option */
111 if (i
==argc
&& (listing
|| !dumping
))
118 printf("%s\n",LUA_COPYRIGHT
);
119 if (version
==argc
-1) exit(EXIT_SUCCESS
);
124 #define FUNCTION "(function()end)();\n"
126 static const char* reader(lua_State
* L
, void* ud
, size_t* size
)
131 *size
=sizeof(FUNCTION
)-1;
141 #define toproto(L,i) getproto(s2v(L->top.p+(i)))
143 static const Proto
* combine(lua_State
* L
, int n
)
146 return toproto(L
,-1);
151 if (lua_load(L
,reader
,&i
,"=(" PROGNAME
")",NULL
)!=LUA_OK
) fatal(lua_tostring(L
,-1));
155 f
->p
[i
]=toproto(L
,i
-n
-1);
156 if (f
->p
[i
]->sizeupvalues
>0) f
->p
[i
]->upvalues
[0].instack
=0;
162 static int writer(lua_State
* L
, sjme_cpointer p
, size_t size
, void* u
)
165 return (fwrite(p
,size
,1,(FILE*)u
)!=1) && (size
!=0);
168 static int pmain(lua_State
* L
)
170 int argc
=(int)lua_tointeger(L
,1);
171 char** argv
=(char**)lua_touserdata(L
,2);
175 if (!lua_checkstack(L
,argc
)) fatal("too many input files");
176 for (i
=0; i
<argc
; i
++)
178 const char* filename
=IS("-") ? NULL
: argv
[i
];
179 if (luaL_loadfile(L
,filename
)!=LUA_OK
) fatal(lua_tostring(L
,-1));
182 if (listing
) luaU_print(f
,listing
>1);
185 FILE* D
= (output
==NULL
) ? stdout
: fopen(output
,"wb");
186 if (D
==NULL
) cannot("open");
188 luaU_dump(L
,f
,writer
,D
,stripping
);
190 if (ferror(D
)) cannot("write");
191 if (fclose(D
)) cannot("close");
196 int main(int argc
, char* argv
[])
199 int i
=doargs(argc
,argv
);
201 if (argc
<=0) usage("no input files given");
203 if (L
==NULL
) fatal("cannot create state: not enough memory");
204 lua_pushcfunction(L
,&pmain
);
205 lua_pushinteger(L
,argc
);
206 lua_pushlightuserdata(L
,argv
);
207 if (lua_pcall(L
,2,0,0)!=LUA_OK
) fatal(lua_tostring(L
,-1));
216 #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
217 #define VOID(p) ((const void*)(p))
218 #define eventname(i) (getstr(tmname[i]))
220 static void PrintString(const TString
* ts
)
222 const char* s
=getstr(ts
);
223 size_t i
,n
=tsslen(ts
);
227 int c
=(int)(unsigned char)s
[i
];
258 if (isprint(c
)) printf("%c",c
); else printf("\\%03d",c
);
265 static void PrintType(const Proto
* f
, int i
)
267 const TValue
* o
=&f
->k
[i
];
287 default: /* cannot happen */
288 printf("?%d",ttypetag(o
));
294 static void PrintConstant(const Proto
* f
, int i
)
296 const TValue
* o
=&f
->k
[i
];
311 sprintf(buff
,LUA_NUMBER_FMT
,fltvalue(o
));
313 if (buff
[strspn(buff
,"-0123456789")]=='\0') printf(".0");
317 printf(LUA_INTEGER_FMT
,ivalue(o
));
321 PrintString(tsvalue(o
));
323 default: /* cannot happen */
324 printf("?%d",ttypetag(o
));
329 #define COMMENT "\t; "
330 #define EXTRAARG GETARG_Ax(code[pc+1])
331 #define EXTRAARGC (EXTRAARG*(MAXARG_C+1))
332 #define ISK (isk ? "k" : "")
334 static void PrintCode(const Proto
* f
)
336 const Instruction
* code
=f
->code
;
337 int pc
,n
=f
->sizecode
;
338 for (pc
=0; pc
<n
; pc
++)
340 Instruction i
=code
[pc
];
341 OpCode o
=GET_OPCODE(i
);
349 int sbx
=GETARG_sBx(i
);
351 int line
=luaG_getfuncline(f
,pc
);
352 printf("\t%d\t",pc
+1);
353 if (line
>0) printf("[%d]\t",line
); else printf("[-]\t");
354 printf("%-9s\t",opnames
[o
]);
361 printf("%d %d",a
,sbx
);
364 printf("%d %d",a
,sbx
);
367 printf("%d %d",a
,bx
);
368 printf(COMMENT
); PrintConstant(f
,bx
);
372 printf(COMMENT
); PrintConstant(f
,EXTRAARG
);
385 printf(COMMENT
"%d out",b
+1);
389 printf(COMMENT
"%s",UPVALNAME(b
));
393 printf(COMMENT
"%s",UPVALNAME(b
));
396 printf("%d %d %d",a
,b
,c
);
397 printf(COMMENT
"%s",UPVALNAME(b
));
398 printf(" "); PrintConstant(f
,c
);
401 printf("%d %d %d",a
,b
,c
);
404 printf("%d %d %d",a
,b
,c
);
407 printf("%d %d %d",a
,b
,c
);
408 printf(COMMENT
); PrintConstant(f
,c
);
411 printf("%d %d %d%s",a
,b
,c
,ISK
);
412 printf(COMMENT
"%s",UPVALNAME(a
));
413 printf(" "); PrintConstant(f
,b
);
414 if (isk
) { printf(" "); PrintConstant(f
,c
); }
417 printf("%d %d %d%s",a
,b
,c
,ISK
);
418 if (isk
) { printf(COMMENT
); PrintConstant(f
,c
); }
421 printf("%d %d %d%s",a
,b
,c
,ISK
);
422 if (isk
) { printf(COMMENT
); PrintConstant(f
,c
); }
425 printf("%d %d %d%s",a
,b
,c
,ISK
);
426 printf(COMMENT
); PrintConstant(f
,b
);
427 if (isk
) { printf(" "); PrintConstant(f
,c
); }
430 printf("%d %d %d",a
,b
,c
);
431 printf(COMMENT
"%d",c
+EXTRAARGC
);
434 printf("%d %d %d%s",a
,b
,c
,ISK
);
435 if (isk
) { printf(COMMENT
); PrintConstant(f
,c
); }
438 printf("%d %d %d",a
,b
,sc
);
441 printf("%d %d %d",a
,b
,c
);
442 printf(COMMENT
); PrintConstant(f
,c
);
445 printf("%d %d %d",a
,b
,c
);
446 printf(COMMENT
); PrintConstant(f
,c
);
449 printf("%d %d %d",a
,b
,c
);
450 printf(COMMENT
); PrintConstant(f
,c
);
453 printf("%d %d %d",a
,b
,c
);
454 printf(COMMENT
); PrintConstant(f
,c
);
457 printf("%d %d %d",a
,b
,c
);
458 printf(COMMENT
); PrintConstant(f
,c
);
461 printf("%d %d %d",a
,b
,c
);
462 printf(COMMENT
); PrintConstant(f
,c
);
465 printf("%d %d %d",a
,b
,c
);
466 printf(COMMENT
); PrintConstant(f
,c
);
469 printf("%d %d %d",a
,b
,c
);
470 printf(COMMENT
); PrintConstant(f
,c
);
473 printf("%d %d %d",a
,b
,c
);
474 printf(COMMENT
); PrintConstant(f
,c
);
477 printf("%d %d %d",a
,b
,c
);
478 printf(COMMENT
); PrintConstant(f
,c
);
481 printf("%d %d %d",a
,b
,sc
);
484 printf("%d %d %d",a
,b
,sc
);
487 printf("%d %d %d",a
,b
,c
);
490 printf("%d %d %d",a
,b
,c
);
493 printf("%d %d %d",a
,b
,c
);
496 printf("%d %d %d",a
,b
,c
);
499 printf("%d %d %d",a
,b
,c
);
502 printf("%d %d %d",a
,b
,c
);
505 printf("%d %d %d",a
,b
,c
);
508 printf("%d %d %d",a
,b
,c
);
511 printf("%d %d %d",a
,b
,c
);
514 printf("%d %d %d",a
,b
,c
);
517 printf("%d %d %d",a
,b
,c
);
520 printf("%d %d %d",a
,b
,c
);
523 printf("%d %d %d",a
,b
,c
);
524 printf(COMMENT
"%s",eventname(c
));
527 printf("%d %d %d %d",a
,sb
,c
,isk
);
528 printf(COMMENT
"%s",eventname(c
));
529 if (isk
) printf(" flip");
532 printf("%d %d %d %d",a
,b
,c
,isk
);
533 printf(COMMENT
"%s ",eventname(c
)); PrintConstant(f
,b
);
534 if (isk
) printf(" flip");
558 printf("%d",GETARG_sJ(i
));
559 printf(COMMENT
"to %d",GETARG_sJ(i
)+pc
+2);
562 printf("%d %d %d",a
,b
,isk
);
565 printf("%d %d %d",a
,b
,isk
);
568 printf("%d %d %d",a
,b
,isk
);
571 printf("%d %d %d",a
,b
,isk
);
572 printf(COMMENT
); PrintConstant(f
,b
);
575 printf("%d %d %d",a
,sb
,isk
);
578 printf("%d %d %d",a
,sb
,isk
);
581 printf("%d %d %d",a
,sb
,isk
);
584 printf("%d %d %d",a
,sb
,isk
);
587 printf("%d %d %d",a
,sb
,isk
);
590 printf("%d %d",a
,isk
);
593 printf("%d %d %d",a
,b
,isk
);
596 printf("%d %d %d",a
,b
,c
);
598 if (b
==0) printf("all in "); else printf("%d in ",b
-1);
599 if (c
==0) printf("all out"); else printf("%d out",c
-1);
602 printf("%d %d %d%s",a
,b
,c
,ISK
);
603 printf(COMMENT
"%d in",b
-1);
606 printf("%d %d %d%s",a
,b
,c
,ISK
);
608 if (b
==0) printf("all out"); else printf("%d out",b
-1);
616 printf("%d %d",a
,bx
);
617 printf(COMMENT
"to %d",pc
-bx
+2);
620 printf("%d %d",a
,bx
);
621 printf(COMMENT
"exit to %d",pc
+bx
+3);
624 printf("%d %d",a
,bx
);
625 printf(COMMENT
"to %d",pc
+bx
+2);
631 printf("%d %d",a
,bx
);
632 printf(COMMENT
"to %d",pc
-bx
+2);
635 printf("%d %d %d",a
,b
,c
);
636 if (isk
) printf(COMMENT
"%d",c
+EXTRAARGC
);
639 printf("%d %d",a
,bx
);
640 printf(COMMENT
"%p",VOID(f
->p
[bx
]));
645 if (c
==0) printf("all out"); else printf("%d out",c
-1);
655 printf("%d %d %d",a
,b
,c
);
656 printf(COMMENT
"not handled");
665 #define SS(x) ((x==1)?"":"s")
666 #define S(x) (int)(x),SS(x)
668 static void PrintHeader(const Proto
* f
)
670 const char* s
=f
->source
? getstr(f
->source
) : "=?";
671 if (*s
=='@' || *s
=='=')
673 else if (*s
==LUA_SIGNATURE
[0])
677 printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
678 (f
->linedefined
==0)?"main":"function",s
,
679 f
->linedefined
,f
->lastlinedefined
,
680 S(f
->sizecode
),VOID(f
));
681 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
682 (int)(f
->numparams
),f
->is_vararg
?"+":"",SS(f
->numparams
),
683 S(f
->maxstacksize
),S(f
->sizeupvalues
));
684 printf("%d local%s, %d constant%s, %d function%s\n",
685 S(f
->sizelocvars
),S(f
->sizek
),S(f
->sizep
));
688 static void PrintDebug(const Proto
* f
)
692 printf("constants (%d) for %p:\n",n
,VOID(f
));
701 printf("locals (%d) for %p:\n",n
,VOID(f
));
704 printf("\t%d\t%s\t%d\t%d\n",
705 i
,getstr(f
->locvars
[i
].varname
),f
->locvars
[i
].startpc
+1,f
->locvars
[i
].endpc
+1);
708 printf("upvalues (%d) for %p:\n",n
,VOID(f
));
711 printf("\t%d\t%s\t%d\t%d\n",
712 i
,UPVALNAME(i
),f
->upvalues
[i
].instack
,f
->upvalues
[i
].idx
);
716 static void PrintFunction(const Proto
* f
, int full
)
721 if (full
) PrintDebug(f
);
722 for (i
=0; i
<n
; i
++) PrintFunction(f
->p
[i
],full
);