undump.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. ** undump.c
  3. ** load bytecodes from files
  4. */
  5. char* rcs_undump="$Id: undump.c,v 1.9 1996/03/06 16:01:08 lhf Exp lhf $";
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "luac.h"
  9. static int swapword=0;
  10. static int swapfloat=0;
  11. static void warn(char* s) /* TODO: remove */
  12. {
  13. fprintf(stderr,"undump: %s\n",s);
  14. }
  15. static void panic(char* s) /* TODO: remove */
  16. {
  17. warn(s);
  18. exit(1);
  19. }
  20. static void Unthread(Byte* code, int i, int v)
  21. {
  22. while (i!=0)
  23. {
  24. CodeWord c;
  25. Byte* p=code+i;
  26. get_word(c,p);
  27. i=c.w;
  28. c.w=v;
  29. p[-2]=c.m.c1;
  30. p[-1]=c.m.c2;
  31. }
  32. }
  33. static int LoadWord(FILE* D)
  34. {
  35. Word w;
  36. fread(&w,sizeof(w),1,D);
  37. if (swapword)
  38. {
  39. Byte* p=&w; /* TODO: need union? */
  40. Byte t;
  41. t=p[0]; p[0]=p[1]; p[1]=t;
  42. }
  43. return w;
  44. }
  45. static char* LoadBlock(int size, FILE* D)
  46. {
  47. char* b=luaI_malloc(size);
  48. fread(b,size,1,D);
  49. return b;
  50. }
  51. static int LoadSize(FILE* D)
  52. {
  53. Word hi=LoadWord(D);
  54. Word lo=LoadWord(D);
  55. int s=(hi<<16)|lo;
  56. if ((Word)s != s) panic("code too long");
  57. return s;
  58. }
  59. static char* LoadString(FILE* D)
  60. {
  61. return LoadBlock(LoadWord(D),D);
  62. }
  63. static TFunc* Main=NULL;
  64. static TFunc* lastF=NULL;
  65. static void LoadFunction(FILE* D)
  66. {
  67. TFunc* tf=new(TFunc);
  68. tf->next=NULL;
  69. tf->locvars=NULL;
  70. tf->size=LoadSize(D);
  71. tf->lineDefined=LoadWord(D);
  72. if (IsMain(tf)) /* new main */
  73. {
  74. tf->fileName=LoadString(D);
  75. Main=lastF=tf;
  76. }
  77. else /* fix PUSHFUNCTION */
  78. {
  79. CodeCode c;
  80. Byte* p;
  81. tf->marked=LoadWord(D);
  82. tf->fileName=Main->fileName;
  83. p=Main->code+tf->marked;
  84. c.tf=tf;
  85. *p++=c.m.c1; *p++=c.m.c2; *p++=c.m.c3; *p++=c.m.c4;
  86. lastF=lastF->next=tf;
  87. }
  88. #if 0
  89. tf->marked=0; /* TODO: is this ok? */
  90. #endif
  91. tf->code=LoadBlock(tf->size,D);
  92. if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
  93. while (1) /* unthread */
  94. {
  95. int c=getc(D);
  96. if (c==ID_VAR) /* global var */
  97. {
  98. int i=LoadWord(D);
  99. char* s=LoadString(D);
  100. int v=luaI_findsymbolbyname(s); /* TODO: free s? */
  101. Unthread(tf->code,i,v);
  102. }
  103. else if (c==ID_STR) /* constant string */
  104. {
  105. int i=LoadWord(D);
  106. char* s=LoadString(D);
  107. int v=luaI_findconstantbyname(s); /* TODO: free s? */
  108. Unthread(tf->code,i,v);
  109. }
  110. else
  111. {
  112. ungetc(c,D);
  113. break;
  114. }
  115. }
  116. }
  117. static void LoadSignature(FILE* D)
  118. {
  119. char* s=SIGNATURE;
  120. while (*s!=0 && getc(D)==*s)
  121. ++s;
  122. if (*s!=0) panic("bad signature");
  123. }
  124. static void LoadHeader(FILE* D) /* TODO: error handling */
  125. {
  126. Word w,tw=TEST_WORD;
  127. float f,tf=TEST_FLOAT;
  128. LoadSignature(D);
  129. getc(D); /* skip version */
  130. fread(&w,sizeof(w),1,D); /* a word for testing byte ordering */
  131. if (w!=tw)
  132. {
  133. swapword=1;
  134. warn("different byte order");
  135. }
  136. fread(&f,sizeof(f),1,D); /* a float for testing byte ordering */
  137. if (f!=tf)
  138. {
  139. swapfloat=1; /* TODO: only one test? */
  140. if (f!=tf) warn("different float representation");
  141. }
  142. }
  143. static void LoadChunk(FILE* D)
  144. {
  145. LoadHeader(D);
  146. while (1)
  147. {
  148. int c=getc(D);
  149. if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
  150. }
  151. #if 1
  152. { /* TODO: run Main? */
  153. TFunc* tf;
  154. for (tf=Main; tf!=NULL; tf=tf->next)
  155. PrintFunction(tf);
  156. }
  157. #endif
  158. }
  159. void luaI_undump(FILE* D)
  160. {
  161. while (1)
  162. {
  163. int c=getc(D);
  164. if (c==ID_CHUNK)
  165. LoadChunk(D);
  166. else if (c==EOF)
  167. break;
  168. else
  169. panic("not a lua binary file");
  170. }
  171. }
  172. int main(int argc, char* argv[])
  173. {
  174. char* fn=(argc>1)? argv[1] : "luac.out";
  175. FILE* f=freopen(fn,"rb",stdin);
  176. if (f==NULL)
  177. {
  178. fprintf(stderr,"undump: cannot open ");
  179. perror(fn);
  180. exit(1);
  181. }
  182. luaI_undump(stdin);
  183. return 0;
  184. }