lundump.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
  3. ** load precompiled Lua chunks
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define lundump_c
  7. #define LUA_CORE
  8. #include "lua.h"
  9. #include <string.h>
  10. #include "ldebug.h"
  11. #include "ldo.h"
  12. #include "lfunc.h"
  13. #include "lmem.h"
  14. #include "lobject.h"
  15. #include "lstring.h"
  16. #include "lundump.h"
  17. #include "lzio.h"
  18. typedef struct {
  19. lua_State* L;
  20. ZIO* Z;
  21. Mbuffer* b;
  22. const char* name;
  23. int swap;
  24. int numsize;
  25. int toflt;
  26. size_t total;
  27. } LoadState;
  28. #ifdef LUAC_TRUST_BINARIES
  29. #define IF(c,s)
  30. #define error(S,s)
  31. #else
  32. #define IF(c,s) if (c) error(S,s)
  33. static void error(LoadState* S, const char* why)
  34. {
  35. luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
  36. luaD_throw(S->L,LUA_ERRSYNTAX);
  37. }
  38. #endif
  39. #define LoadByte(S) (lu_byte)LoadChar(S)
  40. #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
  41. #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
  42. static void LoadBlock(LoadState* S, void* b, size_t size)
  43. {
  44. size_t r=luaZ_read(S->Z,b,size);
  45. IF (r!=0, "unexpected end");
  46. S->total+=size;
  47. }
  48. static void LoadMem (LoadState* S, void* b, int n, size_t size)
  49. {
  50. LoadBlock(S,b,n*size);
  51. if (S->swap && b)
  52. {
  53. char* p=(char*) b;
  54. char c;
  55. switch (size)
  56. {
  57. case 1:
  58. break;
  59. case 2:
  60. while (n--)
  61. {
  62. c=p[0]; p[0]=p[1]; p[1]=c;
  63. p+=2;
  64. }
  65. break;
  66. case 4:
  67. while (n--)
  68. {
  69. c=p[0]; p[0]=p[3]; p[3]=c;
  70. c=p[1]; p[1]=p[2]; p[2]=c;
  71. p+=4;
  72. }
  73. break;
  74. case 8:
  75. while (n--)
  76. {
  77. c=p[0]; p[0]=p[7]; p[7]=c;
  78. c=p[1]; p[1]=p[6]; p[6]=c;
  79. c=p[2]; p[2]=p[5]; p[5]=c;
  80. c=p[3]; p[3]=p[4]; p[4]=c;
  81. p+=8;
  82. }
  83. break;
  84. default:
  85. IF(1, "bad size");
  86. break;
  87. }
  88. }
  89. }
  90. static int LoadChar(LoadState* S)
  91. {
  92. char x;
  93. LoadVar(S,x);
  94. return x;
  95. }
  96. static void Align4(LoadState* S)
  97. {
  98. while(S->total&3)
  99. LoadChar(S);
  100. }
  101. static int LoadInt(LoadState* S)
  102. {
  103. int x;
  104. LoadVar(S,x);
  105. IF (x<0, "bad integer");
  106. return x;
  107. }
  108. static lua_Number LoadNumber(LoadState* S)
  109. {
  110. lua_Number x;
  111. if(S->toflt)
  112. {
  113. switch(S->numsize)
  114. {
  115. case 1: {
  116. int8_t y;
  117. LoadVar(S,y);
  118. x = (lua_Number)y;
  119. } break;
  120. case 2: {
  121. int16_t y;
  122. LoadVar(S,y);
  123. x = (lua_Number)y;
  124. } break;
  125. case 4: {
  126. int32_t y;
  127. LoadVar(S,y);
  128. x = (lua_Number)y;
  129. } break;
  130. case 8: {
  131. int64_t y;
  132. LoadVar(S,y);
  133. x = (lua_Number)y;
  134. } break;
  135. default: lua_assert(0);
  136. }
  137. }
  138. else
  139. {
  140. LoadVar(S,x); /* should probably handle more cases for float here... */
  141. }
  142. return x;
  143. }
  144. static TString* LoadString(LoadState* S)
  145. {
  146. int32_t size;
  147. LoadVar(S,size);
  148. if (size==0)
  149. return NULL;
  150. else
  151. {
  152. char* s = luaZ_openspace(S->L,S->b,size);
  153. LoadBlock(S,s,size);
  154. return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
  155. }
  156. }
  157. static void LoadCode(LoadState* S, Proto* f)
  158. {
  159. int n=LoadInt(S);
  160. Align4(S);
  161. f->code=luaM_newvector(S->L,n,Instruction);
  162. LoadVector(S,f->code,n,sizeof(Instruction));
  163. f->sizecode=n;
  164. }
  165. static Proto* LoadFunction(LoadState* S, TString* p);
  166. static void LoadConstants(LoadState* S, Proto* f)
  167. {
  168. int i,n;
  169. n=LoadInt(S);
  170. f->k=luaM_newvector(S->L,n,TValue);
  171. f->sizek=n;
  172. for (i=0; i<n; i++) setnilvalue(&f->k[i]);
  173. for (i=0; i<n; i++)
  174. {
  175. TValue* o=&f->k[i];
  176. int t=LoadChar(S);
  177. switch (t)
  178. {
  179. case LUA_TNIL:
  180. setnilvalue(o);
  181. break;
  182. case LUA_TBOOLEAN:
  183. setbvalue(o,LoadChar(S)!=0);
  184. break;
  185. case LUA_TNUMBER:
  186. setnvalue(o,LoadNumber(S));
  187. break;
  188. case LUA_TSTRING:
  189. setsvalue2n(S->L,o,LoadString(S));
  190. break;
  191. default:
  192. error(S,"bad constant");
  193. break;
  194. }
  195. }
  196. n=LoadInt(S);
  197. f->p=luaM_newvector(S->L,n,Proto*);
  198. f->sizep=n;
  199. for (i=0; i<n; i++) f->p[i]=NULL;
  200. for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
  201. }
  202. static void LoadDebug(LoadState* S, Proto* f)
  203. {
  204. int i,n;
  205. n=LoadInt(S);
  206. Align4(S);
  207. if(n) {
  208. f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
  209. LoadBlock(S,f->packedlineinfo,n);
  210. } else {
  211. f->packedlineinfo=NULL;
  212. }
  213. n=LoadInt(S);
  214. f->locvars=luaM_newvector(S->L,n,LocVar);
  215. f->sizelocvars=n;
  216. for (i=0; i<n; i++) f->locvars[i].varname=NULL;
  217. for (i=0; i<n; i++)
  218. {
  219. f->locvars[i].varname=LoadString(S);
  220. f->locvars[i].startpc=LoadInt(S);
  221. f->locvars[i].endpc=LoadInt(S);
  222. }
  223. n=LoadInt(S);
  224. f->upvalues=luaM_newvector(S->L,n,TString*);
  225. f->sizeupvalues=n;
  226. for (i=0; i<n; i++) f->upvalues[i]=NULL;
  227. for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
  228. }
  229. static Proto* LoadFunction(LoadState* S, TString* p)
  230. {
  231. Proto* f;
  232. if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
  233. f=luaF_newproto(S->L);
  234. setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
  235. f->source=LoadString(S); if (f->source==NULL) f->source=p;
  236. f->linedefined=LoadInt(S);
  237. f->lastlinedefined=LoadInt(S);
  238. f->nups=LoadByte(S);
  239. f->numparams=LoadByte(S);
  240. f->is_vararg=LoadByte(S);
  241. f->maxstacksize=LoadByte(S);
  242. LoadCode(S,f);
  243. LoadConstants(S,f);
  244. LoadDebug(S,f);
  245. IF (!luaG_checkcode(f), "bad code");
  246. S->L->top--;
  247. S->L->nCcalls--;
  248. return f;
  249. }
  250. static void LoadHeader(LoadState* S)
  251. {
  252. char h[LUAC_HEADERSIZE];
  253. char s[LUAC_HEADERSIZE];
  254. int intck = (((lua_Number)0.5)==0); /* 0=float, 1=int */
  255. luaU_header(h);
  256. LoadBlock(S,s,LUAC_HEADERSIZE);
  257. S->swap=(s[6]!=h[6]); s[6]=h[6]; /* Check if byte-swapping is needed */
  258. S->numsize=h[10]=s[10]; /* length of lua_Number */
  259. S->toflt=(s[11]>intck); /* check if conversion from int lua_Number to flt is needed */
  260. if(S->toflt) s[11]=h[11];
  261. IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
  262. }
  263. /*
  264. ** load precompiled chunk
  265. */
  266. Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
  267. {
  268. LoadState S;
  269. if (*name=='@' || *name=='=')
  270. S.name=name+1;
  271. else if (*name==LUA_SIGNATURE[0])
  272. S.name="binary string";
  273. else
  274. S.name=name;
  275. S.L=L;
  276. S.Z=Z;
  277. S.b=buff;
  278. LoadHeader(&S);
  279. S.total=0;
  280. return LoadFunction(&S,luaS_newliteral(L,"=?"));
  281. }
  282. /*
  283. * make header
  284. */
  285. void luaU_header (char* h)
  286. {
  287. int x=1;
  288. memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
  289. h+=sizeof(LUA_SIGNATURE)-1;
  290. *h++=(char)LUAC_VERSION;
  291. *h++=(char)LUAC_FORMAT;
  292. *h++=(char)*(char*)&x; /* endianness */
  293. *h++=(char)sizeof(int);
  294. *h++=(char)sizeof(int32_t);
  295. *h++=(char)sizeof(Instruction);
  296. *h++=(char)sizeof(lua_Number);
  297. *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
  298. }