Remove building with NOCRYPTO option
[minix.git] / external / mit / lua / dist / src / lundump.c
bloba20f1d38940cca28857b8e4b95efedc635abafce
1 /* $NetBSD: lundump.c,v 1.3 2015/02/02 14:03:05 lneto Exp $ */
3 /*
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
7 */
9 #define lundump_c
10 #define LUA_CORE
12 #include "lprefix.h"
15 #ifndef _KERNEL
16 #include <string.h>
17 #endif
19 #include "lua.h"
21 #include "ldebug.h"
22 #include "ldo.h"
23 #include "lfunc.h"
24 #include "lmem.h"
25 #include "lobject.h"
26 #include "lstring.h"
27 #include "lundump.h"
28 #include "lzio.h"
31 #if !defined(luai_verifycode)
32 #define luai_verifycode(L,b,f) /* empty */
33 #endif
36 typedef struct {
37 lua_State *L;
38 ZIO *Z;
39 Mbuffer *b;
40 const char *name;
41 } LoadState;
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) {
66 lu_byte x;
67 LoadVar(S, x);
68 return x;
72 static int LoadInt (LoadState *S) {
73 int x;
74 LoadVar(S, x);
75 return x;
79 static lua_Number LoadNumber (LoadState *S) {
80 lua_Number x;
81 LoadVar(S, x);
82 return x;
86 static lua_Integer LoadInteger (LoadState *S) {
87 lua_Integer x;
88 LoadVar(S, x);
89 return x;
93 static TString *LoadString (LoadState *S) {
94 size_t size = LoadByte(S);
95 if (size == 0xFF)
96 LoadVar(S, size);
97 if (size == 0)
98 return NULL;
99 else {
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) {
108 int n = LoadInt(S);
109 f->code = luaM_newvector(S->L, n, Instruction);
110 f->sizecode = n;
111 LoadVector(S, f->code, n);
115 static void LoadFunction(LoadState *S, Proto *f, TString *psource);
118 static void LoadConstants (LoadState *S, Proto *f) {
119 int i;
120 int n = LoadInt(S);
121 f->k = luaM_newvector(S->L, n, TValue);
122 f->sizek = n;
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];
127 int t = LoadByte(S);
128 switch (t) {
129 case LUA_TNIL:
130 setnilvalue(o);
131 break;
132 case LUA_TBOOLEAN:
133 setbvalue(o, LoadByte(S));
134 break;
135 #ifndef _KERNEL
136 case LUA_TNUMFLT:
137 setfltvalue(o, LoadNumber(S));
138 break;
139 #endif
140 case LUA_TNUMINT:
141 setivalue(o, LoadInteger(S));
142 break;
143 case LUA_TSHRSTR:
144 case LUA_TLNGSTR:
145 setsvalue2n(S->L, o, LoadString(S));
146 break;
147 default:
148 lua_assert(0);
154 static void LoadProtos (LoadState *S, Proto *f) {
155 int i;
156 int n = LoadInt(S);
157 f->p = luaM_newvector(S->L, n, Proto *);
158 f->sizep = n;
159 for (i = 0; i < n; i++)
160 f->p[i] = NULL;
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) {
169 int i, n;
170 n = LoadInt(S);
171 f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
172 f->sizeupvalues = n;
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) {
183 int i, n;
184 n = LoadInt(S);
185 f->lineinfo = luaM_newvector(S->L, n, int);
186 f->sizelineinfo = n;
187 LoadVector(S, f->lineinfo, n);
188 n = LoadInt(S);
189 f->locvars = luaM_newvector(S->L, n, LocVar);
190 f->sizelocvars = n;
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);
198 n = 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);
213 LoadCode(S, f);
214 LoadConstants(S, f);
215 LoadUpvalues(S, f);
216 LoadProtos(S, f);
217 LoadDebug(S, f);
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)
226 error(S, msg);
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");
245 checksize(S, int);
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,
261 const char *name) {
262 LoadState S;
263 LClosure *cl;
264 if (*name == '@' || *name == '=')
265 S.name = name + 1;
266 else if (*name == LUA_SIGNATURE[0])
267 S.name = "binary string";
268 else
269 S.name = name;
270 S.L = L;
271 S.Z = Z;
272 S.b = buff;
273 checkHeader(&S);
274 cl = luaF_newLclosure(L, LoadByte(&S));
275 setclLvalue(L, L->top, cl);
276 incr_top(L);
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);
281 return cl;