|
@@ -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;
|
|
|
}
|