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 || getstr(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,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, const TString* p, 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 default:
00102 lua_assert(0);
00103 break;
00104 }
00105 }
00106 n=f->sizep;
00107 DumpInt(n,D);
00108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
00109 }
00110
00111 static void DumpDebug(const Proto* f, DumpState* D)
00112 {
00113 int i,n;
00114 n= (D->strip) ? 0 : f->sizelineinfo;
00115 DumpVector(f->lineinfo,n,sizeof(int),D);
00116 n= (D->strip) ? 0 : f->sizelocvars;
00117 DumpInt(n,D);
00118 for (i=0; i<n; i++)
00119 {
00120 DumpString(f->locvars[i].varname,D);
00121 DumpInt(f->locvars[i].startpc,D);
00122 DumpInt(f->locvars[i].endpc,D);
00123 }
00124 n= (D->strip) ? 0 : f->sizeupvalues;
00125 DumpInt(n,D);
00126 for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
00127 }
00128
00129 static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
00130 {
00131 DumpString((f->source==p || D->strip) ? NULL : f->source,D);
00132 DumpInt(f->linedefined,D);
00133 DumpInt(f->lastlinedefined,D);
00134 DumpChar(f->nups,D);
00135 DumpChar(f->numparams,D);
00136 DumpChar(f->is_vararg,D);
00137 DumpChar(f->maxstacksize,D);
00138 DumpCode(f,D);
00139 DumpConstants(f,D);
00140 DumpDebug(f,D);
00141 }
00142
00143 static void DumpHeader(DumpState* D)
00144 {
00145 char h[LUAC_HEADERSIZE];
00146 luaU_header(h);
00147 DumpBlock(h,LUAC_HEADERSIZE,D);
00148 }
00149
00150
00151
00152
00153 int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
00154 {
00155 DumpState D;
00156 D.L=L;
00157 D.writer=w;
00158 D.data=data;
00159 D.strip=strip;
00160 D.status=0;
00161 DumpHeader(&D);
00162 DumpFunction(f,NULL,&D);
00163 return D.status;
00164 }