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