00001
00002
00003
00004
00005
00006
00007 #include <stddef.h>
00008
00009 #define ldump_c
00010 #define LUA_CORE
00011
00012 #include "lua.h"
00013
00014 #include "lobject.h"
00015 #include "lstate.h"
00016 #include "lundump.h"
00017
00018 typedef struct {
00019 lua_State* L;
00020 lua_Writer writer;
00021 void* data;
00022 int strip;
00023 int status;
00024 } DumpState;
00025
00026 #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
00027 #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
00028
00029 static void DumpBlock(const void* b, size_t size, DumpState* D)
00030 {
00031 if (D->status==0)
00032 {
00033 lua_unlock(D->L);
00034 D->status=(*D->writer)(D->L,b,size,D->data);
00035 lua_lock(D->L);
00036 }
00037 }
00038
00039 static void DumpChar(int y, DumpState* D)
00040 {
00041 char x=(char)y;
00042 DumpVar(x,D);
00043 }
00044
00045 static void DumpInt(int x, DumpState* D)
00046 {
00047 DumpVar(x,D);
00048 }
00049
00050 static void DumpNumber(lua_Number x, DumpState* D)
00051 {
00052 DumpVar(x,D);
00053 }
00054
00055 static void DumpVector(const void* b, int n, size_t size, DumpState* D)
00056 {
00057 DumpInt(n,D);
00058 DumpMem(b,n,size,D);
00059 }
00060
00061 static void DumpString(const TString* s, DumpState* D)
00062 {
00063 if (s==NULL)
00064 {
00065 size_t size=0;
00066 DumpVar(size,D);
00067 }
00068 else
00069 {
00070 size_t size=s->tsv.len+1;
00071 DumpVar(size,D);
00072 DumpBlock(getstr(s),size*sizeof(char),D);
00073 }
00074 }
00075
00076 #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
00077
00078 static void DumpFunction(const Proto* f, DumpState* D);
00079
00080 static void DumpConstants(const Proto* f, DumpState* D)
00081 {
00082 int i,n=f->sizek;
00083 DumpInt(n,D);
00084 for (i=0; i<n; i++)
00085 {
00086 const TValue* o=&f->k[i];
00087 DumpChar(ttype(o),D);
00088 switch (ttype(o))
00089 {
00090 case LUA_TNIL:
00091 break;
00092 case LUA_TBOOLEAN:
00093 DumpChar(bvalue(o),D);
00094 break;
00095 case LUA_TNUMBER:
00096 DumpNumber(nvalue(o),D);
00097 break;
00098 case LUA_TSTRING:
00099 DumpString(rawtsvalue(o),D);
00100 break;
00101 }
00102 }
00103 n=f->sizep;
00104 DumpInt(n,D);
00105 for (i=0; i<n; i++) DumpFunction(f->p[i],D);
00106 }
00107
00108 static void DumpUpvalues(const Proto* f, DumpState* D)
00109 {
00110 int i,n=f->sizeupvalues;
00111 DumpInt(n,D);
00112 for (i=0; i<n; i++)
00113 {
00114 DumpChar(f->upvalues[i].instack,D);
00115 DumpChar(f->upvalues[i].idx,D);
00116 }
00117 }
00118
00119 static void DumpDebug(const Proto* f, DumpState* D)
00120 {
00121 int i,n;
00122 DumpString((D->strip) ? NULL : f->source,D);
00123 n= (D->strip) ? 0 : f->sizelineinfo;
00124 DumpVector(f->lineinfo,n,sizeof(int),D);
00125 n= (D->strip) ? 0 : f->sizelocvars;
00126 DumpInt(n,D);
00127 for (i=0; i<n; i++)
00128 {
00129 DumpString(f->locvars[i].varname,D);
00130 DumpInt(f->locvars[i].startpc,D);
00131 DumpInt(f->locvars[i].endpc,D);
00132 }
00133 n= (D->strip) ? 0 : f->sizeupvalues;
00134 DumpInt(n,D);
00135 for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
00136 }
00137
00138 static void DumpFunction(const Proto* f, DumpState* D)
00139 {
00140 DumpInt(f->linedefined,D);
00141 DumpInt(f->lastlinedefined,D);
00142 DumpChar(f->numparams,D);
00143 DumpChar(f->is_vararg,D);
00144 DumpChar(f->maxstacksize,D);
00145 DumpCode(f,D);
00146 DumpConstants(f,D);
00147 DumpUpvalues(f,D);
00148 DumpDebug(f,D);
00149 }
00150
00151 static void DumpHeader(DumpState* D)
00152 {
00153 lu_byte h[LUAC_HEADERSIZE];
00154 luaU_header(h);
00155 DumpBlock(h,LUAC_HEADERSIZE,D);
00156 }
00157
00158
00159
00160
00161 int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
00162 {
00163 DumpState D;
00164 D.L=L;
00165 D.writer=w;
00166 D.data=data;
00167 D.strip=strip;
00168 D.status=0;
00169 DumpHeader(&D);
00170 DumpFunction(f,&D);
00171 return D.status;
00172 }