Branch data Line data Source code
1 : : /*
2 : : ** $Id: ldump.c $
3 : : ** save precompiled Lua chunks
4 : : ** See Copyright Notice in lua.h
5 : : */
6 : :
7 : : #define ldump_c
8 : : #define LUA_CORE
9 : :
10 : : #include "lprefix.h"
11 : :
12 : :
13 : : #include <stddef.h>
14 : :
15 : : #include "lua.h"
16 : :
17 : : #include "lobject.h"
18 : : #include "lstate.h"
19 : : #include "lundump.h"
20 : :
21 : :
22 : : typedef struct {
23 : : lua_State *L;
24 : : lua_Writer writer;
25 : : void *data;
26 : : int strip;
27 : : int status;
28 : : } DumpState;
29 : :
30 : :
31 : : /*
32 : : ** All high-level dumps go through dumpVector; you can change it to
33 : : ** change the endianness of the result
34 : : */
35 : : #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0]))
36 : :
37 : : #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char))
38 : :
39 : :
40 : 0 : static void dumpBlock (DumpState *D, const void *b, size_t size) {
41 [ # # # # ]: 0 : if (D->status == 0 && size > 0) {
42 : : lua_unlock(D->L);
43 : 0 : D->status = (*D->writer)(D->L, b, size, D->data);
44 : : lua_lock(D->L);
45 : 0 : }
46 : 0 : }
47 : :
48 : :
49 : : #define dumpVar(D,x) dumpVector(D,&x,1)
50 : :
51 : :
52 : 0 : static void dumpByte (DumpState *D, int y) {
53 : 0 : lu_byte x = (lu_byte)y;
54 : 0 : dumpVar(D, x);
55 : 0 : }
56 : :
57 : :
58 : : /* dumpInt Buff Size */
59 : : #define DIBS ((sizeof(size_t) * 8 / 7) + 1)
60 : :
61 : 0 : static void dumpSize (DumpState *D, size_t x) {
62 : : lu_byte buff[DIBS];
63 : 0 : int n = 0;
64 : 0 : do {
65 : 0 : buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */
66 : 0 : x >>= 7;
67 [ # # ]: 0 : } while (x != 0);
68 : 0 : buff[DIBS - 1] |= 0x80; /* mark last byte */
69 : 0 : dumpVector(D, buff + DIBS - n, n);
70 : 0 : }
71 : :
72 : :
73 : 0 : static void dumpInt (DumpState *D, int x) {
74 : 0 : dumpSize(D, x);
75 : 0 : }
76 : :
77 : :
78 : 0 : static void dumpNumber (DumpState *D, lua_Number x) {
79 : 0 : dumpVar(D, x);
80 : 0 : }
81 : :
82 : :
83 : 0 : static void dumpInteger (DumpState *D, lua_Integer x) {
84 : 0 : dumpVar(D, x);
85 : 0 : }
86 : :
87 : :
88 : 0 : static void dumpString (DumpState *D, const TString *s) {
89 [ # # ]: 0 : if (s == NULL)
90 : 0 : dumpSize(D, 0);
91 : : else {
92 [ # # ]: 0 : size_t size = tsslen(s);
93 : 0 : const char *str = getstr(s);
94 : 0 : dumpSize(D, size + 1);
95 : 0 : dumpVector(D, str, size);
96 : : }
97 : 0 : }
98 : :
99 : :
100 : 0 : static void dumpCode (DumpState *D, const Proto *f) {
101 : 0 : dumpInt(D, f->sizecode);
102 : 0 : dumpVector(D, f->code, f->sizecode);
103 : 0 : }
104 : :
105 : :
106 : : static void dumpFunction(DumpState *D, const Proto *f, TString *psource);
107 : :
108 : 0 : static void dumpConstants (DumpState *D, const Proto *f) {
109 : : int i;
110 : 0 : int n = f->sizek;
111 : 0 : dumpInt(D, n);
112 [ # # ]: 0 : for (i = 0; i < n; i++) {
113 : 0 : const TValue *o = &f->k[i];
114 : 0 : int tt = ttypetag(o);
115 : 0 : dumpByte(D, tt);
116 [ # # # # ]: 0 : switch (tt) {
117 : : case LUA_VNUMFLT:
118 : 0 : dumpNumber(D, fltvalue(o));
119 : 0 : break;
120 : : case LUA_VNUMINT:
121 : 0 : dumpInteger(D, ivalue(o));
122 : 0 : break;
123 : : case LUA_VSHRSTR:
124 : : case LUA_VLNGSTR:
125 : 0 : dumpString(D, tsvalue(o));
126 : 0 : break;
127 : : default:
128 : : lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE);
129 : 0 : }
130 : 0 : }
131 : 0 : }
132 : :
133 : :
134 : 0 : static void dumpProtos (DumpState *D, const Proto *f) {
135 : : int i;
136 : 0 : int n = f->sizep;
137 : 0 : dumpInt(D, n);
138 [ # # ]: 0 : for (i = 0; i < n; i++)
139 : 0 : dumpFunction(D, f->p[i], f->source);
140 : 0 : }
141 : :
142 : :
143 : 0 : static void dumpUpvalues (DumpState *D, const Proto *f) {
144 : 0 : int i, n = f->sizeupvalues;
145 : 0 : dumpInt(D, n);
146 [ # # ]: 0 : for (i = 0; i < n; i++) {
147 : 0 : dumpByte(D, f->upvalues[i].instack);
148 : 0 : dumpByte(D, f->upvalues[i].idx);
149 : 0 : dumpByte(D, f->upvalues[i].kind);
150 : 0 : }
151 : 0 : }
152 : :
153 : :
154 : 0 : static void dumpDebug (DumpState *D, const Proto *f) {
155 : : int i, n;
156 [ # # ]: 0 : n = (D->strip) ? 0 : f->sizelineinfo;
157 : 0 : dumpInt(D, n);
158 : 0 : dumpVector(D, f->lineinfo, n);
159 [ # # ]: 0 : n = (D->strip) ? 0 : f->sizeabslineinfo;
160 : 0 : dumpInt(D, n);
161 [ # # ]: 0 : for (i = 0; i < n; i++) {
162 : 0 : dumpInt(D, f->abslineinfo[i].pc);
163 : 0 : dumpInt(D, f->abslineinfo[i].line);
164 : 0 : }
165 [ # # ]: 0 : n = (D->strip) ? 0 : f->sizelocvars;
166 : 0 : dumpInt(D, n);
167 [ # # ]: 0 : for (i = 0; i < n; i++) {
168 : 0 : dumpString(D, f->locvars[i].varname);
169 : 0 : dumpInt(D, f->locvars[i].startpc);
170 : 0 : dumpInt(D, f->locvars[i].endpc);
171 : 0 : }
172 [ # # ]: 0 : n = (D->strip) ? 0 : f->sizeupvalues;
173 : 0 : dumpInt(D, n);
174 [ # # ]: 0 : for (i = 0; i < n; i++)
175 : 0 : dumpString(D, f->upvalues[i].name);
176 : 0 : }
177 : :
178 : :
179 : 0 : static void dumpFunction (DumpState *D, const Proto *f, TString *psource) {
180 [ # # # # ]: 0 : if (D->strip || f->source == psource)
181 : 0 : dumpString(D, NULL); /* no debug info or same source as its parent */
182 : : else
183 : 0 : dumpString(D, f->source);
184 : 0 : dumpInt(D, f->linedefined);
185 : 0 : dumpInt(D, f->lastlinedefined);
186 : 0 : dumpByte(D, f->numparams);
187 : 0 : dumpByte(D, f->is_vararg);
188 : 0 : dumpByte(D, f->maxstacksize);
189 : 0 : dumpCode(D, f);
190 : 0 : dumpConstants(D, f);
191 : 0 : dumpUpvalues(D, f);
192 : 0 : dumpProtos(D, f);
193 : 0 : dumpDebug(D, f);
194 : 0 : }
195 : :
196 : :
197 : 0 : static void dumpHeader (DumpState *D) {
198 : 0 : dumpLiteral(D, LUA_SIGNATURE);
199 : 0 : dumpByte(D, LUAC_VERSION);
200 : 0 : dumpByte(D, LUAC_FORMAT);
201 : 0 : dumpLiteral(D, LUAC_DATA);
202 : 0 : dumpByte(D, sizeof(Instruction));
203 : 0 : dumpByte(D, sizeof(lua_Integer));
204 : 0 : dumpByte(D, sizeof(lua_Number));
205 : 0 : dumpInteger(D, LUAC_INT);
206 : 0 : dumpNumber(D, LUAC_NUM);
207 : 0 : }
208 : :
209 : :
210 : : /*
211 : : ** dump Lua function as precompiled chunk
212 : : */
213 : 0 : int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
214 : : int strip) {
215 : : DumpState D;
216 : 0 : D.L = L;
217 : 0 : D.writer = w;
218 : 0 : D.data = data;
219 : 0 : D.strip = strip;
220 : 0 : D.status = 0;
221 : 0 : dumpHeader(&D);
222 : 0 : dumpByte(&D, f->sizeupvalues);
223 : 0 : dumpFunction(&D, f, NULL);
224 : 0 : return D.status;
225 : : }
226 : :
|