2 ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
3 ** load precompiled Lua chunks
4 ** See Copyright Notice in lua.h
32 #ifdef LUAC_TRUST_BINARIES
36 #define IF(c,s) if (c) error(S,s)
38 static void error(LoadState
* S
, const char* why
)
40 luaO_pushfstring(S
->L
,"%s: %s in precompiled chunk",S
->name
,why
);
41 luaD_throw(S
->L
,LUA_ERRSYNTAX
);
45 #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
46 #define LoadByte(S) (lu_byte)LoadChar(S)
47 #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
48 #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
50 static void LoadBlock(LoadState
* S
, void* b
, size_t size
)
52 size_t r
=luaZ_read(S
->Z
,b
,size
);
53 IF (r
!=0, "unexpected end");
56 static int LoadChar(LoadState
* S
)
63 static int LoadInt(LoadState
* S
)
67 IF (x
<0, "bad integer");
71 static lua_Number
LoadNumber(LoadState
* S
)
78 static TString
* LoadString(LoadState
* S
)
86 char* s
=luaZ_openspace(S
->L
,S
->b
,size
);
88 return luaS_newlstr(S
->L
,s
,size
-1); /* remove trailing '\0' */
92 static void LoadCode(LoadState
* S
, Proto
* f
)
95 f
->code
=luaM_newvector(S
->L
,n
,Instruction
);
97 LoadVector(S
,f
->code
,n
,sizeof(Instruction
));
100 static Proto
* LoadFunction(LoadState
* S
, TString
* p
);
102 static void LoadConstants(LoadState
* S
, Proto
* f
)
106 f
->k
=luaM_newvector(S
->L
,n
,TValue
);
108 for (i
=0; i
<n
; i
++) setnilvalue(&f
->k
[i
]);
119 setbvalue(o
,LoadChar(S
)!=0);
122 setnvalue(o
,LoadNumber(S
));
125 setsvalue2n(S
->L
,o
,LoadString(S
));
128 error(S
,"bad constant");
133 f
->p
=luaM_newvector(S
->L
,n
,Proto
*);
135 for (i
=0; i
<n
; i
++) f
->p
[i
]=NULL
;
136 for (i
=0; i
<n
; i
++) f
->p
[i
]=LoadFunction(S
,f
->source
);
139 static void LoadDebug(LoadState
* S
, Proto
* f
)
143 f
->lineinfo
=luaM_newvector(S
->L
,n
,int);
145 LoadVector(S
,f
->lineinfo
,n
,sizeof(int));
147 f
->locvars
=luaM_newvector(S
->L
,n
,LocVar
);
149 for (i
=0; i
<n
; i
++) f
->locvars
[i
].varname
=NULL
;
152 f
->locvars
[i
].varname
=LoadString(S
);
153 f
->locvars
[i
].startpc
=LoadInt(S
);
154 f
->locvars
[i
].endpc
=LoadInt(S
);
157 f
->upvalues
=luaM_newvector(S
->L
,n
,TString
*);
159 for (i
=0; i
<n
; i
++) f
->upvalues
[i
]=NULL
;
160 for (i
=0; i
<n
; i
++) f
->upvalues
[i
]=LoadString(S
);
163 static Proto
* LoadFunction(LoadState
* S
, TString
* p
)
166 if (++S
->L
->nCcalls
> LUAI_MAXCCALLS
) error(S
,"code too deep");
167 f
=luaF_newproto(S
->L
);
168 setptvalue2s(S
->L
,S
->L
->top
,f
); incr_top(S
->L
);
169 f
->source
=LoadString(S
); if (f
->source
==NULL
) f
->source
=p
;
170 f
->linedefined
=LoadInt(S
);
171 f
->lastlinedefined
=LoadInt(S
);
173 f
->numparams
=LoadByte(S
);
174 f
->is_vararg
=LoadByte(S
);
175 f
->maxstacksize
=LoadByte(S
);
179 IF (!luaG_checkcode(f
), "bad code");
185 static void LoadHeader(LoadState
* S
)
187 char h
[LUAC_HEADERSIZE
];
188 char s
[LUAC_HEADERSIZE
];
190 LoadBlock(S
,s
,LUAC_HEADERSIZE
);
191 IF (memcmp(h
,s
,LUAC_HEADERSIZE
)!=0, "bad header");
195 ** load precompiled chunk
197 Proto
* luaU_undump (lua_State
* L
, ZIO
* Z
, Mbuffer
* buff
, const char* name
)
200 if (*name
=='@' || *name
=='=')
202 else if (*name
==LUA_SIGNATURE
[0])
203 S
.name
="binary string";
210 return LoadFunction(&S
,luaS_newliteral(L
,"=?"));
216 void luaU_header (char* h
)
219 memcpy(h
,LUA_SIGNATURE
,sizeof(LUA_SIGNATURE
)-1);
220 h
+=sizeof(LUA_SIGNATURE
)-1;
221 *h
++=(char)LUAC_VERSION
;
222 *h
++=(char)LUAC_FORMAT
;
223 *h
++=(char)*(char*)&x
; /* endianness */
224 *h
++=(char)sizeof(int);
225 *h
++=(char)sizeof(size_t);
226 *h
++=(char)sizeof(Instruction
);
227 *h
++=(char)sizeof(lua_Number
);
228 *h
++=(char)(((lua_Number
)0.5)==0); /* is lua_Number integral? */