123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /*
- ** undump.c
- ** load bytecodes from files
- */
- char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp lhf $";
- #include <stdio.h>
- #include <string.h>
- #include "auxlib.h"
- #include "opcode.h"
- #include "luamem.h"
- #include "table.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 FixCode(Byte* code, Byte* end) /* swap words */
- {
- Byte* p;
- for (p=code; p!=end;)
- {
- int op=*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:
- case VARARGS:
- case STOREMAP:
- p+=2;
- break;
- case STORELIST:
- case CALLFUNC:
- p+=3;
- break;
- case PUSHFUNCTION:
- p+=5; /* TODO: use sizeof(TFunc*) or old? */
- 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: /* assumes sizeof(float)==4 */
- {
- 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:
- luaL_verror("corrupt binary file: bad opcode %d at %d\n",
- op,(int)(p-code));
- break;
- }
- }
- }
- static void Unthread(Byte* code, int i, int v)
- {
- while (i!=0)
- {
- Word w;
- Byte* p=code+i;
- memcpy(&w,p,sizeof(w));
- i=w; w=v;
- memcpy(p,&w,sizeof(w));
- }
- }
- static int LoadWord(FILE* D)
- {
- Word w;
- fread(&w,sizeof(w),1,D);
- if (swapword)
- {
- Byte* p=(Byte*)&w;
- Byte t;
- t=p[0]; p[0]=p[1]; p[1]=t;
- }
- return w;
- }
- static int LoadSize(FILE* D)
- {
- Word hi=LoadWord(D);
- Word lo=LoadWord(D);
- int s=(hi<<16)|lo;
- if ((Word)s != s) lua_error("code too long");
- return s;
- }
- static void* LoadBlock(int size, FILE* D)
- {
- void* b=luaI_malloc(size);
- fread(b,size,1,D);
- return b;
- }
- static char* LoadString(FILE* D)
- {
- int size=LoadWord(D);
- char *b=luaI_buffer(size);
- fread(b,size,1,D);
- return b;
- }
- static char* LoadNewString(FILE* D)
- {
- return LoadBlock(LoadWord(D),D);
- }
- static void LoadFunction(FILE* D)
- {
- TFunc* tf=new(TFunc);
- tf->next=NULL;
- tf->locvars=NULL;
- tf->size=LoadSize(D);
- tf->lineDefined=LoadWord(D);
- if (IsMain(tf)) /* new main */
- {
- tf->fileName=LoadNewString(D);
- Main=lastF=tf;
- }
- else /* fix PUSHFUNCTION */
- {
- tf->marked=LoadWord(D);
- tf->fileName=Main->fileName;
- memcpy(Main->code+tf->marked,&tf,sizeof(tf));
- lastF=lastF->next=tf;
- }
- tf->code=LoadBlock(tf->size,D);
- if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
- while (1) /* unthread */
- {
- int c=getc(D);
- if (c==ID_VAR) /* global var */
- {
- int i=LoadWord(D);
- char* s=LoadString(D);
- int v=luaI_findsymbolbyname(s);
- Unthread(tf->code,i,v);
- }
- else if (c==ID_STR) /* constant string */
- {
- int i=LoadWord(D);
- char* s=LoadString(D);
- int v=luaI_findconstantbyname(s);
- Unthread(tf->code,i,v);
- }
- else
- {
- ungetc(c,D);
- break;
- }
- }
- }
- static void LoadSignature(FILE* D)
- {
- char* s=SIGNATURE;
- while (*s!=0 && getc(D)==*s)
- ++s;
- if (*s!=0) lua_error("cannot load binary file: bad signature");
- }
- static void LoadHeader(FILE* D)
- {
- Word w,tw=TEST_WORD;
- float f,tf=TEST_FLOAT;
- int version;
- LoadSignature(D);
- version=getc(D);
- if (version>0x23) /* after 2.5 */
- {
- int oldsizeofW=getc(D);
- int oldsizeofF=getc(D);
- int oldsizeofP=getc(D);
- if (oldsizeofW!=2)
- luaL_verror(
- "cannot load binary file created on machine with sizeof(Word)=%d; "
- "expected 2",oldsizeofW);
- if (oldsizeofF!=4)
- luaL_verror(
- "cannot load binary file created on machine with sizeof(float)=%d; "
- "expected 4\nnot an IEEE machine?",oldsizeofF);
- if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack? */
- luaL_verror(
- "cannot load binary file created on machine with sizeof(TFunc*)=%d; "
- "expected %d",oldsizeofP,sizeof(TFunc*));
- }
- fread(&w,sizeof(w),1,D); /* test word */
- if (w!=tw)
- {
- swapword=1;
- }
- fread(&f,sizeof(f),1,D); /* test float */
- if (f!=tf)
- {
- Byte* p=(Byte*)&f;
- 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("cannot load binary file: unknown float representation");
- }
- }
- static void LoadChunk(FILE* D)
- {
- LoadHeader(D);
- while (1)
- {
- int c=getc(D);
- if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
- }
- }
- /*
- ** 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)
- return NULL;
- else
- lua_error("not a lua binary file");
- }
- }
- /*
- ** load and run all chunks in a file
- */
- int luaI_undump(FILE* D)
- {
- TFunc* m;
- while ((m=luaI_undump1(D)))
- {
- int status=luaI_dorun(m);
- luaI_freefunc(m);
- if (status!=0) return status;
- }
- return 0;
- }
|