]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/lua-5.3.1/src/lundump.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / civetweb / src / third_party / lua-5.3.1 / src / lundump.c
1 /*
2 ** $Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp $
3 ** load precompiled Lua chunks
4 ** See Copyright Notice in lua.h
5 */
6
7 #define lundump_c
8 #define LUA_CORE
9
10 #include "lprefix.h"
11
12
13 #include <string.h>
14
15 #include "lua.h"
16
17 #include "ldebug.h"
18 #include "ldo.h"
19 #include "lfunc.h"
20 #include "lmem.h"
21 #include "lobject.h"
22 #include "lstring.h"
23 #include "lundump.h"
24 #include "lzio.h"
25
26
27 #if !defined(luai_verifycode)
28 #define luai_verifycode(L,b,f) /* empty */
29 #endif
30
31
32 typedef struct {
33 lua_State *L;
34 ZIO *Z;
35 Mbuffer *b;
36 const char *name;
37 } LoadState;
38
39
40 static l_noret error(LoadState *S, const char *why) {
41 luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
42 luaD_throw(S->L, LUA_ERRSYNTAX);
43 }
44
45
46 /*
47 ** All high-level loads go through LoadVector; you can change it to
48 ** adapt to the endianness of the input
49 */
50 #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
51
52 static void LoadBlock (LoadState *S, void *b, size_t size) {
53 if (luaZ_read(S->Z, b, size) != 0)
54 error(S, "truncated");
55 }
56
57
58 #define LoadVar(S,x) LoadVector(S,&x,1)
59
60
61 static lu_byte LoadByte (LoadState *S) {
62 lu_byte x;
63 LoadVar(S, x);
64 return x;
65 }
66
67
68 static int LoadInt (LoadState *S) {
69 int x;
70 LoadVar(S, x);
71 return x;
72 }
73
74
75 static lua_Number LoadNumber (LoadState *S) {
76 lua_Number x;
77 LoadVar(S, x);
78 return x;
79 }
80
81
82 static lua_Integer LoadInteger (LoadState *S) {
83 lua_Integer x;
84 LoadVar(S, x);
85 return x;
86 }
87
88
89 static TString *LoadString (LoadState *S) {
90 size_t size = LoadByte(S);
91 if (size == 0xFF)
92 LoadVar(S, size);
93 if (size == 0)
94 return NULL;
95 else {
96 char *s = luaZ_openspace(S->L, S->b, --size);
97 LoadVector(S, s, size);
98 return luaS_newlstr(S->L, s, size);
99 }
100 }
101
102
103 static void LoadCode (LoadState *S, Proto *f) {
104 int n = LoadInt(S);
105 f->code = luaM_newvector(S->L, n, Instruction);
106 f->sizecode = n;
107 LoadVector(S, f->code, n);
108 }
109
110
111 static void LoadFunction(LoadState *S, Proto *f, TString *psource);
112
113
114 static void LoadConstants (LoadState *S, Proto *f) {
115 int i;
116 int n = LoadInt(S);
117 f->k = luaM_newvector(S->L, n, TValue);
118 f->sizek = n;
119 for (i = 0; i < n; i++)
120 setnilvalue(&f->k[i]);
121 for (i = 0; i < n; i++) {
122 TValue *o = &f->k[i];
123 int t = LoadByte(S);
124 switch (t) {
125 case LUA_TNIL:
126 setnilvalue(o);
127 break;
128 case LUA_TBOOLEAN:
129 setbvalue(o, LoadByte(S));
130 break;
131 case LUA_TNUMFLT:
132 setfltvalue(o, LoadNumber(S));
133 break;
134 case LUA_TNUMINT:
135 setivalue(o, LoadInteger(S));
136 break;
137 case LUA_TSHRSTR:
138 case LUA_TLNGSTR:
139 setsvalue2n(S->L, o, LoadString(S));
140 break;
141 default:
142 lua_assert(0);
143 }
144 }
145 }
146
147
148 static void LoadProtos (LoadState *S, Proto *f) {
149 int i;
150 int n = LoadInt(S);
151 f->p = luaM_newvector(S->L, n, Proto *);
152 f->sizep = n;
153 for (i = 0; i < n; i++)
154 f->p[i] = NULL;
155 for (i = 0; i < n; i++) {
156 f->p[i] = luaF_newproto(S->L);
157 LoadFunction(S, f->p[i], f->source);
158 }
159 }
160
161
162 static void LoadUpvalues (LoadState *S, Proto *f) {
163 int i, n;
164 n = LoadInt(S);
165 f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
166 f->sizeupvalues = n;
167 for (i = 0; i < n; i++)
168 f->upvalues[i].name = NULL;
169 for (i = 0; i < n; i++) {
170 f->upvalues[i].instack = LoadByte(S);
171 f->upvalues[i].idx = LoadByte(S);
172 }
173 }
174
175
176 static void LoadDebug (LoadState *S, Proto *f) {
177 int i, n;
178 n = LoadInt(S);
179 f->lineinfo = luaM_newvector(S->L, n, int);
180 f->sizelineinfo = n;
181 LoadVector(S, f->lineinfo, n);
182 n = LoadInt(S);
183 f->locvars = luaM_newvector(S->L, n, LocVar);
184 f->sizelocvars = n;
185 for (i = 0; i < n; i++)
186 f->locvars[i].varname = NULL;
187 for (i = 0; i < n; i++) {
188 f->locvars[i].varname = LoadString(S);
189 f->locvars[i].startpc = LoadInt(S);
190 f->locvars[i].endpc = LoadInt(S);
191 }
192 n = LoadInt(S);
193 for (i = 0; i < n; i++)
194 f->upvalues[i].name = LoadString(S);
195 }
196
197
198 static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
199 f->source = LoadString(S);
200 if (f->source == NULL) /* no source in dump? */
201 f->source = psource; /* reuse parent's source */
202 f->linedefined = LoadInt(S);
203 f->lastlinedefined = LoadInt(S);
204 f->numparams = LoadByte(S);
205 f->is_vararg = LoadByte(S);
206 f->maxstacksize = LoadByte(S);
207 LoadCode(S, f);
208 LoadConstants(S, f);
209 LoadUpvalues(S, f);
210 LoadProtos(S, f);
211 LoadDebug(S, f);
212 }
213
214
215 static void checkliteral (LoadState *S, const char *s, const char *msg) {
216 char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
217 size_t len = strlen(s);
218 LoadVector(S, buff, len);
219 if (memcmp(s, buff, len) != 0)
220 error(S, msg);
221 }
222
223
224 static void fchecksize (LoadState *S, size_t size, const char *tname) {
225 if (LoadByte(S) != size)
226 error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
227 }
228
229
230 #define checksize(S,t) fchecksize(S,sizeof(t),#t)
231
232 static void checkHeader (LoadState *S) {
233 checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
234 if (LoadByte(S) != LUAC_VERSION)
235 error(S, "version mismatch in");
236 if (LoadByte(S) != LUAC_FORMAT)
237 error(S, "format mismatch in");
238 checkliteral(S, LUAC_DATA, "corrupted");
239 checksize(S, int);
240 checksize(S, size_t);
241 checksize(S, Instruction);
242 checksize(S, lua_Integer);
243 checksize(S, lua_Number);
244 if (LoadInteger(S) != LUAC_INT)
245 error(S, "endianness mismatch in");
246 if (LoadNumber(S) != LUAC_NUM)
247 error(S, "float format mismatch in");
248 }
249
250
251 /*
252 ** load precompiled chunk
253 */
254 LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
255 const char *name) {
256 LoadState S;
257 LClosure *cl;
258 if (*name == '@' || *name == '=')
259 S.name = name + 1;
260 else if (*name == LUA_SIGNATURE[0])
261 S.name = "binary string";
262 else
263 S.name = name;
264 S.L = L;
265 S.Z = Z;
266 S.b = buff;
267 checkHeader(&S);
268 cl = luaF_newLclosure(L, LoadByte(&S));
269 setclLvalue(L, L->top, cl);
270 incr_top(L);
271 cl->p = luaF_newproto(L);
272 LoadFunction(&S, cl->p, NULL);
273 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
274 luai_verifycode(L, buff, cl->p);
275 return cl;
276 }
277