xref: /illumos-gate/usr/src/uts/common/fs/zfs/lua/lundump.c (revision dfc11533)
1*dfc11533SChris Williamson /*
2*dfc11533SChris Williamson ** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $
3*dfc11533SChris Williamson ** load precompiled Lua chunks
4*dfc11533SChris Williamson ** See Copyright Notice in lua.h
5*dfc11533SChris Williamson */
6*dfc11533SChris Williamson 
7*dfc11533SChris Williamson #include <sys/zfs_context.h>
8*dfc11533SChris Williamson 
9*dfc11533SChris Williamson #define lundump_c
10*dfc11533SChris Williamson #define LUA_CORE
11*dfc11533SChris Williamson 
12*dfc11533SChris Williamson #include "lua.h"
13*dfc11533SChris Williamson 
14*dfc11533SChris Williamson #include "ldebug.h"
15*dfc11533SChris Williamson #include "ldo.h"
16*dfc11533SChris Williamson #include "lfunc.h"
17*dfc11533SChris Williamson #include "lmem.h"
18*dfc11533SChris Williamson #include "lobject.h"
19*dfc11533SChris Williamson #include "lstring.h"
20*dfc11533SChris Williamson #include "lundump.h"
21*dfc11533SChris Williamson #include "lzio.h"
22*dfc11533SChris Williamson 
23*dfc11533SChris Williamson typedef struct {
24*dfc11533SChris Williamson  lua_State* L;
25*dfc11533SChris Williamson  ZIO* Z;
26*dfc11533SChris Williamson  Mbuffer* b;
27*dfc11533SChris Williamson  const char* name;
28*dfc11533SChris Williamson } LoadState;
29*dfc11533SChris Williamson 
error(LoadState * S,const char * why)30*dfc11533SChris Williamson static l_noret error(LoadState* S, const char* why)
31*dfc11533SChris Williamson {
32*dfc11533SChris Williamson  luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
33*dfc11533SChris Williamson  luaD_throw(S->L,LUA_ERRSYNTAX);
34*dfc11533SChris Williamson }
35*dfc11533SChris Williamson 
36*dfc11533SChris Williamson #define LoadMem(S,b,n,size)	LoadBlock(S,b,(n)*(size))
37*dfc11533SChris Williamson #define LoadByte(S)		(lu_byte)LoadChar(S)
38*dfc11533SChris Williamson #define LoadVar(S,x)		LoadMem(S,&x,1,sizeof(x))
39*dfc11533SChris Williamson #define LoadVector(S,b,n,size)	LoadMem(S,b,n,size)
40*dfc11533SChris Williamson 
41*dfc11533SChris Williamson #if !defined(luai_verifycode)
42*dfc11533SChris Williamson #define luai_verifycode(L,b,f)	/* empty */
43*dfc11533SChris Williamson #endif
44*dfc11533SChris Williamson 
LoadBlock(LoadState * S,void * b,size_t size)45*dfc11533SChris Williamson static void LoadBlock(LoadState* S, void* b, size_t size)
46*dfc11533SChris Williamson {
47*dfc11533SChris Williamson  if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
48*dfc11533SChris Williamson }
49*dfc11533SChris Williamson 
LoadChar(LoadState * S)50*dfc11533SChris Williamson static int LoadChar(LoadState* S)
51*dfc11533SChris Williamson {
52*dfc11533SChris Williamson  char x;
53*dfc11533SChris Williamson  LoadVar(S,x);
54*dfc11533SChris Williamson  return x;
55*dfc11533SChris Williamson }
56*dfc11533SChris Williamson 
LoadInt(LoadState * S)57*dfc11533SChris Williamson static int LoadInt(LoadState* S)
58*dfc11533SChris Williamson {
59*dfc11533SChris Williamson  int x;
60*dfc11533SChris Williamson  LoadVar(S,x);
61*dfc11533SChris Williamson  if (x<0) error(S,"corrupted");
62*dfc11533SChris Williamson  return x;
63*dfc11533SChris Williamson }
64*dfc11533SChris Williamson 
LoadNumber(LoadState * S)65*dfc11533SChris Williamson static lua_Number LoadNumber(LoadState* S)
66*dfc11533SChris Williamson {
67*dfc11533SChris Williamson  lua_Number x;
68*dfc11533SChris Williamson  LoadVar(S,x);
69*dfc11533SChris Williamson  return x;
70*dfc11533SChris Williamson }
71*dfc11533SChris Williamson 
LoadString(LoadState * S)72*dfc11533SChris Williamson static TString* LoadString(LoadState* S)
73*dfc11533SChris Williamson {
74*dfc11533SChris Williamson  size_t size;
75*dfc11533SChris Williamson  LoadVar(S,size);
76*dfc11533SChris Williamson  if (size==0)
77*dfc11533SChris Williamson   return NULL;
78*dfc11533SChris Williamson  else
79*dfc11533SChris Williamson  {
80*dfc11533SChris Williamson   char* s=luaZ_openspace(S->L,S->b,size);
81*dfc11533SChris Williamson   LoadBlock(S,s,size*sizeof(char));
82*dfc11533SChris Williamson   return luaS_newlstr(S->L,s,size-1);		/* remove trailing '\0' */
83*dfc11533SChris Williamson  }
84*dfc11533SChris Williamson }
85*dfc11533SChris Williamson 
LoadCode(LoadState * S,Proto * f)86*dfc11533SChris Williamson static void LoadCode(LoadState* S, Proto* f)
87*dfc11533SChris Williamson {
88*dfc11533SChris Williamson  int n=LoadInt(S);
89*dfc11533SChris Williamson  f->code=luaM_newvector(S->L,n,Instruction);
90*dfc11533SChris Williamson  f->sizecode=n;
91*dfc11533SChris Williamson  LoadVector(S,f->code,n,sizeof(Instruction));
92*dfc11533SChris Williamson }
93*dfc11533SChris Williamson 
94*dfc11533SChris Williamson static void LoadFunction(LoadState* S, Proto* f);
95*dfc11533SChris Williamson 
LoadConstants(LoadState * S,Proto * f)96*dfc11533SChris Williamson static void LoadConstants(LoadState* S, Proto* f)
97*dfc11533SChris Williamson {
98*dfc11533SChris Williamson  int i,n;
99*dfc11533SChris Williamson  n=LoadInt(S);
100*dfc11533SChris Williamson  f->k=luaM_newvector(S->L,n,TValue);
101*dfc11533SChris Williamson  f->sizek=n;
102*dfc11533SChris Williamson  for (i=0; i<n; i++) setnilvalue(&f->k[i]);
103*dfc11533SChris Williamson  for (i=0; i<n; i++)
104*dfc11533SChris Williamson  {
105*dfc11533SChris Williamson   TValue* o=&f->k[i];
106*dfc11533SChris Williamson   int t=LoadChar(S);
107*dfc11533SChris Williamson   switch (t)
108*dfc11533SChris Williamson   {
109*dfc11533SChris Williamson    case LUA_TNIL:
110*dfc11533SChris Williamson 	setnilvalue(o);
111*dfc11533SChris Williamson 	break;
112*dfc11533SChris Williamson    case LUA_TBOOLEAN:
113*dfc11533SChris Williamson 	setbvalue(o,LoadChar(S));
114*dfc11533SChris Williamson 	break;
115*dfc11533SChris Williamson    case LUA_TNUMBER:
116*dfc11533SChris Williamson 	setnvalue(o,LoadNumber(S));
117*dfc11533SChris Williamson 	break;
118*dfc11533SChris Williamson    case LUA_TSTRING:
119*dfc11533SChris Williamson 	setsvalue2n(S->L,o,LoadString(S));
120*dfc11533SChris Williamson 	break;
121*dfc11533SChris Williamson     default: lua_assert(0);
122*dfc11533SChris Williamson   }
123*dfc11533SChris Williamson  }
124*dfc11533SChris Williamson  n=LoadInt(S);
125*dfc11533SChris Williamson  f->p=luaM_newvector(S->L,n,Proto*);
126*dfc11533SChris Williamson  f->sizep=n;
127*dfc11533SChris Williamson  for (i=0; i<n; i++) f->p[i]=NULL;
128*dfc11533SChris Williamson  for (i=0; i<n; i++)
129*dfc11533SChris Williamson  {
130*dfc11533SChris Williamson   f->p[i]=luaF_newproto(S->L);
131*dfc11533SChris Williamson   LoadFunction(S,f->p[i]);
132*dfc11533SChris Williamson  }
133*dfc11533SChris Williamson }
134*dfc11533SChris Williamson 
LoadUpvalues(LoadState * S,Proto * f)135*dfc11533SChris Williamson static void LoadUpvalues(LoadState* S, Proto* f)
136*dfc11533SChris Williamson {
137*dfc11533SChris Williamson  int i,n;
138*dfc11533SChris Williamson  n=LoadInt(S);
139*dfc11533SChris Williamson  f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
140*dfc11533SChris Williamson  f->sizeupvalues=n;
141*dfc11533SChris Williamson  for (i=0; i<n; i++) f->upvalues[i].name=NULL;
142*dfc11533SChris Williamson  for (i=0; i<n; i++)
143*dfc11533SChris Williamson  {
144*dfc11533SChris Williamson   f->upvalues[i].instack=LoadByte(S);
145*dfc11533SChris Williamson   f->upvalues[i].idx=LoadByte(S);
146*dfc11533SChris Williamson  }
147*dfc11533SChris Williamson }
148*dfc11533SChris Williamson 
LoadDebug(LoadState * S,Proto * f)149*dfc11533SChris Williamson static void LoadDebug(LoadState* S, Proto* f)
150*dfc11533SChris Williamson {
151*dfc11533SChris Williamson  int i,n;
152*dfc11533SChris Williamson  f->source=LoadString(S);
153*dfc11533SChris Williamson  n=LoadInt(S);
154*dfc11533SChris Williamson  f->lineinfo=luaM_newvector(S->L,n,int);
155*dfc11533SChris Williamson  f->sizelineinfo=n;
156*dfc11533SChris Williamson  LoadVector(S,f->lineinfo,n,sizeof(int));
157*dfc11533SChris Williamson  n=LoadInt(S);
158*dfc11533SChris Williamson  f->locvars=luaM_newvector(S->L,n,LocVar);
159*dfc11533SChris Williamson  f->sizelocvars=n;
160*dfc11533SChris Williamson  for (i=0; i<n; i++) f->locvars[i].varname=NULL;
161*dfc11533SChris Williamson  for (i=0; i<n; i++)
162*dfc11533SChris Williamson  {
163*dfc11533SChris Williamson   f->locvars[i].varname=LoadString(S);
164*dfc11533SChris Williamson   f->locvars[i].startpc=LoadInt(S);
165*dfc11533SChris Williamson   f->locvars[i].endpc=LoadInt(S);
166*dfc11533SChris Williamson  }
167*dfc11533SChris Williamson  n=LoadInt(S);
168*dfc11533SChris Williamson  for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
169*dfc11533SChris Williamson }
170*dfc11533SChris Williamson 
LoadFunction(LoadState * S,Proto * f)171*dfc11533SChris Williamson static void LoadFunction(LoadState* S, Proto* f)
172*dfc11533SChris Williamson {
173*dfc11533SChris Williamson  f->linedefined=LoadInt(S);
174*dfc11533SChris Williamson  f->lastlinedefined=LoadInt(S);
175*dfc11533SChris Williamson  f->numparams=LoadByte(S);
176*dfc11533SChris Williamson  f->is_vararg=LoadByte(S);
177*dfc11533SChris Williamson  f->maxstacksize=LoadByte(S);
178*dfc11533SChris Williamson  LoadCode(S,f);
179*dfc11533SChris Williamson  LoadConstants(S,f);
180*dfc11533SChris Williamson  LoadUpvalues(S,f);
181*dfc11533SChris Williamson  LoadDebug(S,f);
182*dfc11533SChris Williamson }
183*dfc11533SChris Williamson 
184*dfc11533SChris Williamson /* the code below must be consistent with the code in luaU_header */
185*dfc11533SChris Williamson #define N0	LUAC_HEADERSIZE
186*dfc11533SChris Williamson #define N1	(sizeof(LUA_SIGNATURE)-sizeof(char))
187*dfc11533SChris Williamson #define N2	N1+2
188*dfc11533SChris Williamson #define N3	N2+6
189*dfc11533SChris Williamson 
LoadHeader(LoadState * S)190*dfc11533SChris Williamson static void LoadHeader(LoadState* S)
191*dfc11533SChris Williamson {
192*dfc11533SChris Williamson  lu_byte h[LUAC_HEADERSIZE];
193*dfc11533SChris Williamson  lu_byte s[LUAC_HEADERSIZE];
194*dfc11533SChris Williamson  luaU_header(h);
195*dfc11533SChris Williamson  memcpy(s,h,sizeof(char));			/* first char already read */
196*dfc11533SChris Williamson  LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char));
197*dfc11533SChris Williamson  if (memcmp(h,s,N0)==0) return;
198*dfc11533SChris Williamson  if (memcmp(h,s,N1)!=0) error(S,"not a");
199*dfc11533SChris Williamson  if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
200*dfc11533SChris Williamson  if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
201*dfc11533SChris Williamson }
202*dfc11533SChris Williamson 
203*dfc11533SChris Williamson /*
204*dfc11533SChris Williamson ** load precompiled chunk
205*dfc11533SChris Williamson */
luaU_undump(lua_State * L,ZIO * Z,Mbuffer * buff,const char * name)206*dfc11533SChris Williamson Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
207*dfc11533SChris Williamson {
208*dfc11533SChris Williamson  LoadState S;
209*dfc11533SChris Williamson  Closure* cl;
210*dfc11533SChris Williamson  if (*name=='@' || *name=='=')
211*dfc11533SChris Williamson   S.name=name+1;
212*dfc11533SChris Williamson  else if (*name==LUA_SIGNATURE[0])
213*dfc11533SChris Williamson   S.name="binary string";
214*dfc11533SChris Williamson  else
215*dfc11533SChris Williamson   S.name=name;
216*dfc11533SChris Williamson  S.L=L;
217*dfc11533SChris Williamson  S.Z=Z;
218*dfc11533SChris Williamson  S.b=buff;
219*dfc11533SChris Williamson  LoadHeader(&S);
220*dfc11533SChris Williamson  cl=luaF_newLclosure(L,1);
221*dfc11533SChris Williamson  setclLvalue(L,L->top,cl); incr_top(L);
222*dfc11533SChris Williamson  cl->l.p=luaF_newproto(L);
223*dfc11533SChris Williamson  LoadFunction(&S,cl->l.p);
224*dfc11533SChris Williamson  if (cl->l.p->sizeupvalues != 1)
225*dfc11533SChris Williamson  {
226*dfc11533SChris Williamson   Proto* p=cl->l.p;
227*dfc11533SChris Williamson   cl=luaF_newLclosure(L,cl->l.p->sizeupvalues);
228*dfc11533SChris Williamson   cl->l.p=p;
229*dfc11533SChris Williamson   setclLvalue(L,L->top-1,cl);
230*dfc11533SChris Williamson  }
231*dfc11533SChris Williamson  luai_verifycode(L,buff,cl->l.p);
232*dfc11533SChris Williamson  return cl;
233*dfc11533SChris Williamson }
234*dfc11533SChris Williamson 
235*dfc11533SChris Williamson #define MYINT(s)	(s[0]-'0')
236*dfc11533SChris Williamson #define VERSION		MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
237*dfc11533SChris Williamson #define FORMAT		0		/* this is the official format */
238*dfc11533SChris Williamson 
239*dfc11533SChris Williamson /*
240*dfc11533SChris Williamson * make header for precompiled chunks
241*dfc11533SChris Williamson * if you change the code below be sure to update LoadHeader and FORMAT above
242*dfc11533SChris Williamson * and LUAC_HEADERSIZE in lundump.h
243*dfc11533SChris Williamson */
luaU_header(lu_byte * h)244*dfc11533SChris Williamson void luaU_header (lu_byte* h)
245*dfc11533SChris Williamson {
246*dfc11533SChris Williamson  int x=1;
247*dfc11533SChris Williamson  memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));
248*dfc11533SChris Williamson  h+=sizeof(LUA_SIGNATURE)-sizeof(char);
249*dfc11533SChris Williamson  *h++=cast_byte(VERSION);
250*dfc11533SChris Williamson  *h++=cast_byte(FORMAT);
251*dfc11533SChris Williamson  *h++=cast_byte(*(char*)&x);			/* endianness */
252*dfc11533SChris Williamson  *h++=cast_byte(sizeof(int));
253*dfc11533SChris Williamson  *h++=cast_byte(sizeof(size_t));
254*dfc11533SChris Williamson  *h++=cast_byte(sizeof(Instruction));
255*dfc11533SChris Williamson  *h++=cast_byte(sizeof(lua_Number));
256*dfc11533SChris Williamson  *h++=cast_byte(((lua_Number)0.5)==0);		/* is lua_Number integral? */
257*dfc11533SChris Williamson  memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));
258*dfc11533SChris Williamson }
259