luac.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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. if (!s) s = strrchr(fn, '\\');
  156. s = s ? s + 1 : fn;
  157. while (*s == '.') s++;
  158. const char *e = strchr(s, '.');
  159. int l = e ? e - s: strlen(s);
  160. return l ? luaS_newlstr (L, s, l) : luaS_new(L, fn);
  161. }
  162. /*
  163. * If the luac command line includes multiple files or has the -f option
  164. * then luac generates a main function to reference all sub-main prototypes.
  165. * This is one of two types:
  166. * Type 0 The standard luac combination main
  167. * Type 1 A lookup wrapper that facilitates indexing into the generated protos
  168. */
  169. static const Proto* combine(lua_State* L, int n, int type)
  170. {
  171. if (n==1 && type == 0)
  172. return toproto(L,-1);
  173. else
  174. {
  175. int i;
  176. Instruction *pc;
  177. Proto* f=luaF_newproto(L);
  178. setptvalue2s(L,L->top,f); incr_top(L);
  179. f->source=luaS_newliteral(L,"=(" PROGNAME ")");
  180. f->p=luaM_newvector(L,n,Proto*);
  181. f->sizep=n;
  182. for (i=0; i<n; i++)
  183. f->p[i]=toproto(L,i-n-1);
  184. pc=0;
  185. if (type == 0) {
  186. /*
  187. * Type 0 is as per the standard luac, which is just a main routine which
  188. * invokes all of the compiled functions sequentially. This is fine if
  189. * they are self registering modules, but useless otherwise.
  190. */
  191. f->numparams = 0;
  192. f->maxstacksize = 1;
  193. f->sizecode = 2*n + 1 ;
  194. f->sizek = 0;
  195. f->code = luaM_newvector(L, f->sizecode , Instruction);
  196. f->k = luaM_newvector(L,f->sizek,TValue);
  197. for (i=0, pc = f->code; i<n; i++) {
  198. *pc++ = CREATE_ABx(OP_CLOSURE,0,i);
  199. *pc++ = CREATE_ABC(OP_CALL,0,1,1);
  200. }
  201. *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  202. } else {
  203. /*
  204. * The Type 1 main() is a lookup which takes a single argument, the name to
  205. * be resolved. If this matches root name of one of the compiled files then
  206. * a closure to this file main is returned. Otherwise the Unixtime of the
  207. * compile and the list of root names is returned.
  208. */
  209. if (n > LFIELDS_PER_FLUSH) {
  210. #define NO_MOD_ERR_(n) ": Number of modules > " #n
  211. #define NO_MOD_ERR(n) NO_MOD_ERR_(n)
  212. usage(LUA_QL("-f") NO_MOD_ERR(LFIELDS_PER_FLUSH));
  213. }
  214. f->numparams = 1;
  215. f->maxstacksize = n + 3;
  216. f->sizecode = 5*n + 5 ;
  217. f->sizek = n + 1;
  218. f->sizelocvars = 0;
  219. f->code = luaM_newvector(L, f->sizecode , Instruction);
  220. f->k = luaM_newvector(L,f->sizek,TValue);
  221. for (i=0, pc = f->code; i<n; i++)
  222. {
  223. /* if arg1 == FnameA then return function (...) -- funcA -- end end */
  224. setsvalue2n(L,f->k+i,corename(L, f->p[i]->source));
  225. *pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i));
  226. *pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2);
  227. *pc++ = CREATE_ABx(OP_CLOSURE,1,i);
  228. *pc++ = CREATE_ABC(OP_RETURN,1,2,0);
  229. }
  230. setnvalue(f->k+n, (lua_Number) time(NULL));
  231. *pc++ = CREATE_ABx(OP_LOADK,1,n);
  232. *pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0);
  233. for (i=0; i<n; i++)
  234. *pc++ = CREATE_ABx(OP_LOADK,i+3,i);
  235. *pc++ = CREATE_ABC(OP_SETLIST,2,i,1);
  236. *pc++ = CREATE_ABC(OP_RETURN,1,3,0);
  237. *pc++ = CREATE_ABC(OP_RETURN,0,1,0);
  238. }
  239. lua_assert((pc-f->code) == f->sizecode);
  240. return f;
  241. }
  242. }
  243. static int writer(lua_State* L, const void* p, size_t size, void* u)
  244. {
  245. UNUSED(L);
  246. return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
  247. }
  248. struct Smain {
  249. int argc;
  250. char** argv;
  251. };
  252. #if defined(_MSC_VER) || defined(__MINGW32__)
  253. typedef unsigned int uint;
  254. #endif
  255. extern uint dumpToFlashImage (lua_State* L,const Proto *main, lua_Writer w,
  256. void* data, int strip,
  257. lu_int32 address, lu_int32 maxSize);
  258. static int pmain(lua_State* L)
  259. {
  260. struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
  261. int argc=s->argc;
  262. char** argv=s->argv;
  263. const Proto* f;
  264. int i;
  265. if (!lua_checkstack(L,argc)) fatal("too many input files");
  266. if (execute)
  267. {
  268. if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
  269. luaL_openlibs(L);
  270. lua_pushstring(L, execute);
  271. if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
  272. if (!lua_isfunction(L, -1))
  273. {
  274. lua_pop(L,1);
  275. if(argc == 0) return 0;
  276. execute = NULL;
  277. }
  278. }
  279. for (i=0; i<argc; i++)
  280. {
  281. const char* filename=IS("-") ? NULL : argv[i];
  282. if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
  283. }
  284. f=combine(L,argc + (execute ? 1: 0), lookup);
  285. if (listing) luaU_print(f,listing>1);
  286. if (dumping)
  287. {
  288. int result;
  289. FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
  290. if (D==NULL) cannot("open");
  291. lua_lock(L);
  292. if (flash)
  293. {
  294. result=dumpToFlashImage(L,f,writer, D, stripping, address, maxSize);
  295. } else
  296. {
  297. result=luaU_dump_crosscompile(L,f,writer,D,stripping,target);
  298. }
  299. lua_unlock(L);
  300. if (result==LUA_ERR_CC_INTOVERFLOW) fatal("value too big or small for target integer type");
  301. if (result==LUA_ERR_CC_NOTINTEGER) fatal("target lua_Number is integral but fractional value found");
  302. if (ferror(D)) cannot("write");
  303. if (fclose(D)) cannot("close");
  304. }
  305. return 0;
  306. }
  307. int main(int argc, char* argv[])
  308. {
  309. lua_State* L;
  310. struct Smain s;
  311. int test=1;
  312. target.little_endian=*(char*)&test;
  313. target.sizeof_int=sizeof(int);
  314. target.sizeof_strsize_t=sizeof(strsize_t);
  315. target.sizeof_lua_Number=sizeof(lua_Number);
  316. target.lua_Number_integral=(((lua_Number)0.5)==0);
  317. target.is_arm_fpa=0;
  318. int i=doargs(argc,argv);
  319. argc-=i; argv+=i;
  320. if (argc<=0 && execute==0) usage("no input files given");
  321. L=lua_open();
  322. if (L==NULL) fatal("not enough memory for state");
  323. s.argc=argc;
  324. s.argv=argv;
  325. if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
  326. lua_close(L);
  327. return EXIT_SUCCESS;
  328. }