2 ** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $
3 ** load pre-compiled Lua chunks
4 ** See Copyright Notice in lua.h
19 #define LoadByte (lu_byte) ezgetc
29 static void unexpectedEOZ (LoadState
* S
)
31 luaG_runerror(S
->L
,"unexpected end of file in %s",S
->name
);
34 static int ezgetc (LoadState
* S
)
37 if (c
==EOZ
) unexpectedEOZ(S
);
41 static void ezread (LoadState
* S
, void* b
, int n
)
43 int r
=luaZ_read(S
->Z
,b
,n
);
44 if (r
!=0) unexpectedEOZ(S
);
47 static void LoadBlock (LoadState
* S
, void* b
, size_t size
)
51 char* p
=(char*) b
+size
-1;
53 while (n
--) *p
--=(char)ezgetc(S
);
59 static void LoadVector (LoadState
* S
, void* b
, int m
, size_t size
)
68 while (n
--) *p
--=(char)ezgetc(S
);
76 static int LoadInt (LoadState
* S
)
79 LoadBlock(S
,&x
,sizeof(x
));
80 if (x
<0) luaG_runerror(S
->L
,"bad integer in %s",S
->name
);
84 static size_t LoadSize (LoadState
* S
)
87 LoadBlock(S
,&x
,sizeof(x
));
91 static lua_Number
LoadNumber (LoadState
* S
)
94 LoadBlock(S
,&x
,sizeof(x
));
98 static TString
* LoadString (LoadState
* S
)
100 size_t size
=LoadSize(S
);
105 char* s
=luaZ_openspace(S
->L
,S
->b
,size
);
107 return luaS_newlstr(S
->L
,s
,size
-1); /* remove trailing '\0' */
111 static void LoadCode (LoadState
* S
, Proto
* f
)
114 f
->code
=luaM_newvector(S
->L
,size
,Instruction
);
116 LoadVector(S
,f
->code
,size
,sizeof(*f
->code
));
119 static void LoadLocals (LoadState
* S
, Proto
* f
)
123 f
->locvars
=luaM_newvector(S
->L
,n
,LocVar
);
127 f
->locvars
[i
].varname
=LoadString(S
);
128 f
->locvars
[i
].startpc
=LoadInt(S
);
129 f
->locvars
[i
].endpc
=LoadInt(S
);
133 static void LoadLines (LoadState
* S
, Proto
* f
)
136 f
->lineinfo
=luaM_newvector(S
->L
,size
,int);
137 f
->sizelineinfo
=size
;
138 LoadVector(S
,f
->lineinfo
,size
,sizeof(*f
->lineinfo
));
141 static void LoadUpvalues (LoadState
* S
, Proto
* f
)
145 if (n
!=0 && n
!=f
->nups
)
146 luaG_runerror(S
->L
,"bad nupvalues in %s: read %d; expected %d",
148 f
->upvalues
=luaM_newvector(S
->L
,n
,TString
*);
150 for (i
=0; i
<n
; i
++) f
->upvalues
[i
]=LoadString(S
);
153 static Proto
* LoadFunction (LoadState
* S
, TString
* p
);
155 static void LoadConstants (LoadState
* S
, Proto
* f
)
159 f
->k
=luaM_newvector(S
->L
,n
,TObject
);
168 setnvalue(o
,LoadNumber(S
));
171 setsvalue2n(o
,LoadString(S
));
177 luaG_runerror(S
->L
,"bad constant type (%d) in %s",t
,S
->name
);
182 f
->p
=luaM_newvector(S
->L
,n
,Proto
*);
184 for (i
=0; i
<n
; i
++) f
->p
[i
]=LoadFunction(S
,f
->source
);
187 static Proto
* LoadFunction (LoadState
* S
, TString
* p
)
189 Proto
* f
=luaF_newproto(S
->L
);
190 f
->source
=LoadString(S
); if (f
->source
==NULL
) f
->source
=p
;
191 f
->lineDefined
=LoadInt(S
);
193 f
->numparams
=LoadByte(S
);
194 f
->is_vararg
=LoadByte(S
);
195 f
->maxstacksize
=LoadByte(S
);
201 #ifndef TRUST_BINARIES
202 if (!luaG_checkcode(f
)) luaG_runerror(S
->L
,"bad code in %s",S
->name
);
207 static void LoadSignature (LoadState
* S
)
209 const char* s
=LUA_SIGNATURE
;
210 while (*s
!=0 && ezgetc(S
)==*s
)
212 if (*s
!=0) luaG_runerror(S
->L
,"bad signature in %s",S
->name
);
215 static void TestSize (LoadState
* S
, int s
, const char* what
)
219 luaG_runerror(S
->L
,"virtual machine mismatch in %s: "
220 "size of %s is %d but read %d",S
->name
,what
,s
,r
);
223 #define TESTSIZE(s,w) TestSize(S,s,w)
224 #define V(v) v/16,v%16
226 static void LoadHeader (LoadState
* S
)
229 lua_Number x
,tx
=TEST_NUMBER
;
233 luaG_runerror(S
->L
,"%s too new: "
234 "read version %d.%d; expected at most %d.%d",
235 S
->name
,V(version
),V(VERSION
));
236 if (version
<VERSION0
) /* check last major change */
237 luaG_runerror(S
->L
,"%s too old: "
238 "read version %d.%d; expected at least %d.%d",
239 S
->name
,V(version
),V(VERSION0
));
240 S
->swap
=(luaU_endianness()!=LoadByte(S
)); /* need to swap bytes? */
241 TESTSIZE(sizeof(int),"int");
242 TESTSIZE(sizeof(size_t), "size_t");
243 TESTSIZE(sizeof(Instruction
), "Instruction");
244 TESTSIZE(SIZE_OP
, "OP");
245 TESTSIZE(SIZE_A
, "A");
246 TESTSIZE(SIZE_B
, "B");
247 TESTSIZE(SIZE_C
, "C");
248 TESTSIZE(sizeof(lua_Number
), "number");
250 if ((long)x
!=(long)tx
) /* disregard errors in last bits of fraction */
251 luaG_runerror(S
->L
,"unknown number format in %s",S
->name
);
254 static Proto
* LoadChunk (LoadState
* S
)
257 return LoadFunction(S
,NULL
);
261 ** load precompiled chunk
263 Proto
* luaU_undump (lua_State
* L
, ZIO
* Z
, Mbuffer
* buff
)
266 const char* s
=zname(Z
);
267 if (*s
=='@' || *s
=='=')
269 else if (*s
==LUA_SIGNATURE
[0])
270 S
.name
="binary string";
276 return LoadChunk(&S
);
282 int luaU_endianness (void)