2 ** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp $
3 ** load precompiled Lua chunks
4 ** See Copyright Notice in lua.h
30 static l_noret
error(LoadState
* S
, const char* why
)
32 luaO_pushfstring(S
->L
,"%s: %s precompiled chunk",S
->name
,why
);
33 luaD_throw(S
->L
,LUA_ERRSYNTAX
);
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)
41 #if !defined(luai_verifycode)
42 #define luai_verifycode(L,b,f) /* empty */
45 static void LoadBlock(LoadState
* S
, void* b
, size_t size
)
47 if (luaZ_read(S
->Z
,b
,size
)!=0) error(S
,"truncated");
50 static int LoadChar(LoadState
* S
)
57 static int LoadInt(LoadState
* S
)
61 if (x
<0) error(S
,"corrupted");
65 static lua_Number
LoadNumber(LoadState
* S
)
72 static TString
* LoadString(LoadState
* S
)
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' */
86 static void LoadCode(LoadState
* S
, Proto
* f
)
89 f
->code
=luaM_newvector(S
->L
,n
,Instruction
);
91 LoadVector(S
,f
->code
,n
,sizeof(Instruction
));
94 static void LoadFunction(LoadState
* S
, Proto
* f
);
96 static void LoadConstants(LoadState
* S
, Proto
* f
)
100 f
->k
=luaM_newvector(S
->L
,n
,TValue
);
102 for (i
=0; i
<n
; i
++) setnilvalue(&f
->k
[i
]);
113 setbvalue(o
,LoadChar(S
));
116 setnvalue(o
,LoadNumber(S
));
119 setsvalue2n(S
->L
,o
,LoadString(S
));
121 default: lua_assert(0);
125 f
->p
=luaM_newvector(S
->L
,n
,Proto
*);
127 for (i
=0; i
<n
; i
++) f
->p
[i
]=NULL
;
130 f
->p
[i
]=luaF_newproto(S
->L
);
131 LoadFunction(S
,f
->p
[i
]);
135 static void LoadUpvalues(LoadState
* S
, Proto
* f
)
139 f
->upvalues
=luaM_newvector(S
->L
,n
,Upvaldesc
);
141 for (i
=0; i
<n
; i
++) f
->upvalues
[i
].name
=NULL
;
144 f
->upvalues
[i
].instack
=LoadByte(S
);
145 f
->upvalues
[i
].idx
=LoadByte(S
);
149 static void LoadDebug(LoadState
* S
, Proto
* f
)
152 f
->source
=LoadString(S
);
154 f
->lineinfo
=luaM_newvector(S
->L
,n
,int);
156 LoadVector(S
,f
->lineinfo
,n
,sizeof(int));
158 f
->locvars
=luaM_newvector(S
->L
,n
,LocVar
);
160 for (i
=0; i
<n
; i
++) f
->locvars
[i
].varname
=NULL
;
163 f
->locvars
[i
].varname
=LoadString(S
);
164 f
->locvars
[i
].startpc
=LoadInt(S
);
165 f
->locvars
[i
].endpc
=LoadInt(S
);
168 for (i
=0; i
<n
; i
++) f
->upvalues
[i
].name
=LoadString(S
);
171 static void LoadFunction(LoadState
* S
, Proto
* f
)
173 f
->linedefined
=LoadInt(S
);
174 f
->lastlinedefined
=LoadInt(S
);
175 f
->numparams
=LoadByte(S
);
176 f
->is_vararg
=LoadByte(S
);
177 f
->maxstacksize
=LoadByte(S
);
184 /* the code below must be consistent with the code in luaU_header */
185 #define N0 LUAC_HEADERSIZE
186 #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char))
190 static void LoadHeader(LoadState
* S
)
192 lu_byte h
[LUAC_HEADERSIZE
];
193 lu_byte s
[LUAC_HEADERSIZE
];
195 memcpy(s
,h
,sizeof(char)); /* first char already read */
196 LoadBlock(S
,s
+sizeof(char),LUAC_HEADERSIZE
-sizeof(char));
197 if (memcmp(h
,s
,N0
)==0) return;
198 if (memcmp(h
,s
,N1
)!=0) error(S
,"not a");
199 if (memcmp(h
,s
,N2
)!=0) error(S
,"version mismatch in");
200 if (memcmp(h
,s
,N3
)!=0) error(S
,"incompatible"); else error(S
,"corrupted");
204 ** load precompiled chunk
206 Closure
* luaU_undump (lua_State
* L
, ZIO
* Z
, Mbuffer
* buff
, const char* name
)
210 if (*name
=='@' || *name
=='=')
212 else if (*name
==LUA_SIGNATURE
[0])
213 S
.name
="binary string";
220 cl
=luaF_newLclosure(L
,1);
221 setclLvalue(L
,L
->top
,cl
); incr_top(L
);
222 cl
->l
.p
=luaF_newproto(L
);
223 LoadFunction(&S
,cl
->l
.p
);
224 if (cl
->l
.p
->sizeupvalues
!= 1)
227 cl
=luaF_newLclosure(L
,cl
->l
.p
->sizeupvalues
);
229 setclLvalue(L
,L
->top
-1,cl
);
231 luai_verifycode(L
,buff
,cl
->l
.p
);
235 #define MYINT(s) (s[0]-'0')
236 #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
237 #define FORMAT 0 /* this is the official format */
240 * make header for precompiled chunks
241 * if you change the code below be sure to update LoadHeader and FORMAT above
242 * and LUAC_HEADERSIZE in lundump.h
244 void luaU_header (lu_byte
* h
)
247 memcpy(h
,LUA_SIGNATURE
,sizeof(LUA_SIGNATURE
)-sizeof(char));
248 h
+=sizeof(LUA_SIGNATURE
)-sizeof(char);
249 *h
++=cast_byte(VERSION
);
250 *h
++=cast_byte(FORMAT
);
251 *h
++=cast_byte(*(char*)&x
); /* endianness */
252 *h
++=cast_byte(sizeof(int));
253 *h
++=cast_byte(sizeof(size_t));
254 *h
++=cast_byte(sizeof(Instruction
));
255 *h
++=cast_byte(sizeof(lua_Number
));
256 *h
++=cast_byte(((lua_Number
)0.5)==0); /* is lua_Number integral? */
257 memcpy(h
,LUAC_TAIL
,sizeof(LUAC_TAIL
)-sizeof(char));