lundump.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. ** $Id: lundump.c,v 1.18 1999/04/09 03:10:40 lhf Exp lhf $
  3. ** load bytecodes from files
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "lauxlib.h"
  9. #include "lfunc.h"
  10. #include "lmem.h"
  11. #include "lopcodes.h"
  12. #include "lstring.h"
  13. #include "lundump.h"
  14. #define LoadBlock(b,size,Z) ezread(Z,b,size)
  15. #if LUAC_NATIVE
  16. #define doLoadNumber(x,Z) LoadBlock(&x,sizeof(x),Z)
  17. #else
  18. #define doLoadNumber(x,Z) x=LoadNumber(Z)
  19. #endif
  20. static void unexpectedEOZ (ZIO* Z)
  21. {
  22. luaL_verror("unexpected end of file in %s",zname(Z));
  23. }
  24. static int ezgetc (ZIO* Z)
  25. {
  26. int c=zgetc(Z);
  27. if (c==EOZ) unexpectedEOZ(Z);
  28. return c;
  29. }
  30. static void ezread (ZIO* Z, void* b, int n)
  31. {
  32. int r=zread(Z,b,n);
  33. if (r!=0) unexpectedEOZ(Z);
  34. }
  35. static unsigned int LoadWord (ZIO* Z)
  36. {
  37. unsigned int hi=ezgetc(Z);
  38. unsigned int lo=ezgetc(Z);
  39. return (hi<<8)|lo;
  40. }
  41. static unsigned long LoadLong (ZIO* Z)
  42. {
  43. unsigned long hi=LoadWord(Z);
  44. unsigned long lo=LoadWord(Z);
  45. return (hi<<16)|lo;
  46. }
  47. static real LoadNumber (ZIO* Z)
  48. {
  49. char b[256];
  50. int size=ezgetc(Z);
  51. LoadBlock(b,size,Z);
  52. b[size]=0;
  53. if (b[0]=='-')
  54. return -luaO_str2d(b+1);
  55. else
  56. return luaO_str2d(b);
  57. }
  58. static int LoadInt (ZIO* Z, char* message)
  59. {
  60. unsigned long l=LoadLong(Z);
  61. unsigned int i=l;
  62. if (i!=l) luaL_verror(message,l,zname(Z));
  63. return i;
  64. }
  65. #define PAD 5 /* two word operands plus opcode */
  66. static Byte* LoadCode (ZIO* Z)
  67. {
  68. int size=LoadInt(Z,"code too long (%ld bytes) in %s");
  69. Byte* b=luaM_malloc(size+PAD);
  70. LoadBlock(b,size,Z);
  71. if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
  72. memset(b+size,ENDCODE,PAD); /* pad code for safety */
  73. return b;
  74. }
  75. static TaggedString* LoadTString (ZIO* Z)
  76. {
  77. long size=LoadLong(Z);
  78. if (size==0)
  79. return NULL;
  80. else
  81. {
  82. char* s=luaL_openspace(size);
  83. LoadBlock(s,size,Z);
  84. return luaS_newlstr(s,size-1);
  85. }
  86. }
  87. static void LoadLocals (TProtoFunc* tf, ZIO* Z)
  88. {
  89. int i,n=LoadInt(Z,"too many locals (%ld) in %s");
  90. if (n==0) return;
  91. tf->locvars=luaM_newvector(n+1,LocVar);
  92. for (i=0; i<n; i++)
  93. {
  94. tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
  95. tf->locvars[i].varname=LoadTString(Z);
  96. }
  97. tf->locvars[i].line=-1; /* flag end of vector */
  98. tf->locvars[i].varname=NULL;
  99. }
  100. static TProtoFunc* LoadFunction (ZIO* Z);
  101. static void LoadConstants (TProtoFunc* tf, ZIO* Z)
  102. {
  103. int i,n=LoadInt(Z,"too many constants (%ld) in %s");
  104. tf->nconsts=n;
  105. if (n==0) return;
  106. tf->consts=luaM_newvector(n,TObject);
  107. for (i=0; i<n; i++)
  108. {
  109. TObject* o=tf->consts+i;
  110. ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
  111. switch (ttype(o))
  112. {
  113. case LUA_T_NUMBER:
  114. doLoadNumber(nvalue(o),Z);
  115. break;
  116. case LUA_T_STRING:
  117. tsvalue(o)=LoadTString(Z);
  118. break;
  119. case LUA_T_PROTO:
  120. tfvalue(o)=LoadFunction(Z);
  121. break;
  122. case LUA_T_NIL:
  123. break;
  124. default: /* cannot happen */
  125. luaU_badconstant("load",i,o,tf);
  126. break;
  127. }
  128. }
  129. }
  130. static TProtoFunc* LoadFunction (ZIO* Z)
  131. {
  132. TProtoFunc* tf=luaF_newproto();
  133. tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
  134. tf->source=LoadTString(Z);
  135. if (tf->source==NULL) tf->source=luaS_new(zname(Z));
  136. tf->code=LoadCode(Z);
  137. LoadLocals(tf,Z);
  138. LoadConstants(tf,Z);
  139. return tf;
  140. }
  141. static void LoadSignature (ZIO* Z)
  142. {
  143. char* s=SIGNATURE;
  144. while (*s!=0 && ezgetc(Z)==*s)
  145. ++s;
  146. if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
  147. }
  148. static void LoadHeader (ZIO* Z)
  149. {
  150. int version,sizeofR;
  151. LoadSignature(Z);
  152. version=ezgetc(Z);
  153. if (version>VERSION)
  154. luaL_verror(
  155. "%s too new: version=0x%02x; expected at most 0x%02x",
  156. zname(Z),version,VERSION);
  157. if (version<VERSION0) /* check last major change */
  158. luaL_verror(
  159. "%s too old: version=0x%02x; expected at least 0x%02x",
  160. zname(Z),version,VERSION0);
  161. sizeofR=ezgetc(Z); /* test number representation */
  162. #if LUAC_NATIVE
  163. if (sizeofR==0)
  164. luaL_verror("cannot read numbers in %s: "
  165. "support for decimal format not enabled",
  166. zname(Z));
  167. if (sizeofR!=sizeof(real))
  168. luaL_verror("unknown number size in %s: read %d; expected %d",
  169. zname(Z),sizeofR,sizeof(real));
  170. else
  171. {
  172. real f=-TEST_NUMBER,tf=TEST_NUMBER;
  173. doLoadNumber(f,Z);
  174. if (f!=tf)
  175. luaL_verror("unknown number representation in %s: "
  176. "read " NUMBER_FMT "; expected " NUMBER_FMT,
  177. zname(Z),f,tf);
  178. }
  179. #else
  180. if (sizeofR!=0)
  181. luaL_verror("cannot read numbers in %s: "
  182. "support for native format not enabled",
  183. zname(Z));
  184. #endif
  185. }
  186. static TProtoFunc* LoadChunk (ZIO* Z)
  187. {
  188. LoadHeader(Z);
  189. return LoadFunction(Z);
  190. }
  191. /*
  192. ** load one chunk from a file or buffer
  193. ** return main if ok and NULL at EOF
  194. */
  195. TProtoFunc* luaU_undump1 (ZIO* Z)
  196. {
  197. int c=zgetc(Z);
  198. if (c==ID_CHUNK)
  199. return LoadChunk(Z);
  200. else if (c!=EOZ)
  201. luaL_verror("%s is not a Lua binary file",zname(Z));
  202. return NULL;
  203. }
  204. /*
  205. * handle constants that cannot happen
  206. */
  207. void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
  208. {
  209. int t=ttype(o);
  210. char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
  211. luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
  212. }