The Battle for Wesnoth  1.15.0-dev
lundump.cpp
Go to the documentation of this file.
1 /*
2 ** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 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 {
34  ZIO *Z;
35  const char *name;
36 } LoadState;
37 
38 
39 static l_noret error(LoadState *S, const char *why) {
40  luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
42 }
43 
44 
45 /*
46 ** All high-level loads go through LoadVector; you can change it to
47 ** adapt to the endianness of the input
48 */
49 #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
50 
51 static void LoadBlock (LoadState *S, void *b, size_t size) {
52  if (luaZ_read(S->Z, b, size) != 0)
53  error(S, "truncated");
54 }
55 
56 
57 #define LoadVar(S,x) LoadVector(S,&x,1)
58 
59 
60 static lu_byte LoadByte (LoadState *S) {
61  lu_byte x;
62  LoadVar(S, x);
63  return x;
64 }
65 
66 
67 static int LoadInt (LoadState *S) {
68  int x;
69  LoadVar(S, x);
70  return x;
71 }
72 
73 
75  lua_Number x;
76  LoadVar(S, x);
77  return x;
78 }
79 
80 
82  lua_Integer x;
83  LoadVar(S, x);
84  return x;
85 }
86 
87 
89  size_t size = LoadByte(S);
90  if (size == 0xFF)
91  LoadVar(S, size);
92  if (size == 0)
93  return NULL;
94  else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
95  char buff[LUAI_MAXSHORTLEN];
96  LoadVector(S, buff, size);
97  return luaS_newlstr(S->L, buff, size);
98  }
99  else { /* long string */
100  TString *ts = luaS_createlngstrobj(S->L, size);
101  LoadVector(S, getstr(ts), size); /* load directly in final place */
102  return ts;
103  }
104 }
105 
106 
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);
112 }
113 
114 
115 static void LoadFunction(LoadState *S, Proto *f, TString *psource);
116 
117 
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  case LUA_TNUMFLT:
136  setfltvalue(o, LoadNumber(S));
137  break;
138  case LUA_TNUMINT:
139  setivalue(o, LoadInteger(S));
140  break;
141  case LUA_TSHRSTR:
142  case LUA_TLNGSTR:
143  setsvalue2n(S->L, o, LoadString(S));
144  break;
145  default:
146  lua_assert(0);
147  }
148  }
149 }
150 
151 
152 static void LoadProtos (LoadState *S, Proto *f) {
153  int i;
154  int n = LoadInt(S);
155  f->p = luaM_newvector(S->L, n, Proto *);
156  f->sizep = n;
157  for (i = 0; i < n; i++)
158  f->p[i] = NULL;
159  for (i = 0; i < n; i++) {
160  f->p[i] = luaF_newproto(S->L);
161  LoadFunction(S, f->p[i], f->source);
162  }
163 }
164 
165 
166 static void LoadUpvalues (LoadState *S, Proto *f) {
167  int i, n;
168  n = LoadInt(S);
169  f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
170  f->sizeupvalues = n;
171  for (i = 0; i < n; i++)
172  f->upvalues[i].name = NULL;
173  for (i = 0; i < n; i++) {
174  f->upvalues[i].instack = LoadByte(S);
175  f->upvalues[i].idx = LoadByte(S);
176  }
177 }
178 
179 
180 static void LoadDebug (LoadState *S, Proto *f) {
181  int i, n;
182  n = LoadInt(S);
183  f->lineinfo = luaM_newvector(S->L, n, int);
184  f->sizelineinfo = n;
185  LoadVector(S, f->lineinfo, n);
186  n = LoadInt(S);
187  f->locvars = luaM_newvector(S->L, n, LocVar);
188  f->sizelocvars = n;
189  for (i = 0; i < n; i++)
190  f->locvars[i].varname = NULL;
191  for (i = 0; i < n; i++) {
192  f->locvars[i].varname = LoadString(S);
193  f->locvars[i].startpc = LoadInt(S);
194  f->locvars[i].endpc = LoadInt(S);
195  }
196  n = LoadInt(S);
197  for (i = 0; i < n; i++)
198  f->upvalues[i].name = LoadString(S);
199 }
200 
201 
202 static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
203  f->source = LoadString(S);
204  if (f->source == NULL) /* no source in dump? */
205  f->source = psource; /* reuse parent's source */
206  f->linedefined = LoadInt(S);
207  f->lastlinedefined = LoadInt(S);
208  f->numparams = LoadByte(S);
209  f->is_vararg = LoadByte(S);
210  f->maxstacksize = LoadByte(S);
211  LoadCode(S, f);
212  LoadConstants(S, f);
213  LoadUpvalues(S, f);
214  LoadProtos(S, f);
215  LoadDebug(S, f);
216 }
217 
218 
219 static void checkliteral (LoadState *S, const char *s, const char *msg) {
220  char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
221  size_t len = strlen(s);
222  LoadVector(S, buff, len);
223  if (memcmp(s, buff, len) != 0)
224  error(S, msg);
225 }
226 
227 
228 static void fchecksize (LoadState *S, size_t size, const char *tname) {
229  if (LoadByte(S) != size)
230  error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
231 }
232 
233 
234 #define checksize(S,t) fchecksize(S,sizeof(t),#t)
235 
236 static void checkHeader (LoadState *S) {
237  checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
238  if (LoadByte(S) != LUAC_VERSION)
239  error(S, "version mismatch in");
240  if (LoadByte(S) != LUAC_FORMAT)
241  error(S, "format mismatch in");
242  checkliteral(S, LUAC_DATA, "corrupted");
243  checksize(S, int);
244  checksize(S, size_t);
247  checksize(S, lua_Number);
248  if (LoadInteger(S) != LUAC_INT)
249  error(S, "endianness mismatch in");
250  if (LoadNumber(S) != LUAC_NUM)
251  error(S, "float format mismatch in");
252 }
253 
254 
255 /*
256 ** load precompiled chunk
257 */
258 LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
259  LoadState S;
260  LClosure *cl;
261  if (*name == '@' || *name == '=')
262  S.name = name + 1;
263  else if (*name == LUA_SIGNATURE[0])
264  S.name = "binary string";
265  else
266  S.name = name;
267  S.L = L;
268  S.Z = Z;
269  checkHeader(&S);
270  cl = luaF_newLclosure(L, LoadByte(&S));
271  setclLvalue(L, L->top, cl);
272  luaD_inctop(L);
273  cl->p = luaF_newproto(L);
274  LoadFunction(&S, cl->p, NULL);
275  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
276  luai_verifycode(L, buff, cl->p);
277  return cl;
278 }
279 
TString * source
Definition: lobject.h:427
#define LUAC_INT
Definition: lundump.h:18
#define LUAI_MAXSHORTLEN
Definition: llimits.h:177
#define luaM_newvector(L, n, t)
Definition: lmem.h:47
static void LoadBlock(LoadState *S, void *b, size_t size)
Definition: lundump.cpp:51
#define setbvalue(obj, x)
Definition: lobject.h:218
static void LoadFunction(LoadState *S, Proto *f, TString *psource)
Definition: lundump.cpp:202
#define luai_verifycode(L, b, f)
Definition: lundump.cpp:28
Definition: lobject.h:407
Proto * luaF_newproto(lua_State *L)
Definition: lfunc.cpp:99
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
int sizep
Definition: lobject.h:416
static lu_byte LoadByte(LoadState *S)
Definition: lundump.cpp:60
static int LoadInt(LoadState *S)
Definition: lundump.cpp:67
#define l_noret
Definition: llimits.h:143
#define setnilvalue(obj)
Definition: lobject.h:210
static void LoadCode(LoadState *S, Proto *f)
Definition: lundump.cpp:107
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
LocVar * locvars
Definition: lobject.h:424
static void LoadDebug(LoadState *S, Proto *f)
Definition: lundump.cpp:180
#define LUA_SIGNATURE
Definition: lua.h:31
static void LoadUpvalues(LoadState *S, Proto *f)
Definition: lundump.cpp:166
int sizelocvars
Definition: lobject.h:417
#define LUAC_DATA
Definition: lundump.h:16
Upvaldesc * upvalues
Definition: lobject.h:425
#define LUAC_VERSION
Definition: lundump.h:22
#define b
StkId top
Definition: lstate.h:164
static lua_Integer LoadInteger(LoadState *S)
Definition: lundump.cpp:81
LUA_INTEGER lua_Integer
Definition: lua.h:93
unsigned char lu_byte
Definition: llimits.h:35
#define getstr(ts)
Definition: lobject.h:328
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
#define LUAC_NUM
Definition: lundump.h:19
#define LUA_TNUMFLT
Definition: lobject.h:58
#define LUA_TNIL
Definition: lua.h:64
LClosure * luaU_undump(lua_State *L, ZIO *Z, const char *name)
Definition: lundump.cpp:258
static TString * LoadString(LoadState *S)
Definition: lundump.cpp:88
#define checksize(S, t)
Definition: lundump.cpp:234
static void checkliteral(LoadState *S, const char *s, const char *msg)
Definition: lundump.cpp:219
int * lineinfo
Definition: lobject.h:423
int lastlinedefined
Definition: lobject.h:419
#define LUA_TNUMINT
Definition: lobject.h:59
TString * varname
Definition: lobject.h:398
#define LUAC_FORMAT
Definition: lundump.h:23
Instruction * code
Definition: lobject.h:421
#define LoadVector(S, b, n)
Definition: lundump.cpp:49
struct Proto ** p
Definition: lobject.h:422
lu_byte maxstacksize
Definition: lobject.h:411
int sizelineinfo
Definition: lobject.h:415
static void LoadProtos(LoadState *S, Proto *f)
Definition: lundump.cpp:152
l_noret luaD_throw(lua_State *L, int errcode)
Definition: ldo.cpp:110
lua_State * L
Definition: lundump.cpp:33
Definition: lzio.h:55
#define lua_assert(c)
Definition: llimits.h:89
std::size_t i
Definition: function.cpp:933
static lua_Number LoadNumber(LoadState *S)
Definition: lundump.cpp:74
static void LoadConstants(LoadState *S, Proto *f)
Definition: lundump.cpp:118
#define LUA_TLNGSTR
Definition: lobject.h:54
#define setivalue(obj, x)
Definition: lobject.h:204
static void fchecksize(LoadState *S, size_t size, const char *tname)
Definition: lundump.cpp:228
static map_location::DIRECTION s
#define setsvalue2n
Definition: lobject.h:279
lu_byte idx
Definition: lobject.h:389
lu_byte instack
Definition: lobject.h:388
#define setfltvalue(obj, x)
Definition: lobject.h:198
#define setclLvalue(L, obj, x)
Definition: lobject.h:240
int sizek
Definition: lobject.h:413
#define LUA_ERRSYNTAX
Definition: lua.h:50
const char * name
Definition: lundump.cpp:35
lu_byte is_vararg
Definition: lobject.h:410
int linedefined
Definition: lobject.h:418
static void checkHeader(LoadState *S)
Definition: lundump.cpp:236
const char * luaO_pushfstring(lua_State *L, const char *fmt,...)
Definition: lobject.cpp:467
int sizecode
Definition: lobject.h:414
size_t luaZ_read(ZIO *z, void *b, size_t n)
Definition: lzio.cpp:48
unsigned long Instruction
Definition: llimits.h:165
#define LUA_TSHRSTR
Definition: lobject.h:53
LClosure * luaF_newLclosure(lua_State *L, int n)
Definition: lfunc.cpp:33
#define f
double t
Definition: astarsearch.cpp:63
TString * name
Definition: lobject.h:387
struct Proto * p
Definition: lobject.h:455
ZIO * Z
Definition: lundump.cpp:34
int startpc
Definition: lobject.h:399
int endpc
Definition: lobject.h:400
int sizeupvalues
Definition: lobject.h:412
TValue * k
Definition: lobject.h:420
TString * luaS_newlstr(lua_State *L, const char *str, size_t l)
Definition: lstring.cpp:199
void luaD_inctop(lua_State *L)
Definition: ldo.cpp:240
static map_location::DIRECTION n
LUA_NUMBER lua_Number
Definition: lua.h:89
#define LUA_TBOOLEAN
Definition: lua.h:65
lu_byte numparams
Definition: lobject.h:409
TString * luaS_createlngstrobj(lua_State *L, size_t l)
Definition: lstring.cpp:147
#define LoadVar(S, x)
Definition: lundump.cpp:57