rpm  4.5
ldump.c
Go to the documentation of this file.
1 /*
2 ** $Id: ldump.c,v 1.1 2004/03/16 21:58:30 niemeyer 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 {
23  lua_Chunkwriter write;
24  void* data;
25 } DumpState;
26 
27 static void DumpBlock(const void* b, size_t size, DumpState* D)
28  /*@*/
29 {
30  lua_unlock(D->L);
31  (*D->write)(D->L,b,size,D->data);
32  lua_lock(D->L);
33 }
34 
35 static void DumpByte(int y, DumpState* D)
36  /*@*/
37 {
38  char x=(char)y;
39  DumpBlock(&x,sizeof(x),D);
40 }
41 
42 static void DumpInt(int x, DumpState* D)
43  /*@*/
44 {
45  DumpBlock(&x,sizeof(x),D);
46 }
47 
48 static void DumpSize(size_t x, DumpState* D)
49  /*@*/
50 {
51  DumpBlock(&x,sizeof(x),D);
52 }
53 
54 static void DumpNumber(lua_Number x, DumpState* D)
55  /*@*/
56 {
57  DumpBlock(&x,sizeof(x),D);
58 }
59 
60 static void DumpString(/*@null@*/ TString* s, DumpState* D)
61  /*@*/
62 {
63  if (s==NULL || getstr(s)==NULL)
64  DumpSize(0,D);
65  else
66  {
67  size_t size=s->tsv.len+1; /* include trailing '\0' */
68  DumpSize(size,D);
69  DumpBlock(getstr(s),size,D);
70  }
71 }
72 
73 static void DumpCode(const Proto* f, DumpState* D)
74  /*@*/
75 {
76  DumpInt(f->sizecode,D);
77  DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
78 }
79 
80 static void DumpLocals(const Proto* f, DumpState* D)
81  /*@*/
82 {
83  int i,n=f->sizelocvars;
84  DumpInt(n,D);
85  for (i=0; i<n; i++)
86  {
87  DumpString(f->locvars[i].varname,D);
88  DumpInt(f->locvars[i].startpc,D);
89  DumpInt(f->locvars[i].endpc,D);
90  }
91 }
92 
93 static void DumpLines(const Proto* f, DumpState* D)
94  /*@*/
95 {
96  DumpInt(f->sizelineinfo,D);
97  DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
98 }
99 
100 static void DumpUpvalues(const Proto* f, DumpState* D)
101  /*@*/
102 {
103  int i,n=f->sizeupvalues;
104  DumpInt(n,D);
105  for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
106 }
107 
108 static void DumpFunction(const Proto* f, /*@null@*/ const TString* p, DumpState* D) /*@*/;
109 
110 static void DumpConstants(const Proto* f, DumpState* D)
111  /*@*/
112 {
113  int i,n;
114  DumpInt(n=f->sizek,D);
115  for (i=0; i<n; i++)
116  {
117  const TObject* o=&f->k[i];
118  DumpByte(ttype(o),D);
119  switch (ttype(o))
120  {
121  case LUA_TNUMBER:
122  DumpNumber(nvalue(o),D);
123  break;
124  case LUA_TSTRING:
125  DumpString(tsvalue(o),D);
126  break;
127  case LUA_TNIL:
128  break;
129  default:
130  lua_assert(0); /* cannot happen */
131  break;
132  }
133  }
134  DumpInt(n=f->sizep,D);
135  for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
136 }
137 
138 static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
139  /*@*/
140 {
141  DumpString((f->source==p) ? NULL : f->source,D);
142  DumpInt(f->lineDefined,D);
143  DumpByte(f->nups,D);
144  DumpByte(f->numparams,D);
145  DumpByte(f->is_vararg,D);
146  DumpByte(f->maxstacksize,D);
147  DumpLines(f,D);
148  DumpLocals(f,D);
149  DumpUpvalues(f,D);
150  DumpConstants(f,D);
151  DumpCode(f,D);
152 }
153 
154 static void DumpHeader(DumpState* D)
155  /*@*/
156 {
158  DumpByte(VERSION,D);
160  DumpByte(sizeof(int),D);
161  DumpByte(sizeof(size_t),D);
162  DumpByte(sizeof(Instruction),D);
163  DumpByte(SIZE_OP,D);
164  DumpByte(SIZE_A,D);
165  DumpByte(SIZE_B,D);
166  DumpByte(SIZE_C,D);
167  DumpByte(sizeof(lua_Number),D);
169 }
170 
171 /*
172 ** dump function as precompiled chunk
173 */
174 void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
175 {
176  DumpState D;
177  D.L=L;
178  D.write=w;
179  D.data=data;
180  DumpHeader(&D);
181  DumpFunction(Main,NULL,&D);
182 }
183