3 ** save precompiled Lua chunks
4 ** See Copyright Notice in lua.h
33 ** All high-level dumps go through dumpVector; you can change it to
34 ** change the endianness of the result
36 #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0]))
38 #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char))
41 static void dumpBlock (DumpState
*D
, const void *b
, size_t size
) {
42 if (D
->status
== 0 && size
> 0) {
44 D
->status
= (*D
->writer
)(D
->L
, b
, size
, D
->data
);
50 #define dumpVar(D,x) dumpVector(D,&x,1)
53 static void dumpByte (DumpState
*D
, int y
) {
54 lu_byte x
= (lu_byte
)y
;
60 ** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
61 ** rounds up the division.)
63 #define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
65 static void dumpSize (DumpState
*D
, size_t x
) {
69 buff
[DIBS
- (++n
)] = x
& 0x7f; /* fill buffer in reverse order */
72 buff
[DIBS
- 1] |= 0x80; /* mark last byte */
73 dumpVector(D
, buff
+ DIBS
- n
, n
);
77 static void dumpInt (DumpState
*D
, int x
) {
82 static void dumpNumber (DumpState
*D
, lua_Number x
) {
87 static void dumpInteger (DumpState
*D
, lua_Integer x
) {
92 static void dumpString (DumpState
*D
, const TString
*s
) {
96 size_t size
= tsslen(s
);
97 const char *str
= getstr(s
);
98 dumpSize(D
, size
+ 1);
99 dumpVector(D
, str
, size
);
104 static void dumpCode (DumpState
*D
, const Proto
*f
) {
105 dumpInt(D
, f
->sizecode
);
106 dumpVector(D
, f
->code
, f
->sizecode
);
110 static void dumpFunction(DumpState
*D
, const Proto
*f
, TString
*psource
);
112 static void dumpConstants (DumpState
*D
, const Proto
*f
) {
116 for (i
= 0; i
< n
; i
++) {
117 const TValue
*o
= &f
->k
[i
];
118 int tt
= ttypetag(o
);
122 dumpNumber(D
, fltvalue(o
));
125 dumpInteger(D
, ivalue(o
));
129 dumpString(D
, tsvalue(o
));
132 lua_assert(tt
== LUA_VNIL
|| tt
== LUA_VFALSE
|| tt
== LUA_VTRUE
);
138 static void dumpProtos (DumpState
*D
, const Proto
*f
) {
142 for (i
= 0; i
< n
; i
++)
143 dumpFunction(D
, f
->p
[i
], f
->source
);
147 static void dumpUpvalues (DumpState
*D
, const Proto
*f
) {
148 int i
, n
= f
->sizeupvalues
;
150 for (i
= 0; i
< n
; i
++) {
151 dumpByte(D
, f
->upvalues
[i
].instack
);
152 dumpByte(D
, f
->upvalues
[i
].idx
);
153 dumpByte(D
, f
->upvalues
[i
].kind
);
158 static void dumpDebug (DumpState
*D
, const Proto
*f
) {
160 n
= (D
->strip
) ? 0 : f
->sizelineinfo
;
162 dumpVector(D
, f
->lineinfo
, n
);
163 n
= (D
->strip
) ? 0 : f
->sizeabslineinfo
;
165 for (i
= 0; i
< n
; i
++) {
166 dumpInt(D
, f
->abslineinfo
[i
].pc
);
167 dumpInt(D
, f
->abslineinfo
[i
].line
);
169 n
= (D
->strip
) ? 0 : f
->sizelocvars
;
171 for (i
= 0; i
< n
; i
++) {
172 dumpString(D
, f
->locvars
[i
].varname
);
173 dumpInt(D
, f
->locvars
[i
].startpc
);
174 dumpInt(D
, f
->locvars
[i
].endpc
);
176 n
= (D
->strip
) ? 0 : f
->sizeupvalues
;
178 for (i
= 0; i
< n
; i
++)
179 dumpString(D
, f
->upvalues
[i
].name
);
183 static void dumpFunction (DumpState
*D
, const Proto
*f
, TString
*psource
) {
184 if (D
->strip
|| f
->source
== psource
)
185 dumpString(D
, NULL
); /* no debug info or same source as its parent */
187 dumpString(D
, f
->source
);
188 dumpInt(D
, f
->linedefined
);
189 dumpInt(D
, f
->lastlinedefined
);
190 dumpByte(D
, f
->numparams
);
191 dumpByte(D
, f
->is_vararg
);
192 dumpByte(D
, f
->maxstacksize
);
201 static void dumpHeader (DumpState
*D
) {
202 dumpLiteral(D
, LUA_SIGNATURE
);
203 dumpByte(D
, LUAC_VERSION
);
204 dumpByte(D
, LUAC_FORMAT
);
205 dumpLiteral(D
, LUAC_DATA
);
206 dumpByte(D
, sizeof(Instruction
));
207 dumpByte(D
, sizeof(lua_Integer
));
208 dumpByte(D
, sizeof(lua_Number
));
209 dumpInteger(D
, LUAC_INT
);
210 dumpNumber(D
, LUAC_NUM
);
215 ** dump Lua function as precompiled chunk
217 int luaU_dump(lua_State
*L
, const Proto
*f
, lua_Writer w
, void *data
,
226 dumpByte(&D
, f
->sizeupvalues
);
227 dumpFunction(&D
, f
, NULL
);