xref: /minix3/external/mit/lua/dist/src/ldump.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: ldump.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $	*/
211be35a1SLionel Sambuc 
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp
511be35a1SLionel Sambuc ** save precompiled Lua chunks
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc 
911be35a1SLionel Sambuc #define ldump_c
1011be35a1SLionel Sambuc #define LUA_CORE
1111be35a1SLionel Sambuc 
12*0a6a1f1dSLionel Sambuc #include "lprefix.h"
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
16*0a6a1f1dSLionel Sambuc #include <stddef.h>
17*0a6a1f1dSLionel Sambuc #endif
18*0a6a1f1dSLionel Sambuc 
1911be35a1SLionel Sambuc #include "lua.h"
2011be35a1SLionel Sambuc 
2111be35a1SLionel Sambuc #include "lobject.h"
2211be35a1SLionel Sambuc #include "lstate.h"
2311be35a1SLionel Sambuc #include "lundump.h"
2411be35a1SLionel Sambuc 
25*0a6a1f1dSLionel Sambuc 
2611be35a1SLionel Sambuc typedef struct {
2711be35a1SLionel Sambuc   lua_State *L;
2811be35a1SLionel Sambuc   lua_Writer writer;
2911be35a1SLionel Sambuc   void *data;
3011be35a1SLionel Sambuc   int strip;
3111be35a1SLionel Sambuc   int status;
3211be35a1SLionel Sambuc } DumpState;
3311be35a1SLionel Sambuc 
3411be35a1SLionel Sambuc 
35*0a6a1f1dSLionel Sambuc /*
36*0a6a1f1dSLionel Sambuc ** All high-level dumps go through DumpVector; you can change it to
37*0a6a1f1dSLionel Sambuc ** change the endianness of the result
38*0a6a1f1dSLionel Sambuc */
39*0a6a1f1dSLionel Sambuc #define DumpVector(v,n,D)	DumpBlock(v,(n)*sizeof((v)[0]),D)
40*0a6a1f1dSLionel Sambuc 
41*0a6a1f1dSLionel Sambuc #define DumpLiteral(s,D)	DumpBlock(s, sizeof(s) - sizeof(char), D)
42*0a6a1f1dSLionel Sambuc 
43*0a6a1f1dSLionel Sambuc 
DumpBlock(const void * b,size_t size,DumpState * D)44*0a6a1f1dSLionel Sambuc static void DumpBlock (const void *b, size_t size, DumpState *D) {
45*0a6a1f1dSLionel Sambuc   if (D->status == 0) {
4611be35a1SLionel Sambuc     lua_unlock(D->L);
4711be35a1SLionel Sambuc     D->status = (*D->writer)(D->L, b, size, D->data);
4811be35a1SLionel Sambuc     lua_lock(D->L);
4911be35a1SLionel Sambuc   }
5011be35a1SLionel Sambuc }
5111be35a1SLionel Sambuc 
52*0a6a1f1dSLionel Sambuc 
53*0a6a1f1dSLionel Sambuc #define DumpVar(x,D)		DumpVector(&x,1,D)
54*0a6a1f1dSLionel Sambuc 
55*0a6a1f1dSLionel Sambuc 
DumpByte(int y,DumpState * D)56*0a6a1f1dSLionel Sambuc static void DumpByte (int y, DumpState *D) {
57*0a6a1f1dSLionel Sambuc   lu_byte x = (lu_byte)y;
5811be35a1SLionel Sambuc   DumpVar(x, D);
5911be35a1SLionel Sambuc }
6011be35a1SLionel Sambuc 
61*0a6a1f1dSLionel Sambuc 
DumpInt(int x,DumpState * D)62*0a6a1f1dSLionel Sambuc static void DumpInt (int x, DumpState *D) {
6311be35a1SLionel Sambuc   DumpVar(x, D);
6411be35a1SLionel Sambuc }
6511be35a1SLionel Sambuc 
66*0a6a1f1dSLionel Sambuc 
DumpNumber(lua_Number x,DumpState * D)67*0a6a1f1dSLionel Sambuc static void DumpNumber (lua_Number x, DumpState *D) {
6811be35a1SLionel Sambuc   DumpVar(x, D);
6911be35a1SLionel Sambuc }
7011be35a1SLionel Sambuc 
71*0a6a1f1dSLionel Sambuc 
DumpInteger(lua_Integer x,DumpState * D)72*0a6a1f1dSLionel Sambuc static void DumpInteger (lua_Integer x, DumpState *D) {
73*0a6a1f1dSLionel Sambuc   DumpVar(x, D);
7411be35a1SLionel Sambuc }
7511be35a1SLionel Sambuc 
76*0a6a1f1dSLionel Sambuc 
DumpString(const TString * s,DumpState * D)77*0a6a1f1dSLionel Sambuc static void DumpString (const TString *s, DumpState *D) {
78*0a6a1f1dSLionel Sambuc   if (s == NULL)
79*0a6a1f1dSLionel Sambuc     DumpByte(0, D);
80*0a6a1f1dSLionel Sambuc   else {
81*0a6a1f1dSLionel Sambuc     size_t size = tsslen(s) + 1;  /* include trailing '\0' */
82*0a6a1f1dSLionel Sambuc     const char *str = getstr(s);
83*0a6a1f1dSLionel Sambuc     if (size < 0xFF)
84*0a6a1f1dSLionel Sambuc       DumpByte(cast_int(size), D);
85*0a6a1f1dSLionel Sambuc     else {
86*0a6a1f1dSLionel Sambuc       DumpByte(0xFF, D);
8711be35a1SLionel Sambuc       DumpVar(size, D);
8811be35a1SLionel Sambuc     }
89*0a6a1f1dSLionel Sambuc     DumpVector(str, size - 1, D);  /* no need to save '\0' */
9011be35a1SLionel Sambuc   }
9111be35a1SLionel Sambuc }
9211be35a1SLionel Sambuc 
9311be35a1SLionel Sambuc 
DumpCode(const Proto * f,DumpState * D)94*0a6a1f1dSLionel Sambuc static void DumpCode (const Proto *f, DumpState *D) {
95*0a6a1f1dSLionel Sambuc   DumpInt(f->sizecode, D);
96*0a6a1f1dSLionel Sambuc   DumpVector(f->code, f->sizecode, D);
97*0a6a1f1dSLionel Sambuc }
9811be35a1SLionel Sambuc 
99*0a6a1f1dSLionel Sambuc 
100*0a6a1f1dSLionel Sambuc static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
101*0a6a1f1dSLionel Sambuc 
DumpConstants(const Proto * f,DumpState * D)102*0a6a1f1dSLionel Sambuc static void DumpConstants (const Proto *f, DumpState *D) {
103*0a6a1f1dSLionel Sambuc   int i;
104*0a6a1f1dSLionel Sambuc   int n = f->sizek;
10511be35a1SLionel Sambuc   DumpInt(n, D);
106*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
10711be35a1SLionel Sambuc     const TValue *o = &f->k[i];
108*0a6a1f1dSLionel Sambuc     DumpByte(ttype(o), D);
109*0a6a1f1dSLionel Sambuc     switch (ttype(o)) {
11011be35a1SLionel Sambuc     case LUA_TNIL:
11111be35a1SLionel Sambuc       break;
11211be35a1SLionel Sambuc     case LUA_TBOOLEAN:
113*0a6a1f1dSLionel Sambuc       DumpByte(bvalue(o), D);
11411be35a1SLionel Sambuc       break;
115*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
116*0a6a1f1dSLionel Sambuc     case LUA_TNUMFLT:
117*0a6a1f1dSLionel Sambuc       DumpNumber(fltvalue(o), D);
11811be35a1SLionel Sambuc       break;
119*0a6a1f1dSLionel Sambuc #endif
120*0a6a1f1dSLionel Sambuc     case LUA_TNUMINT:
121*0a6a1f1dSLionel Sambuc       DumpInteger(ivalue(o), D);
122*0a6a1f1dSLionel Sambuc       break;
123*0a6a1f1dSLionel Sambuc     case LUA_TSHRSTR:
124*0a6a1f1dSLionel Sambuc     case LUA_TLNGSTR:
125*0a6a1f1dSLionel Sambuc       DumpString(tsvalue(o), D);
12611be35a1SLionel Sambuc       break;
12711be35a1SLionel Sambuc     default:
128*0a6a1f1dSLionel Sambuc       lua_assert(0);
12911be35a1SLionel Sambuc     }
13011be35a1SLionel Sambuc   }
13111be35a1SLionel Sambuc }
13211be35a1SLionel Sambuc 
133*0a6a1f1dSLionel Sambuc 
DumpProtos(const Proto * f,DumpState * D)134*0a6a1f1dSLionel Sambuc static void DumpProtos (const Proto *f, DumpState *D) {
135*0a6a1f1dSLionel Sambuc   int i;
136*0a6a1f1dSLionel Sambuc   int n = f->sizep;
13711be35a1SLionel Sambuc   DumpInt(n, D);
13811be35a1SLionel Sambuc   for (i = 0; i < n; i++)
139*0a6a1f1dSLionel Sambuc     DumpFunction(f->p[i], f->source, D);
140*0a6a1f1dSLionel Sambuc }
141*0a6a1f1dSLionel Sambuc 
142*0a6a1f1dSLionel Sambuc 
DumpUpvalues(const Proto * f,DumpState * D)143*0a6a1f1dSLionel Sambuc static void DumpUpvalues (const Proto *f, DumpState *D) {
144*0a6a1f1dSLionel Sambuc   int i, n = f->sizeupvalues;
145*0a6a1f1dSLionel Sambuc   DumpInt(n, D);
146*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
147*0a6a1f1dSLionel Sambuc     DumpByte(f->upvalues[i].instack, D);
148*0a6a1f1dSLionel Sambuc     DumpByte(f->upvalues[i].idx, D);
149*0a6a1f1dSLionel Sambuc   }
150*0a6a1f1dSLionel Sambuc }
151*0a6a1f1dSLionel Sambuc 
152*0a6a1f1dSLionel Sambuc 
DumpDebug(const Proto * f,DumpState * D)153*0a6a1f1dSLionel Sambuc static void DumpDebug (const Proto *f, DumpState *D) {
154*0a6a1f1dSLionel Sambuc   int i, n;
155*0a6a1f1dSLionel Sambuc   n = (D->strip) ? 0 : f->sizelineinfo;
156*0a6a1f1dSLionel Sambuc   DumpInt(n, D);
157*0a6a1f1dSLionel Sambuc   DumpVector(f->lineinfo, n, D);
158*0a6a1f1dSLionel Sambuc   n = (D->strip) ? 0 : f->sizelocvars;
159*0a6a1f1dSLionel Sambuc   DumpInt(n, D);
160*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
16111be35a1SLionel Sambuc     DumpString(f->locvars[i].varname, D);
16211be35a1SLionel Sambuc     DumpInt(f->locvars[i].startpc, D);
16311be35a1SLionel Sambuc     DumpInt(f->locvars[i].endpc, D);
16411be35a1SLionel Sambuc   }
16511be35a1SLionel Sambuc   n = (D->strip) ? 0 : f->sizeupvalues;
16611be35a1SLionel Sambuc   DumpInt(n, D);
167*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++)
168*0a6a1f1dSLionel Sambuc     DumpString(f->upvalues[i].name, D);
16911be35a1SLionel Sambuc }
17011be35a1SLionel Sambuc 
171*0a6a1f1dSLionel Sambuc 
DumpFunction(const Proto * f,TString * psource,DumpState * D)172*0a6a1f1dSLionel Sambuc static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
173*0a6a1f1dSLionel Sambuc   if (D->strip || f->source == psource)
174*0a6a1f1dSLionel Sambuc     DumpString(NULL, D);  /* no debug info or same source as its parent */
175*0a6a1f1dSLionel Sambuc   else
176*0a6a1f1dSLionel Sambuc     DumpString(f->source, D);
17711be35a1SLionel Sambuc   DumpInt(f->linedefined, D);
17811be35a1SLionel Sambuc   DumpInt(f->lastlinedefined, D);
179*0a6a1f1dSLionel Sambuc   DumpByte(f->numparams, D);
180*0a6a1f1dSLionel Sambuc   DumpByte(f->is_vararg, D);
181*0a6a1f1dSLionel Sambuc   DumpByte(f->maxstacksize, D);
18211be35a1SLionel Sambuc   DumpCode(f, D);
18311be35a1SLionel Sambuc   DumpConstants(f, D);
184*0a6a1f1dSLionel Sambuc   DumpUpvalues(f, D);
185*0a6a1f1dSLionel Sambuc   DumpProtos(f, D);
18611be35a1SLionel Sambuc   DumpDebug(f, D);
18711be35a1SLionel Sambuc }
18811be35a1SLionel Sambuc 
189*0a6a1f1dSLionel Sambuc 
DumpHeader(DumpState * D)190*0a6a1f1dSLionel Sambuc static void DumpHeader (DumpState *D) {
191*0a6a1f1dSLionel Sambuc   DumpLiteral(LUA_SIGNATURE, D);
192*0a6a1f1dSLionel Sambuc   DumpByte(LUAC_VERSION, D);
193*0a6a1f1dSLionel Sambuc   DumpByte(LUAC_FORMAT, D);
194*0a6a1f1dSLionel Sambuc   DumpLiteral(LUAC_DATA, D);
195*0a6a1f1dSLionel Sambuc   DumpByte(sizeof(int), D);
196*0a6a1f1dSLionel Sambuc   DumpByte(sizeof(size_t), D);
197*0a6a1f1dSLionel Sambuc   DumpByte(sizeof(Instruction), D);
198*0a6a1f1dSLionel Sambuc   DumpByte(sizeof(lua_Integer), D);
199*0a6a1f1dSLionel Sambuc   DumpByte(sizeof(lua_Number), D);
200*0a6a1f1dSLionel Sambuc   DumpInteger(LUAC_INT, D);
201*0a6a1f1dSLionel Sambuc   DumpNumber(LUAC_NUM, D);
20211be35a1SLionel Sambuc }
20311be35a1SLionel Sambuc 
204*0a6a1f1dSLionel Sambuc 
20511be35a1SLionel Sambuc /*
20611be35a1SLionel Sambuc ** dump Lua function as precompiled chunk
20711be35a1SLionel Sambuc */
luaU_dump(lua_State * L,const Proto * f,lua_Writer w,void * data,int strip)208*0a6a1f1dSLionel Sambuc int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
209*0a6a1f1dSLionel Sambuc               int strip) {
21011be35a1SLionel Sambuc   DumpState D;
21111be35a1SLionel Sambuc   D.L = L;
21211be35a1SLionel Sambuc   D.writer = w;
21311be35a1SLionel Sambuc   D.data = data;
21411be35a1SLionel Sambuc   D.strip = strip;
21511be35a1SLionel Sambuc   D.status = 0;
21611be35a1SLionel Sambuc   DumpHeader(&D);
217*0a6a1f1dSLionel Sambuc   DumpByte(f->sizeupvalues, &D);
21811be35a1SLionel Sambuc   DumpFunction(f, NULL, &D);
21911be35a1SLionel Sambuc   return D.status;
22011be35a1SLionel Sambuc }
221*0a6a1f1dSLionel Sambuc 
222