/* ** $Id: ldump.c,v 2.23 2014/02/28 16:13:01 roberto Exp roberto $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ #include #define ldump_c #define LUA_CORE #include "lua.h" #include "lobject.h" #include "lstate.h" #include "lundump.h" typedef struct { lua_State* L; lua_Writer writer; void* data; int strip; int status; } DumpState; #define DumpVar(x,D) DumpBlock(&x,sizeof(x),D) #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) static void DumpBlock(const void* b, size_t size, DumpState* D) { if (D->status==0) { lua_unlock(D->L); D->status=(*D->writer)(D->L,b,size,D->data); lua_lock(D->L); } } static void DumpByte(int y, DumpState* D) { lu_byte x=(lu_byte)y; DumpVar(x,D); } static void DumpInt(int x, DumpState* D) { DumpVar(x,D); } static void DumpNumber(lua_Number x, DumpState* D) { DumpVar(x,D); } static void DumpInteger(lua_Integer x, DumpState* D) { DumpVar(x,D); } static void DumpString(const TString* s, DumpState* D) { if (s==NULL) DumpByte(0,D); else { size_t size = s->tsv.len+1; /* include trailing '\0' */ if (size < 0xFF) DumpByte(size,D); else { DumpByte(0xFF,D); DumpVar(size,D); } DumpVector(getstr(s),size-1,D); /* no need to save '\0' */ } } static void DumpCode(const Proto* f, DumpState* D) { DumpInt(f->sizecode,D); DumpVector(f->code,f->sizecode,D); } static void DumpFunction(const Proto* f, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { int i,n=f->sizek; DumpInt(n,D); for (i=0; ik[i]; DumpByte(ttype(o),D); switch (ttype(o)) { case LUA_TNIL: break; case LUA_TBOOLEAN: DumpByte(bvalue(o),D); break; case LUA_TNUMFLT: DumpNumber(fltvalue(o),D); break; case LUA_TNUMINT: DumpInteger(ivalue(o),D); break; case LUA_TSHRSTR: case LUA_TLNGSTR: DumpString(rawtsvalue(o),D); break; default: lua_assert(0); } } n=f->sizep; DumpInt(n,D); for (i=0; ip[i],D); } static void DumpUpvalues(const Proto* f, DumpState* D) { int i,n=f->sizeupvalues; DumpInt(n,D); for (i=0; iupvalues[i].instack,D); DumpByte(f->upvalues[i].idx,D); } } static void DumpDebug(const Proto* f, DumpState* D) { int i,n; DumpString((D->strip) ? NULL : f->source,D); n= (D->strip) ? 0 : f->sizelineinfo; DumpInt(n,D); DumpVector(f->lineinfo,n,D); n= (D->strip) ? 0 : f->sizelocvars; DumpInt(n,D); for (i=0; ilocvars[i].varname,D); DumpInt(f->locvars[i].startpc,D); DumpInt(f->locvars[i].endpc,D); } n= (D->strip) ? 0 : f->sizeupvalues; DumpInt(n,D); for (i=0; iupvalues[i].name,D); } static void DumpFunction(const Proto* f, DumpState* D) { DumpInt(f->linedefined,D); DumpInt(f->lastlinedefined,D); DumpByte(f->numparams,D); DumpByte(f->is_vararg,D); DumpByte(f->maxstacksize,D); DumpCode(f,D); DumpConstants(f,D); DumpUpvalues(f,D); DumpDebug(f,D); } static void DumpHeader(DumpState* D) { DumpBlock(LUA_SIGNATURE,sizeof(LUA_SIGNATURE),D); DumpBlock(LUAC_DATA,sizeof(LUAC_DATA),D); DumpByte(LUAC_VERSION,D); DumpByte(LUAC_FORMAT,D); DumpByte(sizeof(int),D); DumpByte(sizeof(size_t),D); DumpByte(sizeof(Instruction),D); DumpByte(sizeof(lua_Integer),D); DumpByte(sizeof(lua_Number),D); DumpInteger(LUAC_INT,D); DumpNumber(LUAC_NUM,D); } /* ** dump Lua function as precompiled chunk */ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { DumpState D; D.L=L; D.writer=w; D.data=data; D.strip=strip; D.status=0; DumpHeader(&D); DumpByte(f->sizeupvalues,&D); DumpFunction(f,&D); return D.status; }