Răsfoiți Sursa

undump.c is now a module
panic is now lua_error
included swap.c
tries float permutation earlier
new functions: luaI_undump1 and luaI_undump

Luiz Henrique de Figueiredo 29 ani în urmă
părinte
comite
3cab7cd025
1 a modificat fișierele cu 159 adăugiri și 33 ștergeri
  1. 159 33
      undump.c

+ 159 - 33
undump.c

@@ -3,24 +3,134 @@
 ** load bytecodes from files
 */
 
-char* rcs_undump="$Id: undump.c,v 1.9 1996/03/06 16:01:08 lhf Exp lhf $";
+char* rcs_undump="$Id: undump.c,v 1.10 1996/03/06 21:40:10 lhf Exp lhf $";
 
 #include <stdio.h>
 #include <string.h>
-#include "luac.h"
+#include "undump.h"
 
 static int swapword=0;
 static int swapfloat=0;
+static TFunc* Main=NULL;			/* functions in a chunk */
+static TFunc* lastF=NULL;
 
 static void warn(char* s)			/* TODO: remove */
 {
  fprintf(stderr,"undump: %s\n",s);
 }
 
-static void panic(char* s)			/* TODO: remove */
+static void FixCode(Byte* code, Byte* end)	/* swap words */
 {
- warn(s);
- exit(1);
+ Byte* p;
+ for (p=code; p!=end;)
+ {
+	OpCode op=(OpCode)*p;
+	switch (op)
+	{
+	case PUSHNIL:
+	case PUSH0:
+	case PUSH1:
+	case PUSH2:
+	case PUSHLOCAL0:
+	case PUSHLOCAL1:
+	case PUSHLOCAL2:
+	case PUSHLOCAL3:
+	case PUSHLOCAL4:
+	case PUSHLOCAL5:
+	case PUSHLOCAL6:
+	case PUSHLOCAL7:
+	case PUSHLOCAL8:
+	case PUSHLOCAL9:
+	case PUSHINDEXED:
+	case STORELOCAL0:
+	case STORELOCAL1:
+	case STORELOCAL2:
+	case STORELOCAL3:
+	case STORELOCAL4:
+	case STORELOCAL5:
+	case STORELOCAL6:
+	case STORELOCAL7:
+	case STORELOCAL8:
+	case STORELOCAL9:
+	case STOREINDEXED0:
+	case ADJUST0:
+	case EQOP:
+	case LTOP:
+	case LEOP:
+	case GTOP:
+	case GEOP:
+	case ADDOP:
+	case SUBOP:
+	case MULTOP:
+	case DIVOP:
+	case POWOP:
+	case CONCOP:
+	case MINUSOP:
+	case NOTOP:
+	case POP:
+	case RETCODE0:
+		p++;
+		break;
+	case PUSHBYTE:
+	case PUSHLOCAL:
+	case STORELOCAL:
+	case STOREINDEXED:
+	case STORELIST0:
+	case ADJUST:
+	case RETCODE:
+		p+=2;
+		break;
+	case STORELIST:
+	case CALLFUNC:
+		p+=3;
+		break;
+	case PUSHFUNCTION:
+		p+=5;
+		break;
+	case PUSHWORD:
+	case PUSHSELF:
+	case CREATEARRAY:
+	case ONTJMP:
+	case ONFJMP:
+	case JMP:
+	case UPJMP:
+	case IFFJMP:
+	case IFFUPJMP:
+	case SETLINE:
+	case PUSHSTRING:
+	case PUSHGLOBAL:
+	case STOREGLOBAL:
+	{
+		Byte t;
+		t=p[1]; p[1]=p[2]; p[2]=t;
+		p+=3;
+		break;
+	}
+	case PUSHFLOAT:
+	{
+		Byte t;
+		t=p[1]; p[1]=p[4]; p[4]=t;
+		t=p[2]; p[2]=p[3]; p[3]=t;
+		p+=5;
+		break;
+	}
+	case STORERECORD:
+	{
+		int n=*++p;
+		p++;
+		while (n--)
+		{
+			Byte t;
+			t=p[0]; p[0]=p[1]; p[1]=t;
+			p+=2;
+		}
+		break;
+	}
+	default:
+		lua_error("corrupt binary file");
+		break;
+	}
+ }
 }
 
 static void Unthread(Byte* code, int i, int v)
@@ -62,7 +172,7 @@ static int LoadSize(FILE* D)
  Word hi=LoadWord(D);
  Word lo=LoadWord(D);
  int s=(hi<<16)|lo;
- if ((Word)s != s) panic("code too long");
+ if ((Word)s != s) lua_error("code too long");
  return s;
 }
 
@@ -71,9 +181,6 @@ static char* LoadString(FILE* D)
  return LoadBlock(LoadWord(D),D);
 }
 
-static TFunc* Main=NULL;
-static TFunc* lastF=NULL;
-
 static void LoadFunction(FILE* D)
 {
  TFunc* tf=new(TFunc);
@@ -132,7 +239,7 @@ static void LoadSignature(FILE* D)
  char* s=SIGNATURE;
  while (*s!=0 && getc(D)==*s)
   ++s;
- if (*s!=0) panic("bad signature");
+ if (*s!=0) lua_error("bad signature");
 }
 
 static void LoadHeader(FILE* D)			/* TODO: error handling */
@@ -141,17 +248,24 @@ static void LoadHeader(FILE* D)			/* TODO: error handling */
  float f,tf=TEST_FLOAT;
  LoadSignature(D);
  getc(D);					/* skip version */
- fread(&w,sizeof(w),1,D);		/* a word for testing byte ordering */
+ fread(&w,sizeof(w),1,D);			/* test word */
  if (w!=tw)
  {
   swapword=1;
   warn("different byte order");
  }
- fread(&f,sizeof(f),1,D);		/* a float for testing byte ordering */
+ fread(&f,sizeof(f),1,D);			/* test float */
  if (f!=tf)
  {
-  swapfloat=1;					/* TODO: only one test? */
-  if (f!=tf) warn("different float representation");
+  Byte* p=&f;					/* TODO: need union? */
+  Byte t;
+  swapfloat=1;
+  t=p[0]; p[0]=p[3]; p[3]=t;
+  t=p[1]; p[1]=p[2]; p[2]=t;
+  if (f!=tf)					/* TODO: try another perm? */
+   lua_error("different float representation");
+  else
+   warn("different byte order in floats");
  }
 }
 
@@ -163,39 +277,51 @@ static void LoadChunk(FILE* D)
   int c=getc(D);
   if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
  }
-#if 1
- {						/* TODO: run Main? */
-  TFunc* tf;
-  for (tf=Main; tf!=NULL; tf=tf->next)
-   PrintFunction(tf);
- }
-#endif
 }
 
-void luaI_undump(FILE* D)
+/*
+** load one chunk from a file.
+** return list of functions found, headed by main, or NULL at EOF.
+*/
+TFunc* luaI_undump1(FILE* D)
 {
  while (1)
  {
   int c=getc(D);
   if (c==ID_CHUNK)
+  {
    LoadChunk(D);
+   return Main;
+  }
   else if (c==EOF)
-   break;
+   return NULL;
   else
-   panic("not a lua binary file");
+   lua_error("not a lua binary file");
  }
 }
 
-int main(int argc, char* argv[])
+/*
+** load and run all chunks in a file
+*/
+void luaI_undump(FILE* D)
 {
- char* fn=(argc>1)? argv[1] : "luac.out";
- FILE* f=freopen(fn,"rb",stdin);
- if (f==NULL)
+ TFunc* m;
+ while ((m=luaI_undump1(D)))
  {
-  fprintf(stderr,"undump: cannot open ");
-  perror(fn);
-  exit(1);
+#if 0
+  luaI_dorun(m);
+  luaI_freefunc(m);				/* TODO: free others? */
+#endif
  }
- luaI_undump(stdin); 
- return 0;
+}
+
+char* luaI_buffer(int n)
+{
+ static int size=0;
+ static char* buffer=NULL;
+ if (buffer==NULL)
+  buffer=luaI_malloc(n);
+ else if (n>size)
+  buffer=luaI_realloc(buffer,size=n);
+ return buffer;
 }