diff options
author | Lua Team <team@lua.org> | 1999-07-08 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 1999-07-08 12:00:00 +0000 |
commit | afb67002d94ef22c14741910ba83da262a6e9338 (patch) | |
tree | b51ab3502813f590a4b115997f6fe41da43b6586 /src/lundump.c | |
parent | 377347776f1f3d820f92151f70bec667f96d5e6b (diff) | |
download | lua-github-3.2.tar.gz |
Lua 3.23.2
Diffstat (limited to 'src/lundump.c')
-rw-r--r-- | src/lundump.c | 171 |
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); +} |