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