rpm
4.5
|
00001 /* 00002 ** $Id: ldump.c,v 1.1 2004/03/16 21:58:30 niemeyer Exp $ 00003 ** save bytecodes 00004 ** See Copyright Notice in lua.h 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(/*@null@*/ 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; /* include trailing '\0' */ 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, /*@null@*/ 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); /* cannot happen */ 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 ** dump function as precompiled chunk 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