You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
9.8 KiB

  1. /*
  2. ** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $
  3. ** Lua compiler (saves bytecodes to files; also list bytecodes)
  4. ** See Copyright Notice in lua.h
  5. */
  6. #if defined HAVE_CONFIG_H // LOL BEGIN
  7. # include "config.h"
  8. #endif // LOL END
  9. #include <errno.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #define luac_c
  14. #define LUA_CORE
  15. #include "lua.h"
  16. #include "lauxlib.h"
  17. #include "lobject.h"
  18. #include "lstate.h"
  19. #include "lundump.h"
  20. static void PrintFunction(const Proto* f, int full);
  21. #define luaU_print PrintFunction
  22. #define PROGNAME "luac" /* default program name */
  23. #define OUTPUT PROGNAME ".out" /* default output file */
  24. static int listing=0; /* list bytecodes? */
  25. static int dumping=1; /* dump bytecodes? */
  26. static int stripping=0; /* strip debug information? */
  27. static char Output[]={ OUTPUT }; /* default output file name */
  28. static const char* output=Output; /* actual output file name */
  29. static const char* progname=PROGNAME; /* actual program name */
  30. static void fatal(const char* message)
  31. {
  32. fprintf(stderr,"%s: %s\n",progname,message);
  33. exit(EXIT_FAILURE);
  34. }
  35. static void cannot(const char* what)
  36. {
  37. fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
  38. exit(EXIT_FAILURE);
  39. }
  40. static void usage(const char* message)
  41. {
  42. if (*message=='-')
  43. fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
  44. else
  45. fprintf(stderr,"%s: %s\n",progname,message);
  46. fprintf(stderr,
  47. "usage: %s [options] [filenames]\n"
  48. "Available options are:\n"
  49. " -l list (use -l -l for full listing)\n"
  50. " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
  51. " -p parse only\n"
  52. " -s strip debug information\n"
  53. " -v show version information\n"
  54. " -- stop handling options\n"
  55. " - stop handling options and process stdin\n"
  56. ,progname,Output);
  57. exit(EXIT_FAILURE);
  58. }
  59. #define IS(s) (strcmp(argv[i],s)==0)
  60. static int doargs(int argc, char* argv[])
  61. {
  62. int i;
  63. int version=0;
  64. if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
  65. for (i=1; i<argc; i++)
  66. {
  67. if (*argv[i]!='-') /* end of options; keep it */
  68. break;
  69. else if (IS("--")) /* end of options; skip it */
  70. {
  71. ++i;
  72. if (version) ++version;
  73. break;
  74. }
  75. else if (IS("-")) /* end of options; use stdin */
  76. break;
  77. else if (IS("-l")) /* list */
  78. ++listing;
  79. else if (IS("-o")) /* output file */
  80. {
  81. output=argv[++i];
  82. if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
  83. usage(LUA_QL("-o") " needs argument");
  84. if (IS("-")) output=NULL;
  85. }
  86. else if (IS("-p")) /* parse only */
  87. dumping=0;
  88. else if (IS("-s")) /* strip debug information */
  89. stripping=1;
  90. else if (IS("-v")) /* show version */
  91. ++version;
  92. else /* unknown option */
  93. usage(argv[i]);
  94. }
  95. if (i==argc && (listing || !dumping))
  96. {
  97. dumping=0;
  98. argv[--i]=Output;
  99. }
  100. if (version)
  101. {
  102. printf("%s\n",LUA_COPYRIGHT);
  103. if (version==argc-1) exit(EXIT_SUCCESS);
  104. }
  105. return i;
  106. }
  107. #define FUNCTION "(function()end)();"
  108. static const char* reader(lua_State *L, void *ud, size_t *size)
  109. {
  110. UNUSED(L);
  111. if ((*(int*)ud)--)
  112. {
  113. *size=sizeof(FUNCTION)-1;
  114. return FUNCTION;
  115. }
  116. else
  117. {
  118. *size=0;
  119. return NULL;
  120. }
  121. }
  122. #define toproto(L,i) getproto(L->top+(i))
  123. static const Proto* combine(lua_State* L, int n)
  124. {
  125. if (n==1)
  126. return toproto(L,-1);
  127. else
  128. {
  129. Proto* f;
  130. int i=n;
  131. if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
  132. f=toproto(L,-1);
  133. for (i=0; i<n; i++)
  134. {
  135. f->p[i]=toproto(L,i-n-1);
  136. if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
  137. }
  138. f->sizelineinfo=0;
  139. return f;
  140. }
  141. }
  142. static int writer(lua_State* L, const void* p, size_t size, void* u)
  143. {
  144. UNUSED(L);
  145. return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
  146. }
  147. static int pmain(lua_State* L)
  148. {
  149. int argc=(int)lua_tointeger(L,1);
  150. char** argv=(char**)lua_touserdata(L,2);
  151. const Proto* f;
  152. int i;
  153. if (!lua_checkstack(L,argc)) fatal("too many input files");
  154. for (i=0; i<argc; i++)
  155. {
  156. const char* filename=IS("-") ? NULL : argv[i];
  157. if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
  158. }
  159. f=combine(L,argc);
  160. if (listing) luaU_print(f,listing>1);
  161. if (dumping)
  162. {
  163. FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
  164. if (D==NULL) cannot("open");
  165. lua_lock(L);
  166. luaU_dump(L,f,writer,D,stripping);
  167. lua_unlock(L);
  168. if (ferror(D)) cannot("write");
  169. if (fclose(D)) cannot("close");
  170. }
  171. return 0;
  172. }
  173. int main(int argc, char* argv[])
  174. {
  175. lua_State* L;
  176. int i=doargs(argc,argv);
  177. argc-=i; argv+=i;
  178. if (argc<=0) usage("no input files given");
  179. L=luaL_newstate();
  180. if (L==NULL) fatal("cannot create state: not enough memory");
  181. lua_pushcfunction(L,&pmain);
  182. lua_pushinteger(L,argc);
  183. lua_pushlightuserdata(L,argv);
  184. if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
  185. lua_close(L);
  186. return EXIT_SUCCESS;
  187. }
  188. /*
  189. ** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $
  190. ** print bytecodes
  191. ** See Copyright Notice in lua.h
  192. */
  193. #include <ctype.h>
  194. #include <stdio.h>
  195. #define luac_c
  196. #define LUA_CORE
  197. #include "ldebug.h"
  198. #include "lobject.h"
  199. #include "lopcodes.h"
  200. #define VOID(p) ((const void*)(p))
  201. static void PrintString(const TString* ts)
  202. {
  203. const char* s=getstr(ts);
  204. size_t i,n=ts->tsv.len;
  205. printf("%c",'"');
  206. for (i=0; i<n; i++)
  207. {
  208. int c=(int)(unsigned char)s[i];
  209. switch (c)
  210. {
  211. case '"': printf("\\\""); break;
  212. case '\\': printf("\\\\"); break;
  213. case '\a': printf("\\a"); break;
  214. case '\b': printf("\\b"); break;
  215. case '\f': printf("\\f"); break;
  216. case '\n': printf("\\n"); break;
  217. case '\r': printf("\\r"); break;
  218. case '\t': printf("\\t"); break;
  219. case '\v': printf("\\v"); break;
  220. default: if (isprint(c))
  221. printf("%c",c);
  222. else
  223. printf("\\%03d",c);
  224. }
  225. }
  226. printf("%c",'"');
  227. }
  228. static void PrintConstant(const Proto* f, int i)
  229. {
  230. const TValue* o=&f->k[i];
  231. switch (ttype(o))
  232. {
  233. case LUA_TNIL:
  234. printf("nil");
  235. break;
  236. case LUA_TBOOLEAN:
  237. printf(bvalue(o) ? "true" : "false");
  238. break;
  239. case LUA_TNUMBER:
  240. printf(LUA_NUMBER_FMT,nvalue(o));
  241. break;
  242. case LUA_TSTRING:
  243. PrintString(rawtsvalue(o));
  244. break;
  245. default: /* cannot happen */
  246. printf("? type=%d",ttype(o));
  247. break;
  248. }
  249. }
  250. #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
  251. #define MYK(x) (-1-(x))
  252. static void PrintCode(const Proto* f)
  253. {
  254. const Instruction* code=f->code;
  255. int pc,n=f->sizecode;
  256. for (pc=0; pc<n; pc++)
  257. {
  258. Instruction i=code[pc];
  259. OpCode o=GET_OPCODE(i);
  260. int a=GETARG_A(i);
  261. int b=GETARG_B(i);
  262. int c=GETARG_C(i);
  263. int ax=GETARG_Ax(i);
  264. int bx=GETARG_Bx(i);
  265. int sbx=GETARG_sBx(i);
  266. int line=getfuncline(f,pc);
  267. printf("\t%d\t",pc+1);
  268. if (line>0) printf("[%d]\t",line); else printf("[-]\t");
  269. printf("%-9s\t",luaP_opnames[o]);
  270. switch (getOpMode(o))
  271. {
  272. case iABC:
  273. printf("%d",a);
  274. if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
  275. if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
  276. break;
  277. case iABx:
  278. printf("%d",a);
  279. if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
  280. if (getBMode(o)==OpArgU) printf(" %d",bx);
  281. break;
  282. case iAsBx:
  283. printf("%d %d",a,sbx);
  284. break;
  285. case iAx:
  286. printf("%d",MYK(ax));
  287. break;
  288. }
  289. switch (o)
  290. {
  291. case OP_LOADK:
  292. printf("\t; "); PrintConstant(f,bx);
  293. break;
  294. case OP_GETUPVAL:
  295. case OP_SETUPVAL:
  296. printf("\t; %s",UPVALNAME(b));
  297. break;
  298. case OP_GETTABUP:
  299. printf("\t; %s",UPVALNAME(b));
  300. if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
  301. break;
  302. case OP_SETTABUP:
  303. printf("\t; %s",UPVALNAME(a));
  304. if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
  305. if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
  306. break;
  307. case OP_GETTABLE:
  308. case OP_SELF:
  309. if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
  310. break;
  311. case OP_SETTABLE:
  312. case OP_ADD:
  313. case OP_SUB:
  314. case OP_MUL:
  315. case OP_DIV:
  316. case OP_POW:
  317. case OP_EQ:
  318. case OP_LT:
  319. case OP_LE:
  320. if (ISK(b) || ISK(c))
  321. {
  322. printf("\t; ");
  323. if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
  324. printf(" ");
  325. if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
  326. }
  327. break;
  328. case OP_JMP:
  329. case OP_FORLOOP:
  330. case OP_FORPREP:
  331. case OP_TFORLOOP:
  332. printf("\t; to %d",sbx+pc+2);
  333. break;
  334. case OP_CLOSURE:
  335. printf("\t; %p",VOID(f->p[bx]));
  336. break;
  337. case OP_SETLIST:
  338. if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
  339. break;
  340. case OP_EXTRAARG:
  341. printf("\t; "); PrintConstant(f,ax);
  342. break;
  343. default:
  344. break;
  345. }
  346. printf("\n");
  347. }
  348. }
  349. #define SS(x) ((x==1)?"":"s")
  350. #define S(x) (int)(x),SS(x)
  351. static void PrintHeader(const Proto* f)
  352. {
  353. const char* s=f->source ? getstr(f->source) : "=?";
  354. if (*s=='@' || *s=='=')
  355. s++;
  356. else if (*s==LUA_SIGNATURE[0])
  357. s="(bstring)";
  358. else
  359. s="(string)";
  360. printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
  361. (f->linedefined==0)?"main":"function",s,
  362. f->linedefined,f->lastlinedefined,
  363. S(f->sizecode),VOID(f));
  364. printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
  365. (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
  366. S(f->maxstacksize),S(f->sizeupvalues));
  367. printf("%d local%s, %d constant%s, %d function%s\n",
  368. S(f->sizelocvars),S(f->sizek),S(f->sizep));
  369. }
  370. static void PrintDebug(const Proto* f)
  371. {
  372. int i,n;
  373. n=f->sizek;
  374. printf("constants (%d) for %p:\n",n,VOID(f));
  375. for (i=0; i<n; i++)
  376. {
  377. printf("\t%d\t",i+1);
  378. PrintConstant(f,i);
  379. printf("\n");
  380. }
  381. n=f->sizelocvars;
  382. printf("locals (%d) for %p:\n",n,VOID(f));
  383. for (i=0; i<n; i++)
  384. {
  385. printf("\t%d\t%s\t%d\t%d\n",
  386. i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
  387. }
  388. n=f->sizeupvalues;
  389. printf("upvalues (%d) for %p:\n",n,VOID(f));
  390. for (i=0; i<n; i++)
  391. {
  392. printf("\t%d\t%s\t%d\t%d\n",
  393. i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
  394. }
  395. }
  396. static void PrintFunction(const Proto* f, int full)
  397. {
  398. int i,n=f->sizep;
  399. PrintHeader(f);
  400. PrintCode(f);
  401. if (full) PrintDebug(f);
  402. for (i=0; i<n; i++) PrintFunction(f->p[i],full);
  403. }