module to load bytecodes from files.
diff --git a/lundump.c b/lundump.c
new file mode 100644
index 0000000..32d7359
--- /dev/null
+++ b/lundump.c
@@ -0,0 +1,272 @@
+/*
+** $Id: lundump.c,v 1.4 1998/01/13 20:05:24 lhf Exp $
+** load bytecodes from files
+** See Copyright Notice in lua.h
+*/
+
+#include <stdio.h>
+#include "lauxlib.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lstring.h"
+#include "lundump.h"
+
+typedef struct {
+ ZIO* Z;
+ int SwapNumber;
+ int LoadFloat;
+} Sundump;
+
+static void unexpectedEOZ(ZIO* Z)
+{
+ luaL_verror("unexpected end of binary file %s",Z->name);
+}
+
+static int ezgetc(ZIO* Z)
+{
+ int c=zgetc(Z);
+ if (c==EOZ) unexpectedEOZ(Z);
+ return c;
+}
+
+static int ezread(ZIO* Z, void* b, int n)
+{
+ int r=zread(Z,b,n);
+ if (r!=0) unexpectedEOZ(Z);
+ return r;
+}
+
+static int LoadWord(ZIO* Z)
+{
+ int hi=ezgetc(Z);
+ int lo=ezgetc(Z);
+ return (hi<<8)|lo;
+}
+
+static void* LoadBlock(int size, ZIO* Z)
+{
+ void* b=luaM_malloc(size);
+ ezread(Z,b,size);
+ return b;
+}
+
+static int LoadSize(ZIO* Z)
+{
+ int hi=LoadWord(Z);
+ int lo=LoadWord(Z);
+ int s=(hi<<16)|lo;
+ if (hi!=0 && s==lo)
+  luaL_verror("code too long (%ld bytes)",(hi<<16)|(long)lo);
+ return s;
+}
+
+static char* LoadString(ZIO* Z)
+{
+ int size=LoadWord(Z);
+ if (size==0)
+  return NULL;
+ else
+ {
+  char* b=luaL_openspace(size);
+  ezread(Z,b,size);
+  return b;
+ }
+}
+
+static TaggedString* LoadTString(ZIO* Z)
+{
+ char* s=LoadString(Z);
+ return (s==NULL) ? NULL : luaS_new(s);
+}
+
+static void SwapFloat(float* f)
+{
+ Byte* p=(Byte*)f;
+ Byte* q=p+sizeof(float)-1;
+ Byte t;
+ t=*p; *p++=*q; *q--=t;
+ t=*p; *p++=*q; *q--=t;
+}
+
+static void SwapDouble(double* f)
+{
+ Byte* p=(Byte*)f;
+ Byte* q=p+sizeof(double)-1;
+ Byte t;
+ t=*p; *p++=*q; *q--=t;
+ t=*p; *p++=*q; *q--=t;
+ t=*p; *p++=*q; *q--=t;
+ t=*p; *p++=*q; *q--=t;
+}
+
+static real LoadNumber(Sundump* S)
+{
+ if (S->LoadFloat)
+ {
+  float f;
+  ezread(S->Z,&f,sizeof(f));
+  if (S->SwapNumber) SwapFloat(&f);
+  return f;
+ }
+ else
+ {
+  double f;
+  ezread(S->Z,&f,sizeof(f));
+  if (S->SwapNumber) SwapDouble(&f);
+  return f;
+ }
+}
+
+static void LoadLocals(TProtoFunc* tf, ZIO* Z)
+{
+ int i,n=LoadWord(Z);
+ if (n==0) return;
+ tf->locvars=luaM_newvector(n+1,LocVar);
+ for (i=0; i<n; i++)
+ {
+  tf->locvars[i].line=LoadWord(Z);
+  tf->locvars[i].varname=LoadTString(Z);
+ }
+ tf->locvars[i].line=-1;		/* flag end of vector */
+ tf->locvars[i].varname=NULL;
+}
+
+static void LoadConstants(TProtoFunc* tf, Sundump* S)
+{
+ int i,n=LoadWord(S->Z);
+ tf->nconsts=n;
+ if (n==0) return;
+ tf->consts=luaM_newvector(n,TObject);
+ for (i=0; i<n; i++)
+ {
+  TObject* o=tf->consts+i;
+  int c=ezgetc(S->Z);
+  switch (c)
+  {
+   case ID_NUM:
+	ttype(o)=LUA_T_NUMBER;
+	nvalue(o)=LoadNumber(S);
+	break;
+   case ID_STR:
+	ttype(o)=LUA_T_STRING;	
+	tsvalue(o)=LoadTString(S->Z);
+	break;
+   case ID_FUN:
+	ttype(o)=LUA_T_PROTO;
+	tfvalue(o)=NULL;
+	break;
+#ifdef DEBUG
+   default:				/* cannot happen */
+	luaL_verror("internal error in LoadConstants: "
+		"bad constant #%d type=%d ('%c')\n",i,c,c);
+	break;
+#endif
+  }
+ }
+}
+
+static TProtoFunc* LoadFunction(Sundump* S);
+
+static void LoadFunctions(TProtoFunc* tf, Sundump* S)
+{
+ while (zgetc(S->Z)==ID_FUNCTION)
+ {
+  int i=LoadWord(S->Z); 
+  TProtoFunc* t=LoadFunction(S);
+  TObject* o=tf->consts+i;
+  tfvalue(o)=t;
+ }
+}
+
+static TProtoFunc* LoadFunction(Sundump* S)
+{
+ ZIO* Z=S->Z;
+ TProtoFunc* tf=luaF_newproto();
+ tf->lineDefined=LoadWord(Z);
+ tf->fileName=LoadTString(Z);
+ tf->code=LoadBlock(LoadSize(Z),Z);
+ LoadConstants(tf,S);
+ LoadLocals(tf,Z);
+ LoadFunctions(tf,S);
+ return tf;
+}
+
+static void LoadSignature(ZIO* Z)
+{
+ char* s=SIGNATURE;
+ while (*s!=0 && ezgetc(Z)==*s)
+  ++s;
+ if (*s!=0) luaL_verror("bad signature in binary file %s",Z->name);
+}
+
+static void LoadHeader(Sundump* S)
+{
+ ZIO* Z=S->Z;
+ int version,sizeofR;
+ LoadSignature(Z);
+ version=ezgetc(Z);
+ if (version>VERSION)
+  luaL_verror(
+	"binary file %s too new: version=0x%02x; expected at most 0x%02x",
+	Z->name,version,VERSION);
+ if (version<0x31)			/* major change in 3.1 */
+  luaL_verror(
+	"binary file %s too old: version=0x%02x; expected at least 0x%02x",
+	Z->name,version,0x31);
+ sizeofR=ezgetc(Z);			/* test float representation */
+ if (sizeofR==sizeof(float))
+ {
+  float f,tf=TEST_FLOAT;
+  ezread(Z,&f,sizeof(f));
+  if (f!=tf)
+  {
+   SwapFloat(&f);
+   if (f!=tf)
+    luaL_verror("unknown float representation in binary file %s",Z->name);
+   S->SwapNumber=1;
+  }
+  S->LoadFloat=1;
+ }
+ else if (sizeofR==sizeof(double))
+ {
+  double f,tf=TEST_FLOAT;
+  ezread(Z,&f,sizeof(f));
+  if (f!=tf)
+  {
+   SwapDouble(&f);
+   if (f!=tf)
+    luaL_verror("unknown float representation in binary file %s",Z->name);
+   S->SwapNumber=1;
+  }
+  S->LoadFloat=0;
+ }
+ else
+  luaL_verror(
+       "floats in binary file %s have %d bytes; "
+       "expected %d (float) or %d (double)",
+       Z->name,sizeofR,sizeof(float),sizeof(double));
+}
+
+static TProtoFunc* LoadChunk(Sundump* S)
+{
+ LoadHeader(S);
+ return LoadFunction(S);
+}
+
+/*
+** load one chunk from a file or buffer
+** return main if ok and NULL at EOF
+*/
+TProtoFunc* luaU_undump1(ZIO* Z)
+{
+ int c=zgetc(Z);
+ Sundump S;
+ S.Z=Z;
+ S.SwapNumber=0;
+ S.LoadFloat=1;
+ if (c==ID_CHUNK)
+  return LoadChunk(&S);
+ else if (c!=EOZ)
+  luaL_verror("%s is not a lua binary file",Z->name);
+ return NULL;
+}
diff --git a/lundump.h b/lundump.h
new file mode 100644
index 0000000..ea9e975
--- /dev/null
+++ b/lundump.h
@@ -0,0 +1,27 @@
+/*
+** $Id: lundump.h,v 1.4 1998/01/13 20:05:24 lhf Exp $
+** load pre-compiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lundump_h
+#define lundump_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+#define ID_CHUNK	27		/* ESC */
+#define ID_FUNCTION	'#'
+#define ID_END		'$'
+#define ID_NUM		'N'
+#define ID_STR		'S'
+#define ID_FUN		'F'
+#define	SIGNATURE	"Lua"
+#define	VERSION		0x31		/* last format change was in 3.1 */
+#define	TEST_FLOAT	0.123456789e-23	/* a float for testing representation */
+
+#define IsMain(f)	(f->lineDefined==0)
+
+TProtoFunc* luaU_undump1(ZIO* Z);	/* load one chunk */
+
+#endif
diff --git a/undump.c b/undump.c
deleted file mode 100644
index 80f131d..0000000
--- a/undump.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
-** undump.c
-** load bytecodes from files
-*/
-
-char* rcs_undump="$Id: undump.c,v 1.25 1997/07/29 19:44:02 roberto Exp roberto $";
-
-#include <stdio.h>
-#include <string.h>
-#include "auxlib.h"
-#include "opcode.h"
-#include "luamem.h"
-#include "table.h"
-#include "undump.h"
-#include "zio.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 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 PUSHWORD:
-	case PUSHSELF:
-	case CREATEARRAY:
-	case ONTJMP:
-	case ONFJMP:
-	case JMP:
-	case UPJMP:
-	case IFFJMP:
-	case IFFUPJMP:
-	case SETLINE:
-	case PUSHGLOBAL:
-	case STOREGLOBAL:
-	{
-		Byte t;
-		t=p[1]; p[1]=p[2]; p[2]=t;
-		p+=3;
-		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(ZIO* Z)
-{
- Word w;
- zread(Z,&w,sizeof(w));
- if (swapword)
- {
-  Byte* p=(Byte*)&w;
-  Byte t;
-  t=p[0]; p[0]=p[1]; p[1]=t;
- }
- return w;
-}
-
-static int LoadSize(ZIO* Z)
-{
- Word hi=LoadWord(Z);
- Word lo=LoadWord(Z);
- int s=(hi<<16)|lo;
- if ((Word)s != s) lua_error("code too long");
- return s;
-}
-
-static void* LoadBlock(int size, ZIO* Z)
-{
- void* b=luaI_malloc(size);
- zread(Z,b,size);
- return b;
-}
-
-static char* LoadString(ZIO* Z)
-{
- int size=LoadWord(Z);
- char *b=luaI_buffer(size);
- zread(Z,b,size);
- return b;
-}
-
-static char* LoadNewString(ZIO* Z)
-{
- return LoadBlock(LoadWord(Z),Z);
-}
-
-static void LoadFunction(ZIO* Z)
-{
- int size;
- TFunc* tf=new(TFunc);
- tf->next=NULL;
- tf->locvars=NULL;
- size=LoadSize(Z);
- tf->lineDefined=LoadWord(Z);
- if (IsMain(tf))				/* new main */
- {
-  tf->fileName=LoadNewString(Z);
-  Main=lastF=tf;
- }
- else						/* fix PUSHFUNCTION */
- {
-  tf->marked=LoadWord(Z);
-  tf->fileName=Main->fileName;
-  memcpy(Main->code+tf->marked,&tf,sizeof(tf));
-  lastF=lastF->next=tf;
- }
- tf->code=LoadBlock(size,Z);
- if (swapword || swapfloat) FixCode(tf->code,tf->code+size);
- while (1)					/* unthread */
- {
-  int c=zgetc(Z);
-  if (c==ID_VAR)				/* global var */
-  {
-   int i=LoadWord(Z);
-   char* s=LoadString(Z);
-   int v=luaI_findsymbolbyname(s);
-   Unthread(tf->code,i,v);
-  }
-  else if (c==ID_STR)				/* constant string */
-  {
-   int i=LoadWord(Z);
-   char* s=LoadString(Z);
-   int v; /*=luaI_findconstantbyname(s); ??????? */
-   Unthread(tf->code,i,v);
-  }
-  else
-  {
-   zungetc(Z);
-   break;
-  }
- }
-}
-
-static void LoadSignature(ZIO* Z)
-{
- char* s=SIGNATURE;
- while (*s!=0 && zgetc(Z)==*s)
-  ++s;
- if (*s!=0) lua_error("cannot load binary file: bad signature");
-}
-
-static void LoadHeader(ZIO* Z)
-{
- Word w,tw=TEST_WORD;
- float f,tf=TEST_FLOAT;
- int version;
- LoadSignature(Z);
- version=zgetc(Z);
- if (version>0x23)				/* after 2.5 */
- {
-  int oldsizeofW=zgetc(Z);
-  int oldsizeofF=zgetc(Z);
-  int oldsizeofP=zgetc(Z);
-  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,(int)sizeof(TFunc*));
- }
- zread(Z,&w,sizeof(w));			/* test word */
- if (w!=tw)
- {
-  swapword=1;
- }
- zread(Z,&f,sizeof(f));			/* 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(ZIO* Z)
-{
- LoadHeader(Z);
- while (1)
- {
-  int c=zgetc(Z);
-  if (c==ID_FUN) LoadFunction(Z); else { zungetc(Z); break; }
- }
-}
-
-/*
-** load one chunk from a file.
-** return list of functions found, headed by main, or NULL at EOF.
-*/
-TFunc* luaI_undump1(ZIO* Z)
-{
- int c=zgetc(Z);
- if (c==ID_CHUNK)
- {
-  LoadChunk(Z);
-  return Main;
- }
- else if (c!=EOZ)
-   lua_error("not a lua binary file");
- return NULL;
-}
-
-/*
-** load and run all chunks in a file
-*/
-int luaI_undump(ZIO* Z)
-{
- TFunc* m;
- while ((m=luaI_undump1(Z)))
- {
-  int status=luaI_dorun(m);
-/*  luaI_freefunc(m); ???*/
-  if (status!=0) return status;
- }
- return 0;
-}
diff --git a/undump.h b/undump.h
deleted file mode 100644
index 86da43a..0000000
--- a/undump.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-** undump.h
-** definitions for lua decompiler
-** $Id: undump.h,v 1.5 1997/06/16 16:50:22 roberto Exp roberto $
-*/
-
-#ifndef undump_h
-#define undump_h
-
-#include "func.h"
-#include "zio.h"
-
-#define IsMain(f)	(f->lineDefined==0)
-
-/* definitions for chunk headers */
-
-#define ID_CHUNK	27		/* ESC */
-#define ID_FUN		'F'
-#define ID_VAR		'V'
-#define ID_STR		'S'
-#define	SIGNATURE	"Lua"
-#define	VERSION		0x25		/* last format change was in 2.5 */
-#define	TEST_WORD	0x1234		/* a word for testing byte ordering */
-#define	TEST_FLOAT	0.123456789e-23	/* a float for testing representation */
-
-
-TFunc* luaI_undump1(ZIO* Z);
-int luaI_undump(ZIO* Z);		/* load all chunks */
-
-#endif