diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-04 15:53:41 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-04 15:53:41 -0300 |
commit | eebc9729e4614d1c3da7757022cb6d73babd0e0a (patch) | |
tree | 0393a08552300d225254399c57366142657c2b5f | |
parent | 6990b064679576ec46d26294108bd6cb7991faa6 (diff) | |
download | lua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.tar.gz lua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.tar.bz2 lua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.zip |
new versions by lhf
-rw-r--r-- | lundump.c | 254 | ||||
-rw-r--r-- | lundump.h | 10 |
2 files changed, 120 insertions, 144 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 1.25 2000/08/24 14:19:39 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 1.29 2000/06/28 14:12:55 lhf Exp lhf $ |
3 | ** load bytecodes from files | 3 | ** load bytecodes from files |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -7,8 +7,6 @@ | |||
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #include <string.h> | 8 | #include <string.h> |
9 | 9 | ||
10 | #include "lua.h" | ||
11 | |||
12 | #include "lauxlib.h" | 10 | #include "lauxlib.h" |
13 | #include "lfunc.h" | 11 | #include "lfunc.h" |
14 | #include "lmem.h" | 12 | #include "lmem.h" |
@@ -16,6 +14,7 @@ | |||
16 | #include "lstring.h" | 14 | #include "lstring.h" |
17 | #include "lundump.h" | 15 | #include "lundump.h" |
18 | 16 | ||
17 | #define LoadVector(L,b,n,s,Z) LoadBlock(L,b,(n)*(s),Z) | ||
19 | #define LoadBlock(L,b,size,Z) ezread(L,Z,b,size) | 18 | #define LoadBlock(L,b,size,Z) ezread(L,Z,b,size) |
20 | #define LoadByte ezgetc | 19 | #define LoadByte ezgetc |
21 | 20 | ||
@@ -43,41 +42,46 @@ static void ezread (lua_State* L, ZIO* Z, void* b, int n) | |||
43 | if (r!=0) unexpectedEOZ(L,Z); | 42 | if (r!=0) unexpectedEOZ(L,Z); |
44 | } | 43 | } |
45 | 44 | ||
46 | static unsigned int LoadWord (lua_State* L, ZIO* Z) | 45 | static void LoadReverse (lua_State* L, void* b, size_t size, ZIO* Z) |
47 | { | 46 | { |
48 | unsigned int hi=ezgetc(L,Z); | 47 | unsigned char *p=(unsigned char *) b+size; |
49 | unsigned int lo=ezgetc(L,Z); | 48 | int n=size; |
50 | return (hi<<8)|lo; | 49 | while (n--) *p--=ezgetc(L,Z); |
51 | } | 50 | } |
52 | 51 | ||
53 | static unsigned long LoadLong (lua_State* L, ZIO* Z) | 52 | static int LoadInt (lua_State* L, ZIO* Z, int swap) |
54 | { | 53 | { |
55 | unsigned long hi=LoadWord(L,Z); | 54 | int x; |
56 | unsigned long lo=LoadWord(L,Z); | 55 | if (swap) |
57 | return (hi<<16)|lo; | 56 | LoadReverse(L,&x,sizeof(x),Z); |
57 | else | ||
58 | LoadBlock(L,&x,sizeof(x),Z); | ||
59 | return x; | ||
58 | } | 60 | } |
59 | 61 | ||
60 | static Number LoadNumber (lua_State* L, ZIO* Z) | 62 | static size_t LoadSize (lua_State* L, ZIO* Z, int swap) |
61 | { | 63 | { |
62 | char b[256]; | 64 | size_t x; |
63 | int size=ezgetc(L,Z); | 65 | if (swap) |
64 | LoadBlock(L,b,size,Z); | 66 | LoadReverse(L,&x,sizeof(x),Z); |
65 | b[size]=0; | 67 | else |
66 | return luaU_str2d(L,b,ZNAME(Z)); | 68 | LoadBlock(L,&x,sizeof(x),Z); |
69 | return x; | ||
67 | } | 70 | } |
68 | 71 | ||
69 | static int LoadInt (lua_State* L, ZIO* Z, const char* message) | 72 | static Number LoadNumber (lua_State* L, ZIO* Z, int swap) |
70 | { | 73 | { |
71 | unsigned long l=LoadLong(L,Z); | 74 | Number x; |
72 | unsigned int i=l; | 75 | if (swap) |
73 | if (i!=l) luaL_verror(L,"%s in `%.255s';\n" | 76 | LoadReverse(L,&x,sizeof(x),Z); |
74 | " read %lu; expected %u",message,ZNAME(Z),l,-1); | 77 | else |
75 | return i; | 78 | LoadBlock(L,&x,sizeof(x),Z); |
79 | return x; | ||
76 | } | 80 | } |
77 | 81 | ||
78 | static TString* LoadString (lua_State* L, ZIO* Z) | 82 | static TString* LoadString (lua_State* L, ZIO* Z, int swap) |
79 | { | 83 | { |
80 | long size=LoadLong(L,Z); | 84 | size_t size=LoadSize(L,Z,swap); |
81 | if (size==0) | 85 | if (size==0) |
82 | return NULL; | 86 | return NULL; |
83 | else | 87 | else |
@@ -88,96 +92,73 @@ static TString* LoadString (lua_State* L, ZIO* Z) | |||
88 | } | 92 | } |
89 | } | 93 | } |
90 | 94 | ||
91 | static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) | 95 | static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap) |
92 | { | 96 | { |
93 | unsigned char* p; | 97 | int size=LoadInt(L,Z,swap); |
94 | unsigned char c; | 98 | tf->code=luaM_newvector(L,size,Instruction); |
95 | if (sizeof(Instruction)==4) | 99 | LoadVector(L,tf->code,size,sizeof(*tf->code),Z); |
96 | while (size--) | 100 | #if 0 |
97 | { | 101 | if (swap) SwapBytes(tf->code,sizeof(*tf->code),size); |
98 | p=(unsigned char *) code++; | 102 | #endif |
99 | c=p[0]; p[0]=p[3]; p[3]=c; | 103 | if (tf->code[size-1]!=OP_END) luaL_verror(L,"bad code in `%.255s'",ZNAME(Z)); |
100 | c=p[1]; p[1]=p[2]; p[2]=c; | ||
101 | } | ||
102 | else if (sizeof(Instruction)==2) | ||
103 | while (size--) | ||
104 | { | ||
105 | p=(unsigned char *) code++; | ||
106 | c=p[0]; p[0]=p[1]; p[1]=c; | ||
107 | } | ||
108 | else | ||
109 | luaL_verror(L,"cannot swap code with %d-byte instructions in `%.255s'", | ||
110 | (int)sizeof(Instruction),ZNAME(Z)); | ||
111 | } | 104 | } |
112 | 105 | ||
113 | static void LoadCode (lua_State* L, Proto* tf, ZIO* Z) | 106 | static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap) |
114 | { | 107 | { |
115 | int size=LoadInt(L,Z,"code too long"); | 108 | int i,n; |
116 | Instruction t=0,tt=TEST_CODE; | 109 | tf->nlocvars=n=LoadInt(L,Z,swap); |
117 | tf->code=luaM_newvector(L,size,Instruction); | 110 | tf->locvars=luaM_newvector(L,n,LocVar); |
118 | LoadBlock(L,tf->code,size*sizeof(*tf->code),Z); | 111 | for (i=0; i<n; i++) |
119 | if (tf->code[size-1]!=OP_END) luaL_verror(L,"bad code in `%.255s'",ZNAME(Z)); | ||
120 | LoadBlock(L,&t,sizeof(t),Z); | ||
121 | if (t!=tt) | ||
122 | { | 112 | { |
123 | Instruction ot=t; | 113 | tf->locvars[i].varname=LoadString(L,Z,swap); |
124 | SwapCode(L,&t,1,Z); | 114 | tf->locvars[i].startpc=LoadInt(L,Z,swap); |
125 | if (t!=tt) luaL_verror(L,"cannot swap code in `%.255s';\n" | 115 | tf->locvars[i].endpc=LoadInt(L,Z,swap); |
126 | " read 0x%08X; swapped to 0x%08X; expected 0x%08X", | ||
127 | ZNAME(Z),(unsigned long)ot,(unsigned long)t,(unsigned long)tt); | ||
128 | SwapCode(L,tf->code,size,Z); | ||
129 | } | 116 | } |
130 | } | 117 | } |
131 | 118 | ||
132 | static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) | 119 | static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap) |
133 | { | 120 | { |
121 | int n=LoadInt(L,Z,swap); | ||
122 | if (n==0) return; | ||
123 | tf->lineinfo=luaM_newvector(L,n,int); | ||
124 | LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z); | ||
125 | #if 0 | ||
126 | if (swap) SwapBytes(tf->lineinfo,sizeof(*tf->lineinfo),n); | ||
127 | #endif | ||
134 | } | 128 | } |
135 | 129 | ||
136 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int native); | 130 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap); |
137 | 131 | ||
138 | static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native) | 132 | static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap) |
139 | { | 133 | { |
140 | int i,n; | 134 | int i,n; |
141 | tf->nkstr=n=LoadInt(L,Z,"too many strings"); | 135 | tf->nkstr=n=LoadInt(L,Z,swap); |
142 | if (n>0) | 136 | tf->kstr=luaM_newvector(L,n,TString*); |
143 | { | 137 | for (i=0; i<n; i++) |
144 | tf->kstr=luaM_newvector(L,n,TString*); | 138 | tf->kstr[i]=LoadString(L,Z,swap); |
145 | for (i=0; i<n; i++) | 139 | tf->nknum=n=LoadInt(L,Z,swap); |
146 | { | 140 | tf->knum=luaM_newvector(L,n,Number); |
147 | TString* s=LoadString(L,Z); | 141 | LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z); |
148 | LoadByte(L,Z); | 142 | if (swap) |
149 | tf->kstr[i]=s; | 143 | for (i=0; i<n; i++) tf->knum[i]=LoadNumber(L,Z,swap); /* TODO */ |
150 | } | 144 | tf->nkproto=n=LoadInt(L,Z,swap); |
151 | } | 145 | tf->kproto=luaM_newvector(L,n,Proto*); |
152 | tf->nknum=n=LoadInt(L,Z,"too many numbers"); | 146 | for (i=0; i<n; i++) |
153 | if (n>0) | 147 | tf->kproto[i]=LoadFunction(L,Z,swap); |
154 | { | 148 | } |
155 | tf->knum=luaM_newvector(L,n,Number); | 149 | |
156 | if (native) | 150 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap) |
157 | LoadBlock(L,tf->knum,n*sizeof(*tf->knum),Z); | ||
158 | else | ||
159 | for (i=0; i<n; i++) tf->knum[i]=LoadNumber(L,Z); | ||
160 | } | ||
161 | tf->nkproto=n=LoadInt(L,Z,"too many functions"); | ||
162 | if (n>0) | ||
163 | { | ||
164 | tf->kproto=luaM_newvector(L,n,Proto*); | ||
165 | for (i=0; i<n; i++) tf->kproto[i]=LoadFunction(L,Z,native); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int native) | ||
170 | { | 151 | { |
171 | Proto* tf=luaF_newproto(L); | 152 | Proto* tf=luaF_newproto(L); |
172 | tf->source=LoadString(L,Z); | 153 | tf->source=LoadString(L,Z,swap); |
173 | if (tf->source==NULL) tf->source=luaS_new(L,zname(Z)); | 154 | tf->lineDefined=LoadInt(L,Z,swap); |
174 | tf->lineDefined=LoadInt(L,Z,"lineDefined too large"); | 155 | tf->numparams=LoadInt(L,Z,swap); |
175 | tf->numparams=LoadInt(L,Z,"too many parameters"); | ||
176 | tf->is_vararg=LoadByte(L,Z); | 156 | tf->is_vararg=LoadByte(L,Z); |
177 | tf->maxstacksize=LoadInt(L,Z,"too much stack needed"); | 157 | tf->maxstacksize=LoadInt(L,Z,swap); |
178 | LoadCode(L,tf,Z); | 158 | LoadCode(L,tf,Z,swap); |
179 | LoadLocals(L,tf,Z); | 159 | LoadLocals(L,tf,Z,swap); |
180 | LoadConstants(L,tf,Z,native); | 160 | LoadLines(L,tf,Z,swap); |
161 | LoadConstants(L,tf,Z,swap); | ||
181 | return tf; | 162 | return tf; |
182 | } | 163 | } |
183 | 164 | ||
@@ -189,11 +170,21 @@ static void LoadSignature (lua_State* L, ZIO* Z) | |||
189 | if (*s!=0) luaL_verror(L,"bad signature in `%.255s'",ZNAME(Z)); | 170 | if (*s!=0) luaL_verror(L,"bad signature in `%.255s'",ZNAME(Z)); |
190 | } | 171 | } |
191 | 172 | ||
173 | static void TestSize (lua_State* L, int s, const char* what, ZIO* Z) | ||
174 | { | ||
175 | int r=ezgetc(L,Z); | ||
176 | if (r!=s) | ||
177 | luaL_verror(L,"virtual machine mismatch in `%.255s':\n" | ||
178 | " %s is %d but read %d",ZNAME(Z),what,r,s); | ||
179 | } | ||
180 | |||
181 | #define TESTSIZE(s) TestSize(L,s,#s,Z) | ||
192 | #define V(v) v/16,v%16 | 182 | #define V(v) v/16,v%16 |
193 | 183 | ||
194 | static int LoadHeader (lua_State* L, ZIO* Z) | 184 | static int LoadHeader (lua_State* L, ZIO* Z) |
195 | { | 185 | { |
196 | int version,sizeofR,native; | 186 | int version,swap; |
187 | Number f=0,tf=TEST_NUMBER; | ||
197 | LoadSignature(L,Z); | 188 | LoadSignature(L,Z); |
198 | version=ezgetc(L,Z); | 189 | version=ezgetc(L,Z); |
199 | if (version>VERSION) | 190 | if (version>VERSION) |
@@ -204,36 +195,20 @@ static int LoadHeader (lua_State* L, ZIO* Z) | |||
204 | luaL_verror(L,"`%.255s' too old:\n" | 195 | luaL_verror(L,"`%.255s' too old:\n" |
205 | " read version %d.%d; expected at least %d.%d", | 196 | " read version %d.%d; expected at least %d.%d", |
206 | ZNAME(Z),V(version),V(VERSION)); | 197 | ZNAME(Z),V(version),V(VERSION)); |
207 | { | 198 | swap=(luaU_endianess()!=ezgetc(L,Z)); /* need to swap bytes? */ |
208 | int I=ezgetc(L,Z); | 199 | TESTSIZE(sizeof(int)); |
209 | int i=ezgetc(L,Z); | 200 | TESTSIZE(sizeof(size_t)); |
210 | int op=ezgetc(L,Z); | 201 | TESTSIZE(sizeof(Instruction)); |
211 | int b=ezgetc(L,Z); | 202 | TESTSIZE(SIZE_INSTRUCTION); |
212 | if (I!=sizeof(Instruction) || i!=SIZE_INSTRUCTION || op!=SIZE_OP || b!=SIZE_B) | 203 | TESTSIZE(SIZE_OP); |
213 | luaL_verror(L,"virtual machine mismatch in `%.255s':\n" | 204 | TESTSIZE(SIZE_B); |
214 | " read %d-bit,%d-byte instructions, %d-bit opcodes, %d-bit b-arguments;\n" | 205 | TESTSIZE(sizeof(Number)); |
215 | " expected %d-bit,%d-byte instructions, %d-bit opcodes, %d-bit b-arguments", | 206 | f=LoadNumber(L,Z,swap); |
216 | ZNAME(Z),i,I,op,b,SIZE_INSTRUCTION,(int)sizeof(Instruction),SIZE_OP,SIZE_B); | 207 | if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */ |
217 | } | 208 | luaL_verror(L,"unknown number format in `%.255s':\n" |
218 | sizeofR=ezgetc(L,Z); | 209 | " read " NUMBER_FMT "; expected " NUMBER_FMT, |
219 | native=(sizeofR!=0); | 210 | ZNAME(Z),f,tf); |
220 | if (native) /* test number representation */ | 211 | return swap; |
221 | { | ||
222 | if (sizeofR!=sizeof(Number)) | ||
223 | luaL_verror(L,"native number size mismatch in `%.255s':\n" | ||
224 | " read %d; expected %d", | ||
225 | ZNAME(Z),sizeofR,(int)sizeof(Number)); | ||
226 | else | ||
227 | { | ||
228 | Number f=0,tf=TEST_NUMBER; | ||
229 | LoadBlock(L,&f,sizeof(f),Z); | ||
230 | if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */ | ||
231 | luaL_verror(L,"unknown number format in `%.255s':\n" | ||
232 | " read " NUMBER_FMT "; expected " NUMBER_FMT, | ||
233 | ZNAME(Z),f,tf); | ||
234 | } | ||
235 | } | ||
236 | return native; | ||
237 | } | 212 | } |
238 | 213 | ||
239 | static Proto* LoadChunk (lua_State* L, ZIO* Z) | 214 | static Proto* LoadChunk (lua_State* L, ZIO* Z) |
@@ -245,23 +220,26 @@ static Proto* LoadChunk (lua_State* L, ZIO* Z) | |||
245 | ** load one chunk from a file or buffer | 220 | ** load one chunk from a file or buffer |
246 | ** return main if ok and NULL at EOF | 221 | ** return main if ok and NULL at EOF |
247 | */ | 222 | */ |
248 | Proto* luaU_undump1 (lua_State* L, ZIO* Z) | 223 | Proto* luaU_undump (lua_State* L, ZIO* Z) |
249 | { | 224 | { |
250 | int c=zgetc(Z); | 225 | int c=zgetc(Z); |
251 | if (c==ID_CHUNK) | 226 | if (c==ID_CHUNK) |
252 | return LoadChunk(L,Z); | 227 | return LoadChunk(L,Z); |
253 | else if (c!=EOZ) | 228 | else if (c!=EOZ) |
254 | luaL_verror(L,"`%.255s' is not a Lua binary file",ZNAME(Z)); | 229 | luaL_verror(L,"`%.255s' is not a precompiled Lua chunk",ZNAME(Z)); |
255 | return NULL; | 230 | return NULL; |
256 | } | 231 | } |
257 | 232 | ||
233 | Proto* luaU_undump1 (lua_State* L, ZIO* Z) | ||
234 | { | ||
235 | return luaU_undump(L,Z); | ||
236 | } | ||
237 | |||
258 | /* | 238 | /* |
259 | * convert number from text | 239 | ** find byte order |
260 | */ | 240 | */ |
261 | double luaU_str2d (lua_State* L, const char* b, const char* where) | 241 | int luaU_endianess (void) |
262 | { | 242 | { |
263 | double x; | 243 | int x=1; |
264 | if (!luaO_str2d(b,&x)) | 244 | return *(char*)&x; |
265 | luaL_verror(L,"cannot convert number `%.255s' in `%.255s'",b,where); | ||
266 | return x; | ||
267 | } | 245 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.h,v 1.19 2000/04/24 17:32:29 lhf Exp $ | 2 | ** $Id: lundump.h,v 1.19 2000/04/24 17:32:29 lhf Exp lhf $ |
3 | ** load pre-compiled Lua chunks | 3 | ** load pre-compiled Lua chunks |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -11,10 +11,11 @@ | |||
11 | #include "lzio.h" | 11 | #include "lzio.h" |
12 | 12 | ||
13 | /* load one chunk */ | 13 | /* load one chunk */ |
14 | Proto* luaU_undump (lua_State* L, ZIO* Z); | ||
14 | Proto* luaU_undump1 (lua_State* L, ZIO* Z); | 15 | Proto* luaU_undump1 (lua_State* L, ZIO* Z); |
15 | 16 | ||
16 | /* convert number from text */ | 17 | /* find byte order */ |
17 | double luaU_str2d (lua_State* L, const char* b, const char* where); | 18 | int luaU_endianess (void); |
18 | 19 | ||
19 | /* definitions for headers of binary files */ | 20 | /* definitions for headers of binary files */ |
20 | #define VERSION 0x40 /* last format change was in 4.0 */ | 21 | #define VERSION 0x40 /* last format change was in 4.0 */ |
@@ -37,7 +38,4 @@ double luaU_str2d (lua_State* L, const char* b, const char* where); | |||
37 | /* multiplying by 1E8 gives non-trivial integer values */ | 38 | /* multiplying by 1E8 gives non-trivial integer values */ |
38 | #define TEST_NUMBER 3.14159265358979323846E8 | 39 | #define TEST_NUMBER 3.14159265358979323846E8 |
39 | 40 | ||
40 | /* something for testing byte order in instructions */ | ||
41 | #define TEST_CODE 0x01020304 | ||
42 | |||
43 | #endif | 41 | #endif |