1 /* $NetBSD: lundump.c,v 1.3 2015/02/02 14:03:05 lneto Exp $ */
4 ** Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp
5 ** load precompiled Lua chunks
6 ** See Copyright Notice in lua.h
31 #if !defined(luai_verifycode)
32 #define luai_verifycode(L,b,f) /* empty */
44 static l_noret
error(LoadState
*S
, const char *why
) {
45 luaO_pushfstring(S
->L
, "%s: %s precompiled chunk", S
->name
, why
);
46 luaD_throw(S
->L
, LUA_ERRSYNTAX
);
51 ** All high-level loads go through LoadVector; you can change it to
52 ** adapt to the endianness of the input
54 #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
56 static void LoadBlock (LoadState
*S
, void *b
, size_t size
) {
57 if (luaZ_read(S
->Z
, b
, size
) != 0)
58 error(S
, "truncated");
62 #define LoadVar(S,x) LoadVector(S,&x,1)
65 static lu_byte
LoadByte (LoadState
*S
) {
72 static int LoadInt (LoadState
*S
) {
79 static lua_Number
LoadNumber (LoadState
*S
) {
86 static lua_Integer
LoadInteger (LoadState
*S
) {
93 static TString
*LoadString (LoadState
*S
) {
94 size_t size
= LoadByte(S
);
100 char *s
= luaZ_openspace(S
->L
, S
->b
, --size
);
101 LoadVector(S
, s
, size
);
102 return luaS_newlstr(S
->L
, s
, size
);
107 static void LoadCode (LoadState
*S
, Proto
*f
) {
109 f
->code
= luaM_newvector(S
->L
, n
, Instruction
);
111 LoadVector(S
, f
->code
, n
);
115 static void LoadFunction(LoadState
*S
, Proto
*f
, TString
*psource
);
118 static void LoadConstants (LoadState
*S
, Proto
*f
) {
121 f
->k
= luaM_newvector(S
->L
, n
, TValue
);
123 for (i
= 0; i
< n
; i
++)
124 setnilvalue(&f
->k
[i
]);
125 for (i
= 0; i
< n
; i
++) {
126 TValue
*o
= &f
->k
[i
];
133 setbvalue(o
, LoadByte(S
));
137 setfltvalue(o
, LoadNumber(S
));
141 setivalue(o
, LoadInteger(S
));
145 setsvalue2n(S
->L
, o
, LoadString(S
));
154 static void LoadProtos (LoadState
*S
, Proto
*f
) {
157 f
->p
= luaM_newvector(S
->L
, n
, Proto
*);
159 for (i
= 0; i
< n
; i
++)
161 for (i
= 0; i
< n
; i
++) {
162 f
->p
[i
] = luaF_newproto(S
->L
);
163 LoadFunction(S
, f
->p
[i
], f
->source
);
168 static void LoadUpvalues (LoadState
*S
, Proto
*f
) {
171 f
->upvalues
= luaM_newvector(S
->L
, n
, Upvaldesc
);
173 for (i
= 0; i
< n
; i
++)
174 f
->upvalues
[i
].name
= NULL
;
175 for (i
= 0; i
< n
; i
++) {
176 f
->upvalues
[i
].instack
= LoadByte(S
);
177 f
->upvalues
[i
].idx
= LoadByte(S
);
182 static void LoadDebug (LoadState
*S
, Proto
*f
) {
185 f
->lineinfo
= luaM_newvector(S
->L
, n
, int);
187 LoadVector(S
, f
->lineinfo
, n
);
189 f
->locvars
= luaM_newvector(S
->L
, n
, LocVar
);
191 for (i
= 0; i
< n
; i
++)
192 f
->locvars
[i
].varname
= NULL
;
193 for (i
= 0; i
< n
; i
++) {
194 f
->locvars
[i
].varname
= LoadString(S
);
195 f
->locvars
[i
].startpc
= LoadInt(S
);
196 f
->locvars
[i
].endpc
= LoadInt(S
);
199 for (i
= 0; i
< n
; i
++)
200 f
->upvalues
[i
].name
= LoadString(S
);
204 static void LoadFunction (LoadState
*S
, Proto
*f
, TString
*psource
) {
205 f
->source
= LoadString(S
);
206 if (f
->source
== NULL
) /* no source in dump? */
207 f
->source
= psource
; /* reuse parent's source */
208 f
->linedefined
= LoadInt(S
);
209 f
->lastlinedefined
= LoadInt(S
);
210 f
->numparams
= LoadByte(S
);
211 f
->is_vararg
= LoadByte(S
);
212 f
->maxstacksize
= LoadByte(S
);
221 static void checkliteral (LoadState
*S
, const char *s
, const char *msg
) {
222 char buff
[sizeof(LUA_SIGNATURE
) + sizeof(LUAC_DATA
)]; /* larger than both */
223 size_t len
= strlen(s
);
224 LoadVector(S
, buff
, len
);
225 if (memcmp(s
, buff
, len
) != 0)
230 static void fchecksize (LoadState
*S
, size_t size
, const char *tname
) {
231 if (LoadByte(S
) != size
)
232 error(S
, luaO_pushfstring(S
->L
, "%s size mismatch in", tname
));
236 #define checksize(S,t) fchecksize(S,sizeof(t),#t)
238 static void checkHeader (LoadState
*S
) {
239 checkliteral(S
, LUA_SIGNATURE
+ 1, "not a"); /* 1st char already checked */
240 if (LoadByte(S
) != LUAC_VERSION
)
241 error(S
, "version mismatch in");
242 if (LoadByte(S
) != LUAC_FORMAT
)
243 error(S
, "format mismatch in");
244 checkliteral(S
, LUAC_DATA
, "corrupted");
246 checksize(S
, size_t);
247 checksize(S
, Instruction
);
248 checksize(S
, lua_Integer
);
249 checksize(S
, lua_Number
);
250 if (LoadInteger(S
) != LUAC_INT
)
251 error(S
, "endianness mismatch in");
252 if (LoadNumber(S
) != LUAC_NUM
)
253 error(S
, "float format mismatch in");
258 ** load precompiled chunk
260 LClosure
*luaU_undump(lua_State
*L
, ZIO
*Z
, Mbuffer
*buff
,
264 if (*name
== '@' || *name
== '=')
266 else if (*name
== LUA_SIGNATURE
[0])
267 S
.name
= "binary string";
274 cl
= luaF_newLclosure(L
, LoadByte(&S
));
275 setclLvalue(L
, L
->top
, cl
);
277 cl
->p
= luaF_newproto(L
);
278 LoadFunction(&S
, cl
->p
, NULL
);
279 lua_assert(cl
->nupvalues
== cl
->p
->sizeupvalues
);
280 luai_verifycode(L
, buff
, cl
->p
);