3 ** load precompiled Lua chunks
4 ** See Copyright Notice in lua.h
28 #if !defined(luai_verifycode)
29 #define luai_verifycode(L,f) /* empty */
40 static l_noret
error (LoadState
*S
, const char *why
) {
41 luaO_pushfstring(S
->L
, "%s: bad binary format (%s)", S
->name
, why
);
42 luaD_throw(S
->L
, LUA_ERRSYNTAX
);
47 ** All high-level loads go through loadVector; you can change it to
48 ** adapt to the endianness of the input
50 #define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0]))
52 static void loadBlock (LoadState
*S
, void *b
, size_t size
) {
53 if (luaZ_read(S
->Z
, b
, size
) != 0)
54 error(S
, "truncated chunk");
58 #define loadVar(S,x) loadVector(S,&x,1)
61 static lu_byte
loadByte (LoadState
*S
) {
64 error(S
, "truncated chunk");
69 static size_t loadUnsigned (LoadState
*S
, size_t limit
) {
76 error(S
, "integer overflow");
77 x
= (x
<< 7) | (b
& 0x7f);
78 } while ((b
& 0x80) == 0);
83 static size_t loadSize (LoadState
*S
) {
84 return loadUnsigned(S
, ~(size_t)0);
88 static int loadInt (LoadState
*S
) {
89 return cast_int(loadUnsigned(S
, INT_MAX
));
93 static lua_Number
loadNumber (LoadState
*S
) {
100 static lua_Integer
loadInteger (LoadState
*S
) {
108 ** Load a nullable string into prototype 'p'.
110 static TString
*loadStringN (LoadState
*S
, Proto
*p
) {
113 size_t size
= loadSize(S
);
114 if (size
== 0) /* no string? */
116 else if (--size
<= LUAI_MAXSHORTLEN
) { /* short string? */
117 char buff
[LUAI_MAXSHORTLEN
];
118 loadVector(S
, buff
, size
); /* load string into buffer */
119 ts
= luaS_newlstr(L
, buff
, size
); /* create string */
121 else { /* long string */
122 ts
= luaS_createlngstrobj(L
, size
); /* create string */
123 setsvalue2s(L
, L
->top
.p
, ts
); /* anchor it ('loadVector' can GC) */
125 loadVector(S
, getstr(ts
), size
); /* load directly in final place */
126 L
->top
.p
--; /* pop string */
128 luaC_objbarrier(L
, p
, ts
);
134 ** Load a non-nullable string into prototype 'p'.
136 static TString
*loadString (LoadState
*S
, Proto
*p
) {
137 TString
*st
= loadStringN(S
, p
);
139 error(S
, "bad format for constant string");
144 static void loadCode (LoadState
*S
, Proto
*f
) {
146 f
->code
= luaM_newvectorchecked(S
->L
, n
, Instruction
);
148 loadVector(S
, f
->code
, n
);
152 static void loadFunction(LoadState
*S
, Proto
*f
, TString
*psource
);
155 static void loadConstants (LoadState
*S
, Proto
*f
) {
158 f
->k
= luaM_newvectorchecked(S
->L
, n
, TValue
);
160 for (i
= 0; i
< n
; i
++)
161 setnilvalue(&f
->k
[i
]);
162 for (i
= 0; i
< n
; i
++) {
163 TValue
*o
= &f
->k
[i
];
176 setfltvalue(o
, loadNumber(S
));
179 setivalue(o
, loadInteger(S
));
183 setsvalue2n(S
->L
, o
, loadString(S
, f
));
185 default: lua_assert(0);
191 static void loadProtos (LoadState
*S
, Proto
*f
) {
194 f
->p
= luaM_newvectorchecked(S
->L
, n
, Proto
*);
196 for (i
= 0; i
< n
; i
++)
198 for (i
= 0; i
< n
; i
++) {
199 f
->p
[i
] = luaF_newproto(S
->L
);
200 luaC_objbarrier(S
->L
, f
, f
->p
[i
]);
201 loadFunction(S
, f
->p
[i
], f
->source
);
207 ** Load the upvalues for a function. The names must be filled first,
208 ** because the filling of the other fields can raise read errors and
209 ** the creation of the error message can call an emergency collection;
210 ** in that case all prototypes must be consistent for the GC.
212 static void loadUpvalues (LoadState
*S
, Proto
*f
) {
215 f
->upvalues
= luaM_newvectorchecked(S
->L
, n
, Upvaldesc
);
217 for (i
= 0; i
< n
; i
++) /* make array valid for GC */
218 f
->upvalues
[i
].name
= NULL
;
219 for (i
= 0; i
< n
; i
++) { /* following calls can raise errors */
220 f
->upvalues
[i
].instack
= loadByte(S
);
221 f
->upvalues
[i
].idx
= loadByte(S
);
222 f
->upvalues
[i
].kind
= loadByte(S
);
227 static void loadDebug (LoadState
*S
, Proto
*f
) {
230 f
->lineinfo
= luaM_newvectorchecked(S
->L
, n
, ls_byte
);
232 loadVector(S
, f
->lineinfo
, n
);
234 f
->abslineinfo
= luaM_newvectorchecked(S
->L
, n
, AbsLineInfo
);
235 f
->sizeabslineinfo
= n
;
236 for (i
= 0; i
< n
; i
++) {
237 f
->abslineinfo
[i
].pc
= loadInt(S
);
238 f
->abslineinfo
[i
].line
= loadInt(S
);
241 f
->locvars
= luaM_newvectorchecked(S
->L
, n
, LocVar
);
243 for (i
= 0; i
< n
; i
++)
244 f
->locvars
[i
].varname
= NULL
;
245 for (i
= 0; i
< n
; i
++) {
246 f
->locvars
[i
].varname
= loadStringN(S
, f
);
247 f
->locvars
[i
].startpc
= loadInt(S
);
248 f
->locvars
[i
].endpc
= loadInt(S
);
251 if (n
!= 0) /* does it have debug information? */
252 n
= f
->sizeupvalues
; /* must be this many */
253 for (i
= 0; i
< n
; i
++)
254 f
->upvalues
[i
].name
= loadStringN(S
, f
);
258 static void loadFunction (LoadState
*S
, Proto
*f
, TString
*psource
) {
259 f
->source
= loadStringN(S
, f
);
260 if (f
->source
== NULL
) /* no source in dump? */
261 f
->source
= psource
; /* reuse parent's source */
262 f
->linedefined
= loadInt(S
);
263 f
->lastlinedefined
= loadInt(S
);
264 f
->numparams
= loadByte(S
);
265 f
->is_vararg
= loadByte(S
);
266 f
->maxstacksize
= loadByte(S
);
275 static void checkliteral (LoadState
*S
, const char *s
, const char *msg
) {
276 char buff
[sizeof(LUA_SIGNATURE
) + sizeof(LUAC_DATA
)]; /* larger than both */
277 size_t len
= strlen(s
);
278 loadVector(S
, buff
, len
);
279 if (memcmp(s
, buff
, len
) != 0)
284 static void fchecksize (LoadState
*S
, size_t size
, const char *tname
) {
285 if (loadByte(S
) != size
)
286 error(S
, luaO_pushfstring(S
->L
, "%s size mismatch", tname
));
290 #define checksize(S,t) fchecksize(S,sizeof(t),#t)
292 static void checkHeader (LoadState
*S
) {
293 /* skip 1st char (already read and checked) */
294 checkliteral(S
, &LUA_SIGNATURE
[1], "not a binary chunk");
295 if (loadByte(S
) != LUAC_VERSION
)
296 error(S
, "version mismatch");
297 if (loadByte(S
) != LUAC_FORMAT
)
298 error(S
, "format mismatch");
299 checkliteral(S
, LUAC_DATA
, "corrupted chunk");
300 checksize(S
, Instruction
);
301 checksize(S
, lua_Integer
);
302 checksize(S
, lua_Number
);
303 if (loadInteger(S
) != LUAC_INT
)
304 error(S
, "integer format mismatch");
305 if (loadNumber(S
) != LUAC_NUM
)
306 error(S
, "float format mismatch");
311 ** Load precompiled chunk.
313 LClosure
*luaU_undump(lua_State
*L
, ZIO
*Z
, const char *name
) {
316 if (*name
== '@' || *name
== '=')
318 else if (*name
== LUA_SIGNATURE
[0])
319 S
.name
= "binary string";
325 cl
= luaF_newLclosure(L
, loadByte(&S
));
326 setclLvalue2s(L
, L
->top
.p
, cl
);
328 cl
->p
= luaF_newproto(L
);
329 luaC_objbarrier(L
, cl
, cl
->p
);
330 loadFunction(&S
, cl
->p
, NULL
);
331 lua_assert(cl
->nupvalues
== cl
->p
->sizeupvalues
);
332 luai_verifycode(L
, cl
->p
);