Lua 5.1.4: lundump.c
L0001
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);
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
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
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;
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);
L0227 }
Generated by pretty.lua