luac.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. ** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $
  3. ** Lua compiler (saves bytecodes to files; also list bytecodes)
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define LUAC_CROSS_FILE
  7. #include "luac_cross.h"
  8. #include C_HEADER_ERRNO
  9. #include C_HEADER_STDIO
  10. #include C_HEADER_STDLIB
  11. #include C_HEADER_STRING
  12. #include <time.h>
  13. #define luac_c
  14. #define LUA_CORE
  15. #include "lua.h"
  16. #include "lauxlib.h"
  17. #include "lualib.h"
  18. #include "ldo.h"
  19. #include "lfunc.h"
  20. #include "lmem.h"
  21. #include "lobject.h"
  22. #include "lopcodes.h"
  23. #include "lstring.h"
  24. #include "lundump.h"
  25. #define PROGNAME "luac" /* default program name */
  26. #define OUTPUT PROGNAME ".out" /* default output file */
  27. static int listing=0; /* list bytecodes? */
  28. static int dumping=1; /* dump bytecodes? */
  29. static int stripping=0; /* strip debug information? */
  30. static int flash=0; /* output flash image */
  31. static lu_int32 address=0; /* output flash image at absolute location */
  32. static lu_int32 maxSize=0x40000; /* maximuum uncompressed image size */
  33. static int lookup=0; /* output lookup-style master combination header */
  34. static char Output[]={ OUTPUT }; /* default output file name */
  35. static const char* output=Output; /* actual output file name */
  36. static const char* execute; /* executed a Lua file */
  37. static const char* progname=PROGNAME; /* actual program name */
  38. static DumpTargetInfo target;
  39. void luac_fatal(const char* message)
  40. {
  41. fprintf(stderr,"%s: %s\n",progname,message);
  42. exit(EXIT_FAILURE);
  43. }
  44. #define fatal(s) luac_fatal(s)
  45. static void cannot(const char* what)
  46. {
  47. fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
  48. exit(EXIT_FAILURE);
  49. }
  50. static void usage(const char* message)
  51. {
  52. if (*message=='-')
  53. fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
  54. else
  55. fprintf(stderr,"%s: %s\n",progname,message);
  56. fprintf(stderr,
  57. "usage: %s [options] [filenames].\n"
  58. "Available options are:\n"
  59. " - process stdin\n"
  60. " -l list\n"
  61. " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
  62. " -e name execute a lua source file\n"
  63. " -f output a flash image file\n"
  64. " -a addr generate an absolute, rather than position independent flash image file\n"
  65. " -i generate lookup combination master (default with option -f)\n"
  66. " -m size maximum LFS image in bytes\n"
  67. " -p parse only\n"
  68. " -s strip debug information\n"
  69. " -v show version information\n"
  70. " -- stop handling options\n",
  71. progname,Output);
  72. exit(EXIT_FAILURE);
  73. }
  74. #define IS(s) (strcmp(argv[i],s)==0)
  75. #define IROM0_SEG 0x40210000ul
  76. #define IROM0_SEGMAX 0x00100000ul
  77. static int doargs(int argc, char* argv[])
  78. {
  79. int i;
  80. int version=0;
  81. if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
  82. for (i=1; i<argc; i++)
  83. {
  84. if (*argv[i]!='-') /* end of options; keep it */
  85. break;
  86. else if (IS("--")) /* end of options; skip it */
  87. {
  88. ++i;
  89. if (version) ++version;
  90. break;
  91. }
  92. else if (IS("-")) /* end of options; use stdin */
  93. break;
  94. else if (IS("-e")) /* execute a lua source file file */
  95. {
  96. execute=argv[++i];
  97. if (execute ==NULL || *execute==0 || *execute=='-' )
  98. usage(LUA_QL("-e") " needs argument");
  99. }
  100. else if (IS("-f")) /* Flash image file */
  101. {
  102. flash=lookup=1;
  103. }
  104. else if (IS("-a")) /* Absolue flash image file */
  105. {
  106. flash=lookup=1;
  107. address=strtol(argv[++i],NULL,0);
  108. size_t offset = (unsigned) (address -IROM0_SEG);
  109. if (offset > IROM0_SEGMAX)
  110. usage(LUA_QL("-e") " absolute address must be valid flash address");
  111. }
  112. else if (IS("-i")) /* lookup */
  113. lookup = 1;
  114. else if (IS("-l")) /* list */
  115. ++listing;
  116. else if (IS("-m")) /* specify a maximum image size */
  117. {
  118. flash=lookup=1;
  119. maxSize=strtol(argv[++i],NULL,0);
  120. if (maxSize & 0xFFF)
  121. usage(LUA_QL("-e") " maximum size must be a multiple of 4,096");
  122. }
  123. else if (IS("-o")) /* output file */
  124. {
  125. output=argv[++i];
  126. if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
  127. if (IS("-")) output=NULL;
  128. }
  129. else if (IS("-p")) /* parse only */
  130. dumping=0;
  131. else if (IS("-s")) /* strip debug information */
  132. stripping=1;
  133. else if (IS("-v")) /* show version */
  134. ++version;
  135. else /* unknown option */
  136. usage(argv[i]);
  137. }
  138. if (i==argc && (listing || !dumping))
  139. {
  140. dumping=0;
  141. argv[--i]=Output;
  142. }
  143. if (version)
  144. {
  145. printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT);
  146. if (version==argc-1) exit(EXIT_SUCCESS);
  147. }
  148. return i;
  149. }
  150. #define toproto(L,i) (clvalue(L->top+(i))->l.p)
  151. static TString *corename(lua_State *L, const TString *filename)
  152. {
  153. const char *fn = getstr(filename)+1;
  154. const char *s = strrchr(fn, '/');
  155. s = s ? s + 1 : fn;
  156. while (*s == '.') s++;
  157. const char *e = strchr(s, '.');
  158. int l = e ? e - s: strlen(s);
  159. return l ? luaS_newlstr (L, s, l) : luaS_new(L, fn);
  160. }
  161. /*
  162. * If the luac command line includes multiple files or has the -f option
  163. * then luac generates a main function to reference all sub-main prototypes.
  164. * This is one of two types:
  165. * Type 0 The standard luac combination main
  166. * Type 1 A lookup wrapper that facilitates indexing into the generated protos
  167. */
  168. static const Proto* combine(lua_State* L, int n, int type)
  169. {
  170. if (n==1 && type == 0)
  171. return toproto(L,-1);
  172. else
  173. {
  174. int i;
  175. Instruction *pc;
  176. Proto* f=luaF_newproto(L);
  177. setptvalue2s(L,L->top,f); incr_top(L);
  178. f->source=luaS_newliteral(L,"=(" PROGNAME ")");
  179. f->p=luaM_newvector(L,n,Proto*);
  180. f->sizep=n;
  181. for (i=0; i<n; i++)
  182. f->p[i]=toproto(L,i-n-1);
  183. pc=0;
  184. if (type == 0) {
  185. /*
  186. * Type 0 is as per the standard luac, which is just a main routine which
  187. * invokes all of the compiled functions sequentially. This is fine if
  188. * they are self registering modules, but useless otherwise.
  189. */
  190. f->numparams = 0;
  191. f->maxstacksize = 1;
  192. f->sizecode = 2*n + 1 ;
  193. f->sizek = 0;
  194. f->code = luaM_newvector(L, f->sizecode , Instruction);
  195. f->k = luaM_newvector(L,f->sizek,TValue);
  196. for (i=0, pc = f->code; i<n; i++) {
  197. *pc++ = CREATE_ABx(OP_CLOSURE,0,i);
  198. *pc++ = CREATE_ABC(OP_CALL,0,1,1);
  199. }
  200. *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  201. } else {
  202. /*
  203. * The Type 1 main() is a lookup which takes a single argument, the name to
  204. * be resolved. If this matches root name of one of the compiled files then
  205. * a closure to this file main is returned. Otherwise the Unixtime of the
  206. * compile and the list of root names is returned.
  207. */
  208. if (n > LFIELDS_PER_FLUSH) {
  209. #define NO_MOD_ERR_(n) ": Number of modules > " #n
  210. #define NO_MOD_ERR(n) NO_MOD_ERR_(n)
  211. usage(LUA_QL("-f") NO_MOD_ERR(LFIELDS_PER_FLUSH));
  212. }
  213. f->numparams = 1;
  214. f->maxstacksize = n + 3;
  215. f->sizecode = 5*n + 5 ;
  216. f->sizek = n + 1;
  217. f->sizelocvars = 0;
  218. f->code = luaM_newvector(L, f->sizecode , Instruction);
  219. f->k = luaM_newvector(L,f->sizek,TValue);
  220. for (i=0, pc = f->code; i<n; i++)
  221. {
  222. /* if arg1 == FnameA then return function (...) -- funcA -- end end */
  223. setsvalue2n(L,f->k+i,corename(L, f->p[i]->source));
  224. *pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i));
  225. *pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2);
  226. *pc++ = CREATE_ABx(OP_CLOSURE,1,i);
  227. *pc++ = CREATE_ABC(OP_RETURN,1,2,0);
  228. }
  229. setnvalue(f->k+n, (lua_Number) time(NULL));
  230. *pc++ = CREATE_ABx(OP_LOADK,1,n);
  231. *pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0);
  232. for (i=0; i<n; i++)
  233. *pc++ = CREATE_ABx(OP_LOADK,i+3,i);
  234. *pc++ = CREATE_ABC(OP_SETLIST,2,i,1);
  235. *pc++ = CREATE_ABC(OP_RETURN,1,3,0);
  236. *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  237. }
  238. lua_assert((pc-f->code) == f->sizecode);
  239. return f;
  240. }
  241. }
  242. static int writer(lua_State* L, const void* p, size_t size, void* u)
  243. {
  244. UNUSED(L);
  245. return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
  246. }
  247. struct Smain {
  248. int argc;
  249. char** argv;
  250. };
  251. extern uint dumpToFlashImage (lua_State* L,const Proto *main, lua_Writer w,
  252. void* data, int strip,
  253. lu_int32 address, lu_int32 maxSize);
  254. static int pmain(lua_State* L)
  255. {
  256. struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
  257. int argc=s->argc;
  258. char** argv=s->argv;
  259. const Proto* f;
  260. int i;
  261. if (!lua_checkstack(L,argc)) fatal("too many input files");
  262. if (execute)
  263. {
  264. if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
  265. luaL_openlibs(L);
  266. lua_pushstring(L, execute);
  267. if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
  268. if (!lua_isfunction(L, -1))
  269. {
  270. lua_pop(L,1);
  271. if(argc == 0) return 0;
  272. execute = NULL;
  273. }
  274. }
  275. for (i=0; i<argc; i++)
  276. {
  277. const char* filename=IS("-") ? NULL : argv[i];
  278. if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
  279. }
  280. f=combine(L,argc + (execute ? 1: 0), lookup);
  281. if (listing) luaU_print(f,listing>1);
  282. if (dumping)
  283. {
  284. int result;
  285. FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
  286. if (D==NULL) cannot("open");
  287. lua_lock(L);
  288. if (flash)
  289. {
  290. result=dumpToFlashImage(L,f,writer, D, stripping, address, maxSize);
  291. } else
  292. {
  293. result=luaU_dump_crosscompile(L,f,writer,D,stripping,target);
  294. }
  295. lua_unlock(L);
  296. if (result==LUA_ERR_CC_INTOVERFLOW) fatal("value too big or small for target integer type");
  297. if (result==LUA_ERR_CC_NOTINTEGER) fatal("target lua_Number is integral but fractional value found");
  298. if (ferror(D)) cannot("write");
  299. if (fclose(D)) cannot("close");
  300. }
  301. return 0;
  302. }
  303. int main(int argc, char* argv[])
  304. {
  305. lua_State* L;
  306. struct Smain s;
  307. int test=1;
  308. target.little_endian=*(char*)&test;
  309. target.sizeof_int=sizeof(int);
  310. target.sizeof_strsize_t=sizeof(strsize_t);
  311. target.sizeof_lua_Number=sizeof(lua_Number);
  312. target.lua_Number_integral=(((lua_Number)0.5)==0);
  313. target.is_arm_fpa=0;
  314. int i=doargs(argc,argv);
  315. argc-=i; argv+=i;
  316. if (argc<=0 && execute==0) usage("no input files given");
  317. L=lua_open();
  318. if (L==NULL) fatal("not enough memory for state");
  319. s.argc=argc;
  320. s.argv=argv;
  321. if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
  322. lua_close(L);
  323. return EXIT_SUCCESS;
  324. }