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