Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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