lundump.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. ** $Id: lundump.c,v 2.4 2005/05/05 20:47:02 roberto Exp roberto $
  3. ** load pre-compiled Lua chunks
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define lundump_c
  7. #define LUA_CORE
  8. #include "lua.h"
  9. #include "ldebug.h"
  10. #include "ldo.h"
  11. #include "lfunc.h"
  12. #include "lmem.h"
  13. #include "lopcodes.h"
  14. #include "lstring.h"
  15. #include "lundump.h"
  16. #include "lzio.h"
  17. #define LoadByte (lu_byte) ezgetc
  18. typedef struct {
  19. lua_State* L;
  20. ZIO* Z;
  21. Mbuffer* b;
  22. int swap;
  23. const char* name;
  24. } LoadState;
  25. static void unexpectedEOZ (LoadState* S)
  26. {
  27. luaG_runerror(S->L,"unexpected end of file in %s",S->name);
  28. }
  29. static int ezgetc (LoadState* S)
  30. {
  31. int c=zgetc(S->Z);
  32. if (c==EOZ) unexpectedEOZ(S);
  33. return c;
  34. }
  35. static void ezread (LoadState* S, void* b, size_t n)
  36. {
  37. size_t r=luaZ_read(S->Z,b,n);
  38. if (r!=0) unexpectedEOZ(S);
  39. }
  40. static void LoadBlock (LoadState* S, void* b, size_t size)
  41. {
  42. if (S->swap)
  43. {
  44. char* p=(char*) b+size-1;
  45. size_t n=size;
  46. while (n--) *p--=(char)ezgetc(S);
  47. }
  48. else
  49. ezread(S,b,size);
  50. }
  51. static void LoadVector (LoadState* S, void* b, int m, size_t size)
  52. {
  53. if (S->swap)
  54. {
  55. char* q=(char*) b;
  56. while (m--)
  57. {
  58. char* p=q+size-1;
  59. size_t n=size;
  60. while (n--) *p--=(char)ezgetc(S);
  61. q+=size;
  62. }
  63. }
  64. else
  65. ezread(S,b,m*size);
  66. }
  67. static int LoadInt (LoadState* S)
  68. {
  69. int x;
  70. LoadBlock(S,&x,sizeof(x));
  71. if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name);
  72. return x;
  73. }
  74. static size_t LoadSize (LoadState* S)
  75. {
  76. size_t x;
  77. LoadBlock(S,&x,sizeof(x));
  78. return x;
  79. }
  80. static lua_Number LoadNumber (LoadState* S)
  81. {
  82. lua_Number x;
  83. LoadBlock(S,&x,sizeof(x));
  84. return x;
  85. }
  86. static TString* LoadString (LoadState* S)
  87. {
  88. size_t size=LoadSize(S);
  89. if (size==0)
  90. return NULL;
  91. else
  92. {
  93. char* s=luaZ_openspace(S->L,S->b,size);
  94. ezread(S,s,size);
  95. return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
  96. }
  97. }
  98. static void LoadCode (LoadState* S, Proto* f)
  99. {
  100. int size=LoadInt(S);
  101. f->code=luaM_newvector(S->L,size,Instruction);
  102. f->sizecode=size;
  103. LoadVector(S,f->code,size,sizeof(*f->code));
  104. }
  105. static void LoadLocals (LoadState* S, Proto* f)
  106. {
  107. int i,n;
  108. n=LoadInt(S);
  109. f->locvars=luaM_newvector(S->L,n,LocVar);
  110. f->sizelocvars=n;
  111. for (i=0; i<n; i++) f->locvars[i].varname=NULL;
  112. for (i=0; i<n; i++)
  113. {
  114. f->locvars[i].varname=LoadString(S);
  115. f->locvars[i].startpc=LoadInt(S);
  116. f->locvars[i].endpc=LoadInt(S);
  117. }
  118. }
  119. static void LoadLines (LoadState* S, Proto* f)
  120. {
  121. int size=LoadInt(S);
  122. f->lineinfo=luaM_newvector(S->L,size,int);
  123. f->sizelineinfo=size;
  124. LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
  125. }
  126. static void LoadUpvalues (LoadState* S, Proto* f)
  127. {
  128. int i,n;
  129. n=LoadInt(S);
  130. if (n!=0 && n!=f->nups)
  131. luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
  132. S->name,n,f->nups);
  133. f->upvalues=luaM_newvector(S->L,n,TString*);
  134. f->sizeupvalues=n;
  135. for (i=0; i<n; i++) f->upvalues[i]=NULL;
  136. for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
  137. }
  138. static Proto* LoadFunction (LoadState* S, TString* p);
  139. static void LoadConstants (LoadState* S, Proto* f)
  140. {
  141. int i,n;
  142. lua_State *L=S->L;
  143. n=LoadInt(S);
  144. f->k=luaM_newvector(L,n,TValue);
  145. f->sizek=n;
  146. for (i=0; i<n; i++) setnilvalue(&f->k[i]);
  147. for (i=0; i<n; i++)
  148. {
  149. TValue* o=&f->k[i];
  150. int t=LoadByte(S);
  151. switch (t)
  152. {
  153. case LUA_TNUMBER:
  154. setnvalue(o,LoadNumber(S));
  155. break;
  156. case LUA_TSTRING:
  157. setsvalue2n(L, o,LoadString(S));
  158. break;
  159. case LUA_TNIL:
  160. setnilvalue(o);
  161. break;
  162. case LUA_TBOOLEAN:
  163. setbvalue(o, LoadByte(S));
  164. break;
  165. default:
  166. luaG_runerror(L,"bad constant type (%d) in %s",t,S->name);
  167. break;
  168. }
  169. }
  170. n=LoadInt(S);
  171. f->p=luaM_newvector(L,n,Proto*);
  172. f->sizep=n;
  173. for (i=0; i<n; i++) f->p[i]=NULL;
  174. for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
  175. }
  176. static Proto* LoadFunction (LoadState* S, TString* p)
  177. {
  178. lua_State *L=S->L;
  179. Proto* f=luaF_newproto(L);
  180. setptvalue2s(L, L->top, f);
  181. incr_top(L);
  182. f->source=LoadString(S); if (f->source==NULL) f->source=p;
  183. f->linedefined=LoadInt(S);
  184. f->lastlinedefined=LoadInt(S);
  185. f->nups=LoadByte(S);
  186. f->numparams=LoadByte(S);
  187. f->is_vararg=LoadByte(S);
  188. f->maxstacksize=LoadByte(S);
  189. LoadLines(S,f);
  190. LoadLocals(S,f);
  191. LoadUpvalues(S,f);
  192. LoadConstants(S,f);
  193. LoadCode(S,f);
  194. #ifndef TRUST_BINARIES
  195. if (!luaG_checkcode(f)) luaG_runerror(L,"bad code in %s",S->name);
  196. #endif
  197. L->top--;
  198. return f;
  199. }
  200. static void LoadSignature (LoadState* S)
  201. {
  202. const char* s=LUA_SIGNATURE;
  203. while (*s!=0 && ezgetc(S)==*s)
  204. ++s;
  205. if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name);
  206. }
  207. static void TestSize (LoadState* S, int s, const char* what)
  208. {
  209. int r=LoadByte(S);
  210. if (r!=s)
  211. luaG_runerror(S->L,"virtual machine mismatch in %s: "
  212. "size of %s is %d but read %d",S->name,what,s,r);
  213. }
  214. #define TESTSIZE(s,w) TestSize(S,s,w)
  215. #define V(v) v/16,v%16
  216. static void LoadHeader (LoadState* S)
  217. {
  218. int version;
  219. lua_Number x,tx=TEST_NUMBER;
  220. LoadSignature(S);
  221. version=LoadByte(S);
  222. if (version>VERSION)
  223. luaG_runerror(S->L,"%s too new: "
  224. "read version %d.%d; expected at most %d.%d",
  225. S->name,V(version),V(VERSION));
  226. if (version<VERSION0) /* check last major change */
  227. luaG_runerror(S->L,"%s too old: "
  228. "read version %d.%d; expected at least %d.%d",
  229. S->name,V(version),V(VERSION0));
  230. S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
  231. TESTSIZE(sizeof(int),"int");
  232. TESTSIZE(sizeof(size_t), "size_t");
  233. TESTSIZE(sizeof(Instruction), "Instruction");
  234. TESTSIZE(sizeof(lua_Number), "number");
  235. x=LoadNumber(S);
  236. if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */
  237. luaG_runerror(S->L,"unknown number format in %s",S->name);
  238. }
  239. static Proto* LoadChunk (LoadState* S)
  240. {
  241. LoadHeader(S);
  242. return LoadFunction(S,NULL);
  243. }
  244. /*
  245. ** load precompiled chunk
  246. */
  247. Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char *s)
  248. {
  249. LoadState S;
  250. if (*s=='@' || *s=='=')
  251. S.name=s+1;
  252. else if (*s==LUA_SIGNATURE[0])
  253. S.name="binary string";
  254. else
  255. S.name=s;
  256. S.L=L;
  257. S.Z=Z;
  258. S.b=buff;
  259. return LoadChunk(&S);
  260. }
  261. /*
  262. ** find byte order
  263. */
  264. int luaU_endianness (void)
  265. {
  266. int x=1;
  267. return *(char*)&x;
  268. }