20e8b2398e105384ac676cb8bee73e39877b0998
[olsrd.git] / lib / tas / src / lua / ldump.c
1 /*
2 ** save bytecodes
3 ** See Copyright Notice in lua.h
4 */
5
6 #include <stddef.h>
7
8 #define ldump_c
9
10 #include "lua.h"
11
12 #include "lobject.h"
13 #include "lopcodes.h"
14 #include "lstate.h"
15 #include "lundump.h"
16
17 #define DumpVector(b,n,size,D)  DumpBlock(b,(n)*(size),D)
18 #define DumpLiteral(s,D)        DumpBlock("" s,(sizeof(s))-1,D)
19
20 typedef struct {
21  lua_State* L;
22  lua_Chunkwriter write;
23  void* data;
24 } DumpState;
25
26 static void DumpBlock(const void* b, size_t size, DumpState* D)
27 {
28  lua_unlock(D->L);
29  (*D->write)(D->L,b,size,D->data);
30  lua_lock(D->L);
31 }
32
33 static void DumpByte(int y, DumpState* D)
34 {
35  char x=(char)y;
36  DumpBlock(&x,sizeof(x),D);
37 }
38
39 static void DumpInt(int x, DumpState* D)
40 {
41  DumpBlock(&x,sizeof(x),D);
42 }
43
44 static void DumpSize(size_t x, DumpState* D)
45 {
46  DumpBlock(&x,sizeof(x),D);
47 }
48
49 static void DumpNumber(lua_Number x, DumpState* D)
50 {
51  DumpBlock(&x,sizeof(x),D);
52 }
53
54 static void DumpString(TString* s, DumpState* D)
55 {
56  if (s==NULL || getstr(s)==NULL)
57   DumpSize(0,D);
58  else
59  {
60   size_t size=s->tsv.len+1;             /* include trailing '\0' */
61   DumpSize(size,D);
62   DumpBlock(getstr(s),size,D);
63  }
64 }
65
66 static void DumpCode(const Proto* f, DumpState* D)
67 {
68  DumpInt(f->sizecode,D);
69  DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
70 }
71
72 static void DumpLocals(const Proto* f, DumpState* D)
73 {
74  int i,n=f->sizelocvars;
75  DumpInt(n,D);
76  for (i=0; i<n; i++)
77  {
78   DumpString(f->locvars[i].varname,D);
79   DumpInt(f->locvars[i].startpc,D);
80   DumpInt(f->locvars[i].endpc,D);
81  }
82 }
83
84 static void DumpLines(const Proto* f, DumpState* D)
85 {
86  DumpInt(f->sizelineinfo,D);
87  DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
88 }
89
90 static void DumpUpvalues(const Proto* f, DumpState* D)
91 {
92  int i,n=f->sizeupvalues;
93  DumpInt(n,D);
94  for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
95 }
96
97 static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
98
99 static void DumpConstants(const Proto* f, DumpState* D)
100 {
101  int i,n;
102  DumpInt(n=f->sizek,D);
103  for (i=0; i<n; i++)
104  {
105   const TObject* o= &f->k[i];
106   DumpByte(ttype(o),D);
107   switch (ttype(o))
108   {
109    case LUA_TNUMBER:
110         DumpNumber(nvalue(o),D);
111         break;
112    case LUA_TSTRING:
113         DumpString(tsvalue(o),D);
114         break;
115    case LUA_TNIL:
116         break;
117    default:
118         lua_assert(0);                  /* cannot happen */
119         break;
120   }
121  }
122  DumpInt(n=f->sizep,D);
123  for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
124 }
125
126 static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
127 {
128  DumpString((f->source==p) ? NULL : f->source,D);
129  DumpInt(f->lineDefined,D);
130  DumpByte(f->nups,D);
131  DumpByte(f->numparams,D);
132  DumpByte(f->is_vararg,D);
133  DumpByte(f->maxstacksize,D);
134  DumpLines(f,D);
135  DumpLocals(f,D);
136  DumpUpvalues(f,D);
137  DumpConstants(f,D);
138  DumpCode(f,D);
139 }
140
141 static void DumpHeader(DumpState* D)
142 {
143  DumpLiteral(LUA_SIGNATURE,D);
144  DumpByte(VERSION,D);
145  DumpByte(luaU_endianness(),D);
146  DumpByte(sizeof(int),D);
147  DumpByte(sizeof(size_t),D);
148  DumpByte(sizeof(Instruction),D);
149  DumpByte(SIZE_OP,D);
150  DumpByte(SIZE_A,D);
151  DumpByte(SIZE_B,D);
152  DumpByte(SIZE_C,D);
153  DumpByte(sizeof(lua_Number),D);
154  DumpNumber(TEST_NUMBER,D);
155 }
156
157 /*
158 ** dump function as precompiled chunk
159 */
160 void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
161 {
162  DumpState D;
163  D.L=L;
164  D.write=w;
165  D.data=data;
166  DumpHeader(&D);
167  DumpFunction(Main,NULL,&D);
168 }
169