- /* 
- ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $ 
- ** load precompiled Lua chunks 
- ** See Copyright Notice in lua.h 
- */ 
-   
- #define lundump_c 
- #define LUA_CORE 
-   
- #include "lprefix.h" 
-   
-   
- #include <string.h> 
-   
- #include "lua.h" 
-   
- #include "ldebug.h" 
- #include "ldo.h" 
- #include "lfunc.h" 
- #include "lmem.h" 
- #include "lobject.h" 
- #include "lstring.h" 
- #include "lundump.h" 
- #include "lzio.h" 
-   
-   
- #if !defined(luai_verifycode) 
- #define luai_verifycode(L,b,f)  /* empty */ 
- #endif 
-   
-   
- typedef struct { 
-   lua_State *L; 
-   ZIO *Z; 
-   const char *name; 
- } LoadState; 
-   
-   
- static l_noret error(LoadState *S, const char *why) { 
-   luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); 
-   luaD_throw(S->L, LUA_ERRSYNTAX); 
- } 
-   
-   
- /* 
- ** All high-level loads go through LoadVector; you can change it to 
- ** adapt to the endianness of the input 
- */ 
- #define LoadVector(S,b,n)       LoadBlock(S,b,(n)*sizeof((b)[0])) 
-   
- static void LoadBlock (LoadState *S, void *b, size_t size) { 
-   if (luaZ_read(S->Z, b, size) != 0) 
-     error(S, "truncated"); 
- } 
-   
-   
- #define LoadVar(S,x)            LoadVector(S,&x,1) 
-   
-   
- static lu_byte LoadByte (LoadState *S) { 
-   lu_byte x; 
-   LoadVar(S, x); 
-   return x; 
- } 
-   
-   
- static int LoadInt (LoadState *S) { 
-   int x; 
-   LoadVar(S, x); 
-   return x; 
- } 
-   
-   
- static lua_Number LoadNumber (LoadState *S) { 
-   lua_Number x; 
-   LoadVar(S, x); 
-   return x; 
- } 
-   
-   
- static lua_Integer LoadInteger (LoadState *S) { 
-   lua_Integer x; 
-   LoadVar(S, x); 
-   return x; 
- } 
-   
-   
- static TString *LoadString (LoadState *S, Proto *p) { 
-   lua_State *L = S->L; 
-   size_t size = LoadByte(S); 
-   TString *ts; 
-   if (size == 0xFF) 
-     LoadVar(S, size); 
-   if (size == 0) 
-     return NULL; 
-   else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */ 
-     char buff[LUAI_MAXSHORTLEN]; 
-     LoadVector(S, buff, size); 
-     ts = luaS_newlstr(L, buff, size); 
-   } 
-   else {  /* long string */ 
-     ts = luaS_createlngstrobj(L, size); 
-     setsvalue2s(L, L->top, ts);  /* anchor it ('loadVector' can GC) */ 
-     luaD_inctop(L); 
-     LoadVector(S, getstr(ts), size);  /* load directly in final place */ 
-     L->top--;  /* pop string */ 
-   } 
-   luaC_objbarrier(L, p, ts); 
-   return ts; 
- } 
-   
-   
- static void LoadCode (LoadState *S, Proto *f) { 
-   int n = LoadInt(S); 
-   f->code = luaM_newvector(S->L, n, Instruction); 
-   f->sizecode = n; 
-   LoadVector(S, f->code, n); 
- } 
-   
-   
- static void LoadFunction(LoadState *S, Proto *f, TString *psource); 
-   
-   
- static void LoadConstants (LoadState *S, Proto *f) { 
-   int i; 
-   int n = LoadInt(S); 
-   f->k = luaM_newvector(S->L, n, TValue); 
-   f->sizek = n; 
-   for (i = 0; i < n; i++) 
-     setnilvalue(&f->k[i]); 
-   for (i = 0; i < n; i++) { 
-     TValue *o = &f->k[i]; 
-     int t = LoadByte(S); 
-     switch (t) { 
-     case LUA_TNIL: 
-       setnilvalue(o); 
-       break; 
-     case LUA_TBOOLEAN: 
-       setbvalue(o, LoadByte(S)); 
-       break; 
-     case LUA_TNUMFLT: 
-       setfltvalue(o, LoadNumber(S)); 
-       break; 
-     case LUA_TNUMINT: 
-       setivalue(o, LoadInteger(S)); 
-       break; 
-     case LUA_TSHRSTR: 
-     case LUA_TLNGSTR: 
-       setsvalue2n(S->L, o, LoadString(S, f)); 
-       break; 
-     default: 
-       lua_assert(0); 
-     } 
-   } 
- } 
-   
-   
- static void LoadProtos (LoadState *S, Proto *f) { 
-   int i; 
-   int n = LoadInt(S); 
-   f->p = luaM_newvector(S->L, n, Proto *); 
-   f->sizep = n; 
-   for (i = 0; i < n; i++) 
-     f->p[i] = NULL; 
-   for (i = 0; i < n; i++) { 
-     f->p[i] = luaF_newproto(S->L); 
-     luaC_objbarrier(S->L, f, f->p[i]); 
-     LoadFunction(S, f->p[i], f->source); 
-   } 
- } 
-   
-   
- static void LoadUpvalues (LoadState *S, Proto *f) { 
-   int i, n; 
-   n = LoadInt(S); 
-   f->upvalues = luaM_newvector(S->L, n, Upvaldesc); 
-   f->sizeupvalues = n; 
-   for (i = 0; i < n; i++) 
-     f->upvalues[i].name = NULL; 
-   for (i = 0; i < n; i++) { 
-     f->upvalues[i].instack = LoadByte(S); 
-     f->upvalues[i].idx = LoadByte(S); 
-   } 
- } 
-   
-   
- static void LoadDebug (LoadState *S, Proto *f) { 
-   int i, n; 
-   n = LoadInt(S); 
-   f->lineinfo = luaM_newvector(S->L, n, int); 
-   f->sizelineinfo = n; 
-   LoadVector(S, f->lineinfo, n); 
-   n = LoadInt(S); 
-   f->locvars = luaM_newvector(S->L, n, LocVar); 
-   f->sizelocvars = n; 
-   for (i = 0; i < n; i++) 
-     f->locvars[i].varname = NULL; 
-   for (i = 0; i < n; i++) { 
-     f->locvars[i].varname = LoadString(S, f); 
-     f->locvars[i].startpc = LoadInt(S); 
-     f->locvars[i].endpc = LoadInt(S); 
-   } 
-   n = LoadInt(S); 
-   for (i = 0; i < n; i++) 
-     f->upvalues[i].name = LoadString(S, f); 
- } 
-   
-   
- static void LoadFunction (LoadState *S, Proto *f, TString *psource) { 
-   f->source = LoadString(S, f); 
-   if (f->source == NULL)  /* no source in dump? */ 
-     f->source = psource;  /* reuse parent's source */ 
-   f->linedefined = LoadInt(S); 
-   f->lastlinedefined = LoadInt(S); 
-   f->numparams = LoadByte(S); 
-   f->is_vararg = LoadByte(S); 
-   f->maxstacksize = LoadByte(S); 
-   LoadCode(S, f); 
-   LoadConstants(S, f); 
-   LoadUpvalues(S, f); 
-   LoadProtos(S, f); 
-   LoadDebug(S, f); 
- } 
-   
-   
- static void checkliteral (LoadState *S, const char *s, const char *msg) { 
-   char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 
-   LoadVector(S, buff, len); 
-   if (memcmp(- s ,-  buff ,-  len ) != 0)
 
-     error(S, msg); 
- } 
-   
-   
- static void fchecksize (LoadState *S, size_t size, const char *tname) { 
-   if (LoadByte(S) != size) 
-     error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); 
- } 
-   
-   
- #define checksize(S,t)  fchecksize(S,sizeof(t),#t) 
-   
- static void checkHeader (LoadState *S) { 
-   checkliteral(S, LUA_SIGNATURE + 1, "not a");  /* 1st char already checked */ 
-   if (LoadByte(S) != LUAC_VERSION) 
-     error(S, "version mismatch in"); 
-   if (LoadByte(S) != LUAC_FORMAT) 
-     error(S, "format mismatch in"); 
-   checkliteral(S, LUAC_DATA, "corrupted"); 
-   checksize(S, int); 
-   checksize(S, size_t); 
-   checksize(S, Instruction); 
-   checksize(S, lua_Integer); 
-   checksize(S, lua_Number); 
-   if (LoadInteger(S) != LUAC_INT) 
-     error(S, "endianness mismatch in"); 
-   if (LoadNumber(S) != LUAC_NUM) 
-     error(S, "float format mismatch in"); 
- } 
-   
-   
- /* 
- ** load precompiled chunk 
- */ 
- LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 
-   LoadState S; 
-   LClosure *cl; 
-   if (*name == '@' || *name == '=') 
-     S.name = name + 1; 
-   else if (*name == LUA_SIGNATURE[0]) 
-     S.name = "binary string"; 
-   else 
-     S.name = name; 
-   S.L = L; 
-   S.Z = Z; 
-   checkHeader(&S); 
-   cl = luaF_newLclosure(L, LoadByte(&S)); 
-   setclLvalue(L, L->top, cl); 
-   luaD_inctop(L); 
-   cl->p = luaF_newproto(L); 
-   luaC_objbarrier(L, cl, cl->p); 
-   LoadFunction(&S, cl->p, NULL); 
-   lua_assert(cl->nupvalues == cl->p->sizeupvalues); 
-   luai_verifycode(L, buff, cl->p); 
-   return cl; 
- } 
-   
-