/*
** undump.c
** load bytecodes from files
*/

char* rcs_undump="$Id: undump.c,v 1.20 1996/11/16 20:14:23 lhf Exp lhf $";

#include <stdio.h>
#include <string.h>
#include "opcode.h"
#include "mem.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 warn(char* s)			/* TODO: remove */
{
#if 0
 fprintf(stderr,"undump: %s\n",s);
#endif
}

static void FixCode(Byte* code, Byte* end)	/* swap words */
{
 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;			/* 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:
		lua_error("corrupt binary file");
		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;				/* TODO: need union? */
  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("bad signature");
}

static void LoadHeader(FILE* D)			/* TODO: error handling */
{
 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)
   lua_error("cannot load binary file created on machine with sizeof(Word)!=2");
  if (oldsizeofF!=4)
   lua_error("cannot load binary file created on machine with sizeof(float)!=4. not an IEEE machine?");
  if (oldsizeofP!=sizeof(TFunc*))		/* TODO: pack */
   lua_error("cannot load binary file: different pointer sizes");
 }
 fread(&w,sizeof(w),1,D);			/* test word */
 if (w!=tw)
 {
  swapword=1;
  warn("different byte order");
 }
 fread(&f,sizeof(f),1,D);			/* test float */
 if (f!=tf)
 {
  Byte* p=(Byte*)&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");
 }
}

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