aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-04 15:53:41 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-09-04 15:53:41 -0300
commiteebc9729e4614d1c3da7757022cb6d73babd0e0a (patch)
tree0393a08552300d225254399c57366142657c2b5f
parent6990b064679576ec46d26294108bd6cb7991faa6 (diff)
downloadlua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.tar.gz
lua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.tar.bz2
lua-eebc9729e4614d1c3da7757022cb6d73babd0e0a.zip
new versions by lhf
-rw-r--r--lundump.c254
-rw-r--r--lundump.h10
2 files changed, 120 insertions, 144 deletions
diff --git a/lundump.c b/lundump.c
index 2e3478ad..b42f441b 100644
--- a/lundump.c
+++ b/lundump.c
@@ -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
46static unsigned int LoadWord (lua_State* L, ZIO* Z) 45static 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
53static unsigned long LoadLong (lua_State* L, ZIO* Z) 52static 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
60static Number LoadNumber (lua_State* L, ZIO* Z) 62static 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
69static int LoadInt (lua_State* L, ZIO* Z, const char* message) 72static 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
78static TString* LoadString (lua_State* L, ZIO* Z) 82static 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
91static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) 95static 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
113static void LoadCode (lua_State* L, Proto* tf, ZIO* Z) 106static 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
132static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) 119static 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
136static Proto* LoadFunction (lua_State* L, ZIO* Z, int native); 130static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
137 131
138static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native) 132static 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) 150static 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
169static 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
173static 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
194static int LoadHeader (lua_State* L, ZIO* Z) 184static 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
239static Proto* LoadChunk (lua_State* L, ZIO* Z) 214static 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*/
248Proto* luaU_undump1 (lua_State* L, ZIO* Z) 223Proto* 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
233Proto* 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*/
261double luaU_str2d (lua_State* L, const char* b, const char* where) 241int 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}
diff --git a/lundump.h b/lundump.h
index 5c27ae07..debe0b7a 100644
--- a/lundump.h
+++ b/lundump.h
@@ -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 */
14Proto* luaU_undump (lua_State* L, ZIO* Z);
14Proto* luaU_undump1 (lua_State* L, ZIO* Z); 15Proto* luaU_undump1 (lua_State* L, ZIO* Z);
15 16
16/* convert number from text */ 17/* find byte order */
17double luaU_str2d (lua_State* L, const char* b, const char* where); 18int 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