diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-01-14 13:49:01 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-01-14 13:49:01 -0200 |
commit | 981fddea022b6cad7768223353b4e7386080c271 (patch) | |
tree | c596f191df4b59c85ea056fca3933ad1f14e984b /lundump.c | |
parent | 81b953f27e2c218e9d772cc5f653f541c451d516 (diff) | |
download | lua-981fddea022b6cad7768223353b4e7386080c271.tar.gz lua-981fddea022b6cad7768223353b4e7386080c271.tar.bz2 lua-981fddea022b6cad7768223353b4e7386080c271.zip |
module to load bytecodes from files.v3.1-alpha
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/lundump.c b/lundump.c new file mode 100644 index 00000000..32d7359a --- /dev/null +++ b/lundump.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | ** $Id: lundump.c,v 1.4 1998/01/13 20:05:24 lhf Exp $ | ||
3 | ** load bytecodes from files | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <stdio.h> | ||
8 | #include "lauxlib.h" | ||
9 | #include "lfunc.h" | ||
10 | #include "lmem.h" | ||
11 | #include "lstring.h" | ||
12 | #include "lundump.h" | ||
13 | |||
14 | typedef struct { | ||
15 | ZIO* Z; | ||
16 | int SwapNumber; | ||
17 | int LoadFloat; | ||
18 | } Sundump; | ||
19 | |||
20 | static void unexpectedEOZ(ZIO* Z) | ||
21 | { | ||
22 | luaL_verror("unexpected end of binary file %s",Z->name); | ||
23 | } | ||
24 | |||
25 | static int ezgetc(ZIO* Z) | ||
26 | { | ||
27 | int c=zgetc(Z); | ||
28 | if (c==EOZ) unexpectedEOZ(Z); | ||
29 | return c; | ||
30 | } | ||
31 | |||
32 | static int ezread(ZIO* Z, void* b, int n) | ||
33 | { | ||
34 | int r=zread(Z,b,n); | ||
35 | if (r!=0) unexpectedEOZ(Z); | ||
36 | return r; | ||
37 | } | ||
38 | |||
39 | static int LoadWord(ZIO* Z) | ||
40 | { | ||
41 | int hi=ezgetc(Z); | ||
42 | int lo=ezgetc(Z); | ||
43 | return (hi<<8)|lo; | ||
44 | } | ||
45 | |||
46 | static void* LoadBlock(int size, ZIO* Z) | ||
47 | { | ||
48 | void* b=luaM_malloc(size); | ||
49 | ezread(Z,b,size); | ||
50 | return b; | ||
51 | } | ||
52 | |||
53 | static int LoadSize(ZIO* Z) | ||
54 | { | ||
55 | int hi=LoadWord(Z); | ||
56 | int lo=LoadWord(Z); | ||
57 | int s=(hi<<16)|lo; | ||
58 | if (hi!=0 && s==lo) | ||
59 | luaL_verror("code too long (%ld bytes)",(hi<<16)|(long)lo); | ||
60 | return s; | ||
61 | } | ||
62 | |||
63 | static char* LoadString(ZIO* Z) | ||
64 | { | ||
65 | int size=LoadWord(Z); | ||
66 | if (size==0) | ||
67 | return NULL; | ||
68 | else | ||
69 | { | ||
70 | char* b=luaL_openspace(size); | ||
71 | ezread(Z,b,size); | ||
72 | return b; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static TaggedString* LoadTString(ZIO* Z) | ||
77 | { | ||
78 | char* s=LoadString(Z); | ||
79 | return (s==NULL) ? NULL : luaS_new(s); | ||
80 | } | ||
81 | |||
82 | static void SwapFloat(float* f) | ||
83 | { | ||
84 | Byte* p=(Byte*)f; | ||
85 | Byte* q=p+sizeof(float)-1; | ||
86 | Byte t; | ||
87 | t=*p; *p++=*q; *q--=t; | ||
88 | t=*p; *p++=*q; *q--=t; | ||
89 | } | ||
90 | |||
91 | static void SwapDouble(double* f) | ||
92 | { | ||
93 | Byte* p=(Byte*)f; | ||
94 | Byte* q=p+sizeof(double)-1; | ||
95 | Byte t; | ||
96 | t=*p; *p++=*q; *q--=t; | ||
97 | t=*p; *p++=*q; *q--=t; | ||
98 | t=*p; *p++=*q; *q--=t; | ||
99 | t=*p; *p++=*q; *q--=t; | ||
100 | } | ||
101 | |||
102 | static real LoadNumber(Sundump* S) | ||
103 | { | ||
104 | if (S->LoadFloat) | ||
105 | { | ||
106 | float f; | ||
107 | ezread(S->Z,&f,sizeof(f)); | ||
108 | if (S->SwapNumber) SwapFloat(&f); | ||
109 | return f; | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | double f; | ||
114 | ezread(S->Z,&f,sizeof(f)); | ||
115 | if (S->SwapNumber) SwapDouble(&f); | ||
116 | return f; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void LoadLocals(TProtoFunc* tf, ZIO* Z) | ||
121 | { | ||
122 | int i,n=LoadWord(Z); | ||
123 | if (n==0) return; | ||
124 | tf->locvars=luaM_newvector(n+1,LocVar); | ||
125 | for (i=0; i<n; i++) | ||
126 | { | ||
127 | tf->locvars[i].line=LoadWord(Z); | ||
128 | tf->locvars[i].varname=LoadTString(Z); | ||
129 | } | ||
130 | tf->locvars[i].line=-1; /* flag end of vector */ | ||
131 | tf->locvars[i].varname=NULL; | ||
132 | } | ||
133 | |||
134 | static void LoadConstants(TProtoFunc* tf, Sundump* S) | ||
135 | { | ||
136 | int i,n=LoadWord(S->Z); | ||
137 | tf->nconsts=n; | ||
138 | if (n==0) return; | ||
139 | tf->consts=luaM_newvector(n,TObject); | ||
140 | for (i=0; i<n; i++) | ||
141 | { | ||
142 | TObject* o=tf->consts+i; | ||
143 | int c=ezgetc(S->Z); | ||
144 | switch (c) | ||
145 | { | ||
146 | case ID_NUM: | ||
147 | ttype(o)=LUA_T_NUMBER; | ||
148 | nvalue(o)=LoadNumber(S); | ||
149 | break; | ||
150 | case ID_STR: | ||
151 | ttype(o)=LUA_T_STRING; | ||
152 | tsvalue(o)=LoadTString(S->Z); | ||
153 | break; | ||
154 | case ID_FUN: | ||
155 | ttype(o)=LUA_T_PROTO; | ||
156 | tfvalue(o)=NULL; | ||
157 | break; | ||
158 | #ifdef DEBUG | ||
159 | default: /* cannot happen */ | ||
160 | luaL_verror("internal error in LoadConstants: " | ||
161 | "bad constant #%d type=%d ('%c')\n",i,c,c); | ||
162 | break; | ||
163 | #endif | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | |||
168 | static TProtoFunc* LoadFunction(Sundump* S); | ||
169 | |||
170 | static void LoadFunctions(TProtoFunc* tf, Sundump* S) | ||
171 | { | ||
172 | while (zgetc(S->Z)==ID_FUNCTION) | ||
173 | { | ||
174 | int i=LoadWord(S->Z); | ||
175 | TProtoFunc* t=LoadFunction(S); | ||
176 | TObject* o=tf->consts+i; | ||
177 | tfvalue(o)=t; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | static TProtoFunc* LoadFunction(Sundump* S) | ||
182 | { | ||
183 | ZIO* Z=S->Z; | ||
184 | TProtoFunc* tf=luaF_newproto(); | ||
185 | tf->lineDefined=LoadWord(Z); | ||
186 | tf->fileName=LoadTString(Z); | ||
187 | tf->code=LoadBlock(LoadSize(Z),Z); | ||
188 | LoadConstants(tf,S); | ||
189 | LoadLocals(tf,Z); | ||
190 | LoadFunctions(tf,S); | ||
191 | return tf; | ||
192 | } | ||
193 | |||
194 | static void LoadSignature(ZIO* Z) | ||
195 | { | ||
196 | char* s=SIGNATURE; | ||
197 | while (*s!=0 && ezgetc(Z)==*s) | ||
198 | ++s; | ||
199 | if (*s!=0) luaL_verror("bad signature in binary file %s",Z->name); | ||
200 | } | ||
201 | |||
202 | static void LoadHeader(Sundump* S) | ||
203 | { | ||
204 | ZIO* Z=S->Z; | ||
205 | int version,sizeofR; | ||
206 | LoadSignature(Z); | ||
207 | version=ezgetc(Z); | ||
208 | if (version>VERSION) | ||
209 | luaL_verror( | ||
210 | "binary file %s too new: version=0x%02x; expected at most 0x%02x", | ||
211 | Z->name,version,VERSION); | ||
212 | if (version<0x31) /* major change in 3.1 */ | ||
213 | luaL_verror( | ||
214 | "binary file %s too old: version=0x%02x; expected at least 0x%02x", | ||
215 | Z->name,version,0x31); | ||
216 | sizeofR=ezgetc(Z); /* test float representation */ | ||
217 | if (sizeofR==sizeof(float)) | ||
218 | { | ||
219 | float f,tf=TEST_FLOAT; | ||
220 | ezread(Z,&f,sizeof(f)); | ||
221 | if (f!=tf) | ||
222 | { | ||
223 | SwapFloat(&f); | ||
224 | if (f!=tf) | ||
225 | luaL_verror("unknown float representation in binary file %s",Z->name); | ||
226 | S->SwapNumber=1; | ||
227 | } | ||
228 | S->LoadFloat=1; | ||
229 | } | ||
230 | else if (sizeofR==sizeof(double)) | ||
231 | { | ||
232 | double f,tf=TEST_FLOAT; | ||
233 | ezread(Z,&f,sizeof(f)); | ||
234 | if (f!=tf) | ||
235 | { | ||
236 | SwapDouble(&f); | ||
237 | if (f!=tf) | ||
238 | luaL_verror("unknown float representation in binary file %s",Z->name); | ||
239 | S->SwapNumber=1; | ||
240 | } | ||
241 | S->LoadFloat=0; | ||
242 | } | ||
243 | else | ||
244 | luaL_verror( | ||
245 | "floats in binary file %s have %d bytes; " | ||
246 | "expected %d (float) or %d (double)", | ||
247 | Z->name,sizeofR,sizeof(float),sizeof(double)); | ||
248 | } | ||
249 | |||
250 | static TProtoFunc* LoadChunk(Sundump* S) | ||
251 | { | ||
252 | LoadHeader(S); | ||
253 | return LoadFunction(S); | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | ** load one chunk from a file or buffer | ||
258 | ** return main if ok and NULL at EOF | ||
259 | */ | ||
260 | TProtoFunc* luaU_undump1(ZIO* Z) | ||
261 | { | ||
262 | int c=zgetc(Z); | ||
263 | Sundump S; | ||
264 | S.Z=Z; | ||
265 | S.SwapNumber=0; | ||
266 | S.LoadFloat=1; | ||
267 | if (c==ID_CHUNK) | ||
268 | return LoadChunk(&S); | ||
269 | else if (c!=EOZ) | ||
270 | luaL_verror("%s is not a lua binary file",Z->name); | ||
271 | return NULL; | ||
272 | } | ||