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