Lua 5.1.4: lundump.c


L0001    /*
L0002    ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
L0003    ** load precompiled Lua chunks
L0004    ** See Copyright Notice in lua.h
L0005    */
L0006    
L0007    #include <string.h>
L0008    
L0009    #define lundump_c
L0010    #define LUA_CORE
L0011    
L0012    #include "lua.h"
L0013    
L0014    #include "ldebug.h"
L0015    #include "ldo.h"
L0016    #include "lfunc.h"
L0017    #include "lmem.h"
L0018    #include "lobject.h"
L0019    #include "lstring.h"
L0020    #include "lundump.h"
L0021    #include "lzio.h"
L0022    
L0023    typedef struct {
L0024     lua_State* L;
L0025     ZIO* Z;
L0026     Mbuffer* b;
L0027     const char* name;
L0028    } LoadState;
L0029    
L0030    #ifdef LUAC_TRUST_BINARIES
L0031    #define IF(c,s)
L0032    #define error(S,s)
L0033    #else
L0034    #define IF(c,s)		if (c) error(S,s)
L0035    
L0036    static void error(LoadState* S, const char* why)
L0037    {
L0038     luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
L0039     luaD_throw(S->L,LUA_ERRSYNTAX);
L0040    }
L0041    #endif
L0042    
L0043    #define LoadMem(S,b,n,size)	LoadBlock(S,b,(n)*(size))
L0044    #define	LoadByte(S)		(lu_byte)LoadChar(S)
L0045    #define LoadVar(S,x)		LoadMem(S,&x,1,sizeof(x))
L0046    #define LoadVector(S,b,n,size)	LoadMem(S,b,n,size)
L0047    
L0048    static void LoadBlock(LoadState* S, void* b, size_t size)
L0049    {
L0050     size_t r=luaZ_read(S->Z,b,size);
L0051     IF (r!=0, "unexpected end");
L0052    }
L0053    
L0054    static int LoadChar(LoadState* S)
L0055    {
L0056     char x;
L0057     LoadVar(S,x);
L0058     return x;
L0059    }
L0060    
L0061    static int LoadInt(LoadState* S)
L0062    {
L0063     int x;
L0064     LoadVar(S,x);
L0065     IF (x<0, "bad integer");
L0066     return x;
L0067    }
L0068    
L0069    static lua_Number LoadNumber(LoadState* S)
L0070    {
L0071     lua_Number x;
L0072     LoadVar(S,x);
L0073     return x;
L0074    }
L0075    
L0076    static TString* LoadString(LoadState* S)
L0077    {
L0078     size_t size;
L0079     LoadVar(S,size);
L0080     if (size==0)
L0081      return NULL;
L0082     else
L0083     {
L0084      char* s=luaZ_openspace(S->L,S->b,size);
L0085      LoadBlock(S,s,size);
L0086      return luaS_newlstr(S->L,s,size-1);		/* remove trailing '\0' */
L0087     }
L0088    }
L0089    
L0090    static void LoadCode(LoadState* S, Proto* f)
L0091    {
L0092     int n=LoadInt(S);
L0093     f->code=luaM_newvector(S->L,n,Instruction);
L0094     f->sizecode=n;
L0095     LoadVector(S,f->code,n,sizeof(Instruction));
L0096    }
L0097    
L0098    static Proto* LoadFunction(LoadState* S, TString* p);
L0099    
L0100    static void LoadConstants(LoadState* S, Proto* f)
L0101    {
L0102     int i,n;
L0103     n=LoadInt(S);
L0104     f->k=luaM_newvector(S->L,n,TValue);
L0105     f->sizek=n;
L0106     for (i=0; i<n; i++) setnilvalue(&f->k[i]);
L0107     for (i=0; i<n; i++)
L0108     {
L0109      TValue* o=&f->k[i];
L0110      int t=LoadChar(S);
L0111      switch (t)
L0112      {
L0113       case LUA_TNIL:
L0114       	setnilvalue(o);
L0115    	break;
L0116       case LUA_TBOOLEAN:
L0117       	setbvalue(o,LoadChar(S)!=0);
L0118    	break;
L0119       case LUA_TNUMBER:
L0120    	setnvalue(o,LoadNumber(S));
L0121    	break;
L0122       case LUA_TSTRING:
L0123    	setsvalue2n(S->L,o,LoadString(S));
L0124    	break;
L0125       default:
L0126    	error(S,"bad constant");
L0127    	break;
L0128      }
L0129     }
L0130     n=LoadInt(S);
L0131     f->p=luaM_newvector(S->L,n,Proto*);
L0132     f->sizep=n;
L0133     for (i=0; i<n; i++) f->p[i]=NULL;
L0134     for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
L0135    }
L0136    
L0137    static void LoadDebug(LoadState* S, Proto* f)
L0138    {
L0139     int i,n;
L0140     n=LoadInt(S);
L0141     f->lineinfo=luaM_newvector(S->L,n,int);
L0142     f->sizelineinfo=n;
L0143     LoadVector(S,f->lineinfo,n,sizeof(int));
L0144     n=LoadInt(S);
L0145     f->locvars=luaM_newvector(S->L,n,LocVar);
L0146     f->sizelocvars=n;
L0147     for (i=0; i<n; i++) f->locvars[i].varname=NULL;
L0148     for (i=0; i<n; i++)
L0149     {
L0150      f->locvars[i].varname=LoadString(S);
L0151      f->locvars[i].startpc=LoadInt(S);
L0152      f->locvars[i].endpc=LoadInt(S);
L0153     }
L0154     n=LoadInt(S);
L0155     f->upvalues=luaM_newvector(S->L,n,TString*);
L0156     f->sizeupvalues=n;
L0157     for (i=0; i<n; i++) f->upvalues[i]=NULL;
L0158     for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
L0159    }
L0160    
L0161    static Proto* LoadFunction(LoadState* S, TString* p)
L0162    {
L0163     Proto* f;
L0164     if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
L0165     f=luaF_newproto(S->L);
L0166     setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
L0167     f->source=LoadString(S); if (f->source==NULL) f->source=p;
L0168     f->linedefined=LoadInt(S);
L0169     f->lastlinedefined=LoadInt(S);
L0170     f->nups=LoadByte(S);
L0171     f->numparams=LoadByte(S);
L0172     f->is_vararg=LoadByte(S);
L0173     f->maxstacksize=LoadByte(S);
L0174     LoadCode(S,f);
L0175     LoadConstants(S,f);
L0176     LoadDebug(S,f);
L0177     IF (!luaG_checkcode(f), "bad code");
L0178     S->L->top--;
L0179     S->L->nCcalls--;
L0180     return f;
L0181    }
L0182    
L0183    static void LoadHeader(LoadState* S)
L0184    {
L0185     char h[LUAC_HEADERSIZE];
L0186     char s[LUAC_HEADERSIZE];
L0187     luaU_header(h);
L0188     LoadBlock(S,s,LUAC_HEADERSIZE);
L0189     IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
L0190    }
L0191    
L0192    /*
L0193    ** load precompiled chunk
L0194    */
L0195    Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
L0196    {
L0197     LoadState S;
L0198     if (*name=='@' || *name=='=')
L0199      S.name=name+1;
L0200     else if (*name==LUA_SIGNATURE[0])
L0201      S.name="binary string";
L0202     else
L0203      S.name=name;
L0204     S.L=L;
L0205     S.Z=Z;
L0206     S.b=buff;
L0207     LoadHeader(&S);
L0208     return LoadFunction(&S,luaS_newliteral(L,"=?"));
L0209    }
L0210    
L0211    /*
L0212    * make header
L0213    */
L0214    void luaU_header (char* h)
L0215    {
L0216     int x=1;
L0217     memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
L0218     h+=sizeof(LUA_SIGNATURE)-1;
L0219     *h++=(char)LUAC_VERSION;
L0220     *h++=(char)LUAC_FORMAT;
L0221     *h++=(char)*(char*)&x;				/* endianness */
L0222     *h++=(char)sizeof(int);
L0223     *h++=(char)sizeof(size_t);
L0224     *h++=(char)sizeof(Instruction);
L0225     *h++=(char)sizeof(lua_Number);
L0226     *h++=(char)(((lua_Number)0.5)==0);		/* is lua_Number integral? */
L0227    }

Generated by pretty.lua