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