xref: /minix3/external/mit/lua/dist/src/lundump.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: lundump.c,v 1.3 2015/02/02 14:03:05 lneto Exp $	*/
211be35a1SLionel Sambuc 
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp
511be35a1SLionel Sambuc ** load precompiled Lua chunks
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc 
911be35a1SLionel Sambuc #define lundump_c
1011be35a1SLionel Sambuc #define LUA_CORE
1111be35a1SLionel Sambuc 
12*0a6a1f1dSLionel Sambuc #include "lprefix.h"
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
16*0a6a1f1dSLionel Sambuc #include <string.h>
17*0a6a1f1dSLionel Sambuc #endif
18*0a6a1f1dSLionel Sambuc 
1911be35a1SLionel Sambuc #include "lua.h"
2011be35a1SLionel Sambuc 
2111be35a1SLionel Sambuc #include "ldebug.h"
2211be35a1SLionel Sambuc #include "ldo.h"
2311be35a1SLionel Sambuc #include "lfunc.h"
2411be35a1SLionel Sambuc #include "lmem.h"
2511be35a1SLionel Sambuc #include "lobject.h"
2611be35a1SLionel Sambuc #include "lstring.h"
2711be35a1SLionel Sambuc #include "lundump.h"
2811be35a1SLionel Sambuc #include "lzio.h"
2911be35a1SLionel Sambuc 
30*0a6a1f1dSLionel Sambuc 
31*0a6a1f1dSLionel Sambuc #if !defined(luai_verifycode)
32*0a6a1f1dSLionel Sambuc #define luai_verifycode(L,b,f)  /* empty */
33*0a6a1f1dSLionel Sambuc #endif
34*0a6a1f1dSLionel Sambuc 
35*0a6a1f1dSLionel Sambuc 
3611be35a1SLionel Sambuc typedef struct {
3711be35a1SLionel Sambuc   lua_State *L;
3811be35a1SLionel Sambuc   ZIO *Z;
3911be35a1SLionel Sambuc   Mbuffer *b;
4011be35a1SLionel Sambuc   const char *name;
4111be35a1SLionel Sambuc } LoadState;
4211be35a1SLionel Sambuc 
4311be35a1SLionel Sambuc 
error(LoadState * S,const char * why)44*0a6a1f1dSLionel Sambuc static l_noret error(LoadState *S, const char *why) {
45*0a6a1f1dSLionel Sambuc   luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
4611be35a1SLionel Sambuc   luaD_throw(S->L, LUA_ERRSYNTAX);
4711be35a1SLionel Sambuc }
4811be35a1SLionel Sambuc 
4911be35a1SLionel Sambuc 
50*0a6a1f1dSLionel Sambuc /*
51*0a6a1f1dSLionel Sambuc ** All high-level loads go through LoadVector; you can change it to
52*0a6a1f1dSLionel Sambuc ** adapt to the endianness of the input
53*0a6a1f1dSLionel Sambuc */
54*0a6a1f1dSLionel Sambuc #define LoadVector(S,b,n)	LoadBlock(S,b,(n)*sizeof((b)[0]))
55*0a6a1f1dSLionel Sambuc 
LoadBlock(LoadState * S,void * b,size_t size)56*0a6a1f1dSLionel Sambuc static void LoadBlock (LoadState *S, void *b, size_t size) {
57*0a6a1f1dSLionel Sambuc   if (luaZ_read(S->Z, b, size) != 0)
58*0a6a1f1dSLionel Sambuc     error(S, "truncated");
5911be35a1SLionel Sambuc }
6011be35a1SLionel Sambuc 
61*0a6a1f1dSLionel Sambuc 
62*0a6a1f1dSLionel Sambuc #define LoadVar(S,x)		LoadVector(S,&x,1)
63*0a6a1f1dSLionel Sambuc 
64*0a6a1f1dSLionel Sambuc 
LoadByte(LoadState * S)65*0a6a1f1dSLionel Sambuc static lu_byte LoadByte (LoadState *S) {
66*0a6a1f1dSLionel Sambuc   lu_byte x;
6711be35a1SLionel Sambuc   LoadVar(S, x);
6811be35a1SLionel Sambuc   return x;
6911be35a1SLionel Sambuc }
7011be35a1SLionel Sambuc 
71*0a6a1f1dSLionel Sambuc 
LoadInt(LoadState * S)72*0a6a1f1dSLionel Sambuc static int LoadInt (LoadState *S) {
7311be35a1SLionel Sambuc   int x;
7411be35a1SLionel Sambuc   LoadVar(S, x);
7511be35a1SLionel Sambuc   return x;
7611be35a1SLionel Sambuc }
7711be35a1SLionel Sambuc 
78*0a6a1f1dSLionel Sambuc 
LoadNumber(LoadState * S)79*0a6a1f1dSLionel Sambuc static lua_Number LoadNumber (LoadState *S) {
8011be35a1SLionel Sambuc   lua_Number x;
8111be35a1SLionel Sambuc   LoadVar(S, x);
8211be35a1SLionel Sambuc   return x;
8311be35a1SLionel Sambuc }
8411be35a1SLionel Sambuc 
85*0a6a1f1dSLionel Sambuc 
LoadInteger(LoadState * S)86*0a6a1f1dSLionel Sambuc static lua_Integer LoadInteger (LoadState *S) {
87*0a6a1f1dSLionel Sambuc   lua_Integer x;
88*0a6a1f1dSLionel Sambuc   LoadVar(S, x);
89*0a6a1f1dSLionel Sambuc   return x;
90*0a6a1f1dSLionel Sambuc }
91*0a6a1f1dSLionel Sambuc 
92*0a6a1f1dSLionel Sambuc 
LoadString(LoadState * S)93*0a6a1f1dSLionel Sambuc static TString *LoadString (LoadState *S) {
94*0a6a1f1dSLionel Sambuc   size_t size = LoadByte(S);
95*0a6a1f1dSLionel Sambuc   if (size == 0xFF)
9611be35a1SLionel Sambuc     LoadVar(S, size);
9711be35a1SLionel Sambuc   if (size == 0)
9811be35a1SLionel Sambuc     return NULL;
99*0a6a1f1dSLionel Sambuc   else {
100*0a6a1f1dSLionel Sambuc     char *s = luaZ_openspace(S->L, S->b, --size);
101*0a6a1f1dSLionel Sambuc     LoadVector(S, s, size);
102*0a6a1f1dSLionel Sambuc     return luaS_newlstr(S->L, s, size);
10311be35a1SLionel Sambuc   }
10411be35a1SLionel Sambuc }
10511be35a1SLionel Sambuc 
106*0a6a1f1dSLionel Sambuc 
LoadCode(LoadState * S,Proto * f)107*0a6a1f1dSLionel Sambuc static void LoadCode (LoadState *S, Proto *f) {
10811be35a1SLionel Sambuc   int n = LoadInt(S);
10911be35a1SLionel Sambuc   f->code = luaM_newvector(S->L, n, Instruction);
11011be35a1SLionel Sambuc   f->sizecode = n;
111*0a6a1f1dSLionel Sambuc   LoadVector(S, f->code, n);
11211be35a1SLionel Sambuc }
11311be35a1SLionel Sambuc 
11411be35a1SLionel Sambuc 
115*0a6a1f1dSLionel Sambuc static void LoadFunction(LoadState *S, Proto *f, TString *psource);
116*0a6a1f1dSLionel Sambuc 
117*0a6a1f1dSLionel Sambuc 
LoadConstants(LoadState * S,Proto * f)118*0a6a1f1dSLionel Sambuc static void LoadConstants (LoadState *S, Proto *f) {
119*0a6a1f1dSLionel Sambuc   int i;
120*0a6a1f1dSLionel Sambuc   int n = LoadInt(S);
12111be35a1SLionel Sambuc   f->k = luaM_newvector(S->L, n, TValue);
12211be35a1SLionel Sambuc   f->sizek = n;
12311be35a1SLionel Sambuc   for (i = 0; i < n; i++)
124*0a6a1f1dSLionel Sambuc     setnilvalue(&f->k[i]);
125*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
12611be35a1SLionel Sambuc     TValue *o = &f->k[i];
127*0a6a1f1dSLionel Sambuc     int t = LoadByte(S);
128*0a6a1f1dSLionel Sambuc     switch (t) {
12911be35a1SLionel Sambuc     case LUA_TNIL:
13011be35a1SLionel Sambuc       setnilvalue(o);
13111be35a1SLionel Sambuc       break;
13211be35a1SLionel Sambuc     case LUA_TBOOLEAN:
133*0a6a1f1dSLionel Sambuc       setbvalue(o, LoadByte(S));
13411be35a1SLionel Sambuc       break;
135*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
136*0a6a1f1dSLionel Sambuc     case LUA_TNUMFLT:
137*0a6a1f1dSLionel Sambuc       setfltvalue(o, LoadNumber(S));
13811be35a1SLionel Sambuc       break;
139*0a6a1f1dSLionel Sambuc #endif
140*0a6a1f1dSLionel Sambuc     case LUA_TNUMINT:
141*0a6a1f1dSLionel Sambuc       setivalue(o, LoadInteger(S));
142*0a6a1f1dSLionel Sambuc       break;
143*0a6a1f1dSLionel Sambuc     case LUA_TSHRSTR:
144*0a6a1f1dSLionel Sambuc     case LUA_TLNGSTR:
14511be35a1SLionel Sambuc       setsvalue2n(S->L, o, LoadString(S));
14611be35a1SLionel Sambuc       break;
14711be35a1SLionel Sambuc     default:
148*0a6a1f1dSLionel Sambuc       lua_assert(0);
14911be35a1SLionel Sambuc     }
15011be35a1SLionel Sambuc   }
15111be35a1SLionel Sambuc }
15211be35a1SLionel Sambuc 
153*0a6a1f1dSLionel Sambuc 
LoadProtos(LoadState * S,Proto * f)154*0a6a1f1dSLionel Sambuc static void LoadProtos (LoadState *S, Proto *f) {
155*0a6a1f1dSLionel Sambuc   int i;
156*0a6a1f1dSLionel Sambuc   int n = LoadInt(S);
157*0a6a1f1dSLionel Sambuc   f->p = luaM_newvector(S->L, n, Proto *);
158*0a6a1f1dSLionel Sambuc   f->sizep = n;
159*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++)
160*0a6a1f1dSLionel Sambuc     f->p[i] = NULL;
161*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
162*0a6a1f1dSLionel Sambuc     f->p[i] = luaF_newproto(S->L);
163*0a6a1f1dSLionel Sambuc     LoadFunction(S, f->p[i], f->source);
164*0a6a1f1dSLionel Sambuc   }
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc 
167*0a6a1f1dSLionel Sambuc 
LoadUpvalues(LoadState * S,Proto * f)168*0a6a1f1dSLionel Sambuc static void LoadUpvalues (LoadState *S, Proto *f) {
169*0a6a1f1dSLionel Sambuc   int i, n;
170*0a6a1f1dSLionel Sambuc   n = LoadInt(S);
171*0a6a1f1dSLionel Sambuc   f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
172*0a6a1f1dSLionel Sambuc   f->sizeupvalues = n;
173*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++)
174*0a6a1f1dSLionel Sambuc     f->upvalues[i].name = NULL;
175*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
176*0a6a1f1dSLionel Sambuc     f->upvalues[i].instack = LoadByte(S);
177*0a6a1f1dSLionel Sambuc     f->upvalues[i].idx = LoadByte(S);
178*0a6a1f1dSLionel Sambuc   }
179*0a6a1f1dSLionel Sambuc }
180*0a6a1f1dSLionel Sambuc 
181*0a6a1f1dSLionel Sambuc 
LoadDebug(LoadState * S,Proto * f)182*0a6a1f1dSLionel Sambuc static void LoadDebug (LoadState *S, Proto *f) {
18311be35a1SLionel Sambuc   int i, n;
18411be35a1SLionel Sambuc   n = LoadInt(S);
18511be35a1SLionel Sambuc   f->lineinfo = luaM_newvector(S->L, n, int);
18611be35a1SLionel Sambuc   f->sizelineinfo = n;
187*0a6a1f1dSLionel Sambuc   LoadVector(S, f->lineinfo, n);
18811be35a1SLionel Sambuc   n = LoadInt(S);
18911be35a1SLionel Sambuc   f->locvars = luaM_newvector(S->L, n, LocVar);
19011be35a1SLionel Sambuc   f->sizelocvars = n;
19111be35a1SLionel Sambuc   for (i = 0; i < n; i++)
192*0a6a1f1dSLionel Sambuc     f->locvars[i].varname = NULL;
193*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++) {
19411be35a1SLionel Sambuc     f->locvars[i].varname = LoadString(S);
19511be35a1SLionel Sambuc     f->locvars[i].startpc = LoadInt(S);
19611be35a1SLionel Sambuc     f->locvars[i].endpc = LoadInt(S);
19711be35a1SLionel Sambuc   }
19811be35a1SLionel Sambuc   n = LoadInt(S);
199*0a6a1f1dSLionel Sambuc   for (i = 0; i < n; i++)
200*0a6a1f1dSLionel Sambuc     f->upvalues[i].name = LoadString(S);
20111be35a1SLionel Sambuc }
20211be35a1SLionel Sambuc 
203*0a6a1f1dSLionel Sambuc 
LoadFunction(LoadState * S,Proto * f,TString * psource)204*0a6a1f1dSLionel Sambuc static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
205*0a6a1f1dSLionel Sambuc   f->source = LoadString(S);
206*0a6a1f1dSLionel Sambuc   if (f->source == NULL)  /* no source in dump? */
207*0a6a1f1dSLionel Sambuc     f->source = psource;  /* reuse parent's source */
20811be35a1SLionel Sambuc   f->linedefined = LoadInt(S);
20911be35a1SLionel Sambuc   f->lastlinedefined = LoadInt(S);
21011be35a1SLionel Sambuc   f->numparams = LoadByte(S);
21111be35a1SLionel Sambuc   f->is_vararg = LoadByte(S);
21211be35a1SLionel Sambuc   f->maxstacksize = LoadByte(S);
21311be35a1SLionel Sambuc   LoadCode(S, f);
21411be35a1SLionel Sambuc   LoadConstants(S, f);
215*0a6a1f1dSLionel Sambuc   LoadUpvalues(S, f);
216*0a6a1f1dSLionel Sambuc   LoadProtos(S, f);
21711be35a1SLionel Sambuc   LoadDebug(S, f);
21811be35a1SLionel Sambuc }
21911be35a1SLionel Sambuc 
220*0a6a1f1dSLionel Sambuc 
checkliteral(LoadState * S,const char * s,const char * msg)221*0a6a1f1dSLionel Sambuc static void checkliteral (LoadState *S, const char *s, const char *msg) {
222*0a6a1f1dSLionel Sambuc   char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
223*0a6a1f1dSLionel Sambuc   size_t len = strlen(s);
224*0a6a1f1dSLionel Sambuc   LoadVector(S, buff, len);
225*0a6a1f1dSLionel Sambuc   if (memcmp(s, buff, len) != 0)
226*0a6a1f1dSLionel Sambuc     error(S, msg);
22711be35a1SLionel Sambuc }
22811be35a1SLionel Sambuc 
229*0a6a1f1dSLionel Sambuc 
fchecksize(LoadState * S,size_t size,const char * tname)230*0a6a1f1dSLionel Sambuc static void fchecksize (LoadState *S, size_t size, const char *tname) {
231*0a6a1f1dSLionel Sambuc   if (LoadByte(S) != size)
232*0a6a1f1dSLionel Sambuc     error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
233*0a6a1f1dSLionel Sambuc }
234*0a6a1f1dSLionel Sambuc 
235*0a6a1f1dSLionel Sambuc 
236*0a6a1f1dSLionel Sambuc #define checksize(S,t)	fchecksize(S,sizeof(t),#t)
237*0a6a1f1dSLionel Sambuc 
checkHeader(LoadState * S)238*0a6a1f1dSLionel Sambuc static void checkHeader (LoadState *S) {
239*0a6a1f1dSLionel Sambuc   checkliteral(S, LUA_SIGNATURE + 1, "not a");  /* 1st char already checked */
240*0a6a1f1dSLionel Sambuc   if (LoadByte(S) != LUAC_VERSION)
241*0a6a1f1dSLionel Sambuc     error(S, "version mismatch in");
242*0a6a1f1dSLionel Sambuc   if (LoadByte(S) != LUAC_FORMAT)
243*0a6a1f1dSLionel Sambuc     error(S, "format mismatch in");
244*0a6a1f1dSLionel Sambuc   checkliteral(S, LUAC_DATA, "corrupted");
245*0a6a1f1dSLionel Sambuc   checksize(S, int);
246*0a6a1f1dSLionel Sambuc   checksize(S, size_t);
247*0a6a1f1dSLionel Sambuc   checksize(S, Instruction);
248*0a6a1f1dSLionel Sambuc   checksize(S, lua_Integer);
249*0a6a1f1dSLionel Sambuc   checksize(S, lua_Number);
250*0a6a1f1dSLionel Sambuc   if (LoadInteger(S) != LUAC_INT)
251*0a6a1f1dSLionel Sambuc     error(S, "endianness mismatch in");
252*0a6a1f1dSLionel Sambuc   if (LoadNumber(S) != LUAC_NUM)
253*0a6a1f1dSLionel Sambuc     error(S, "float format mismatch in");
254*0a6a1f1dSLionel Sambuc }
255*0a6a1f1dSLionel Sambuc 
256*0a6a1f1dSLionel Sambuc 
25711be35a1SLionel Sambuc /*
25811be35a1SLionel Sambuc ** load precompiled chunk
25911be35a1SLionel Sambuc */
luaU_undump(lua_State * L,ZIO * Z,Mbuffer * buff,const char * name)260*0a6a1f1dSLionel Sambuc LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
261*0a6a1f1dSLionel Sambuc                       const char *name) {
26211be35a1SLionel Sambuc   LoadState S;
263*0a6a1f1dSLionel Sambuc   LClosure *cl;
26411be35a1SLionel Sambuc   if (*name == '@' || *name == '=')
26511be35a1SLionel Sambuc     S.name = name + 1;
26611be35a1SLionel Sambuc   else if (*name == LUA_SIGNATURE[0])
26711be35a1SLionel Sambuc     S.name = "binary string";
26811be35a1SLionel Sambuc   else
26911be35a1SLionel Sambuc     S.name = name;
27011be35a1SLionel Sambuc   S.L = L;
27111be35a1SLionel Sambuc   S.Z = Z;
27211be35a1SLionel Sambuc   S.b = buff;
273*0a6a1f1dSLionel Sambuc   checkHeader(&S);
274*0a6a1f1dSLionel Sambuc   cl = luaF_newLclosure(L, LoadByte(&S));
275*0a6a1f1dSLionel Sambuc   setclLvalue(L, L->top, cl);
276*0a6a1f1dSLionel Sambuc   incr_top(L);
277*0a6a1f1dSLionel Sambuc   cl->p = luaF_newproto(L);
278*0a6a1f1dSLionel Sambuc   LoadFunction(&S, cl->p, NULL);
279*0a6a1f1dSLionel Sambuc   lua_assert(cl->nupvalues == cl->p->sizeupvalues);
280*0a6a1f1dSLionel Sambuc   luai_verifycode(L, buff, cl->p);
281*0a6a1f1dSLionel Sambuc   return cl;
28211be35a1SLionel Sambuc }
28311be35a1SLionel Sambuc 
284