summaryrefslogtreecommitdiff
path: root/src/lundump.c
diff options
context:
space:
mode:
authorLua Team <team@lua.org>1999-07-08 12:00:00 +0000
committerrepogen <>1999-07-08 12:00:00 +0000
commitafb67002d94ef22c14741910ba83da262a6e9338 (patch)
treeb51ab3502813f590a4b115997f6fe41da43b6586 /src/lundump.c
parent377347776f1f3d820f92151f70bec667f96d5e6b (diff)
downloadlua-github-3.2.tar.gz
Lua 3.23.2
Diffstat (limited to 'src/lundump.c')
-rw-r--r--src/lundump.c171
1 files changed, 91 insertions, 80 deletions
diff --git a/src/lundump.c b/src/lundump.c
index 4fe2b0d7..0c3b5fd7 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 1.12 1998/07/12 01:46:59 lhf Exp $
+** $Id: lundump.c,v 1.21 1999/07/02 19:34:26 lhf Exp $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@@ -9,99 +9,96 @@
#include "lauxlib.h"
#include "lfunc.h"
#include "lmem.h"
+#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define LoadBlock(b,size,Z) ezread(Z,b,size)
-#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
-#if ID_NUMBER==ID_NATIVE
- #define doLoadNumber(f,Z) LoadNative(f,Z)
-#else
- #define doLoadNumber(f,Z) f=LoadNumber(Z)
-#endif
-
-static void unexpectedEOZ(ZIO* Z)
+static void unexpectedEOZ (ZIO* Z)
{
luaL_verror("unexpected end of file in %s",zname(Z));
}
-static int ezgetc(ZIO* Z)
+static int ezgetc (ZIO* Z)
{
int c=zgetc(Z);
if (c==EOZ) unexpectedEOZ(Z);
return c;
}
-static void ezread(ZIO* Z, void* b, int n)
+static void ezread (ZIO* Z, void* b, int n)
{
int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(Z);
}
-static unsigned int LoadWord(ZIO* Z)
+static unsigned int LoadWord (ZIO* Z)
{
unsigned int hi=ezgetc(Z);
unsigned int lo=ezgetc(Z);
return (hi<<8)|lo;
}
-static unsigned long LoadLong(ZIO* Z)
+static unsigned long LoadLong (ZIO* Z)
{
unsigned long hi=LoadWord(Z);
unsigned long lo=LoadWord(Z);
return (hi<<16)|lo;
}
-#if ID_NUMBER==ID_REAL4
-/* LUA_NUMBER */
-/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
-static float LoadFloat(ZIO* Z)
+/*
+* convert number from text
+*/
+double luaU_str2d (char* b, char* where)
{
- unsigned long l=LoadLong(Z);
- float f;
- memcpy(&f,&l,sizeof(f));
- return f;
+ int negative=(b[0]=='-');
+ double x=luaO_str2d(b+negative);
+ if (x<0) luaL_verror("cannot convert number '%s' in %s",b,where);
+ return negative ? -x : x;
}
-#endif
-#if ID_NUMBER==ID_REAL8
-/* LUA_NUMBER */
-/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
-static double LoadDouble(ZIO* Z)
+static real LoadNumber (ZIO* Z, int native)
{
- unsigned long l[2];
- double f;
- int x=1;
- if (*(char*)&x==1) /* little-endian */
+ real x;
+ if (native)
{
- l[1]=LoadLong(Z);
- l[0]=LoadLong(Z);
+ LoadBlock(&x,sizeof(x),Z);
+ return x;
}
- else /* big-endian */
+ else
{
- l[0]=LoadLong(Z);
- l[1]=LoadLong(Z);
+ char b[256];
+ int size=ezgetc(Z);
+ LoadBlock(b,size,Z);
+ b[size]=0;
+ return luaU_str2d(b,zname(Z));
}
- memcpy(&f,l,sizeof(f));
- return f;
}
-#endif
-static Byte* LoadCode(ZIO* Z)
+static int LoadInt (ZIO* Z, char* message)
{
- unsigned long size=LoadLong(Z);
- unsigned int s=size;
- void* b;
- if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
- b=luaM_malloc(size);
+ unsigned long l=LoadLong(Z);
+ unsigned int i=l;
+ if (i!=l) luaL_verror(message,l,zname(Z));
+ return i;
+}
+
+#define PAD 5 /* two word operands plus opcode */
+
+static Byte* LoadCode (ZIO* Z)
+{
+ int size=LoadInt(Z,"code too long (%ld bytes) in %s");
+ Byte* b=luaM_malloc(size+PAD);
LoadBlock(b,size,Z);
+ if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
+ memset(b+size,ENDCODE,PAD); /* pad code for safety */
return b;
}
-static TaggedString* LoadTString(ZIO* Z)
+static TaggedString* LoadTString (ZIO* Z)
{
- int size=LoadWord(Z);
+ long size=LoadLong(Z);
if (size==0)
return NULL;
else
@@ -112,65 +109,65 @@ static TaggedString* LoadTString(ZIO* Z)
}
}
-static void LoadLocals(TProtoFunc* tf, ZIO* Z)
+static void LoadLocals (TProtoFunc* tf, ZIO* Z)
{
- int i,n=LoadWord(Z);
+ int i,n=LoadInt(Z,"too many locals (%ld) in %s");
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].line=LoadInt(Z,"too many lines (%ld) in %s");
tf->locvars[i].varname=LoadTString(Z);
}
tf->locvars[i].line=-1; /* flag end of vector */
tf->locvars[i].varname=NULL;
}
-static TProtoFunc* LoadFunction(ZIO* Z);
+static TProtoFunc* LoadFunction (ZIO* Z, int native);
-static void LoadConstants(TProtoFunc* tf, ZIO* Z)
+static void LoadConstants (TProtoFunc* tf, ZIO* Z, int native)
{
- int i,n=LoadWord(Z);
+ int i,n=LoadInt(Z,"too many constants (%ld) in %s");
tf->nconsts=n;
if (n==0) return;
tf->consts=luaM_newvector(n,TObject);
for (i=0; i<n; i++)
{
TObject* o=tf->consts+i;
- ttype(o)=-ezgetc(Z);
+ ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
switch (ttype(o))
{
case LUA_T_NUMBER:
- doLoadNumber(nvalue(o),Z);
+ nvalue(o)=LoadNumber(Z,native);
break;
case LUA_T_STRING:
tsvalue(o)=LoadTString(Z);
break;
case LUA_T_PROTO:
- tfvalue(o)=LoadFunction(Z);
+ tfvalue(o)=LoadFunction(Z,native);
break;
case LUA_T_NIL:
break;
- default:
- luaL_verror("bad constant #%d in %s: type=%d [%s]",
- i,zname(Z),ttype(o),luaO_typename(o));
+ default: /* cannot happen */
+ luaU_badconstant("load",i,o,tf);
break;
}
}
}
-static TProtoFunc* LoadFunction(ZIO* Z)
+static TProtoFunc* LoadFunction (ZIO* Z, int native)
{
TProtoFunc* tf=luaF_newproto();
- tf->lineDefined=LoadWord(Z);
- tf->fileName=LoadTString(Z);
+ tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
+ tf->source=LoadTString(Z);
+ if (tf->source==NULL) tf->source=luaS_new(zname(Z));
tf->code=LoadCode(Z);
LoadLocals(tf,Z);
- LoadConstants(tf,Z);
+ LoadConstants(tf,Z,native);
return tf;
}
-static void LoadSignature(ZIO* Z)
+static void LoadSignature (ZIO* Z)
{
char* s=SIGNATURE;
while (*s!=0 && ezgetc(Z)==*s)
@@ -178,10 +175,10 @@ static void LoadSignature(ZIO* Z)
if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
}
-static void LoadHeader(ZIO* Z)
+static int LoadHeader (ZIO* Z)
{
- int version,id,sizeofR;
- real f=-TEST_NUMBER,tf=TEST_NUMBER;
+ int version,sizeofR;
+ int native;
LoadSignature(Z);
version=ezgetc(Z);
if (version>VERSION)
@@ -192,32 +189,36 @@ static void LoadHeader(ZIO* Z)
luaL_verror(
"%s too old: version=0x%02x; expected at least 0x%02x",
zname(Z),version,VERSION0);
- id=ezgetc(Z); /* test number representation */
sizeofR=ezgetc(Z);
- if (id!=ID_NUMBER || sizeofR!=sizeof(real))
+ native=(sizeofR!=0);
+ if (native) /* test number representation */
{
- luaL_verror("unknown number signature in %s: "
- "read 0x%02x%02x; expected 0x%02x%02x",
- zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
+ if (sizeofR!=sizeof(real))
+ luaL_verror("unknown number size in %s: read %d; expected %d",
+ zname(Z),sizeofR,sizeof(real));
+ else
+ {
+ real tf=TEST_NUMBER;
+ real f=LoadNumber(Z,native);
+ if ((long)f!=(long)tf)
+ luaL_verror("unknown number format in %s: "
+ "read " NUMBER_FMT "; expected " NUMBER_FMT,
+ zname(Z),f,tf);
+ }
}
- doLoadNumber(f,Z);
- if (f!=tf)
- luaL_verror("unknown number representation in %s: "
- "read " NUMBER_FMT "; expected " NUMBER_FMT, /* LUA_NUMBER */
- zname(Z),f,tf);
+ return native;
}
-static TProtoFunc* LoadChunk(ZIO* Z)
+static TProtoFunc* LoadChunk (ZIO* Z)
{
- LoadHeader(Z);
- return LoadFunction(Z);
+ return LoadFunction(Z,LoadHeader(Z));
}
/*
** load one chunk from a file or buffer
** return main if ok and NULL at EOF
*/
-TProtoFunc* luaU_undump1(ZIO* Z)
+TProtoFunc* luaU_undump1 (ZIO* Z)
{
int c=zgetc(Z);
if (c==ID_CHUNK)
@@ -226,3 +227,13 @@ TProtoFunc* luaU_undump1(ZIO* Z)
luaL_verror("%s is not a Lua binary file",zname(Z));
return NULL;
}
+
+/*
+* handle constants that cannot happen
+*/
+void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
+{
+ int t=ttype(o);
+ char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
+ luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
+}