diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-25 13:44:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-04-25 13:44:31 -0300 |
commit | 0e8855e171ffa957d08d1a1df707d917a029b39f (patch) | |
tree | 569cdbd8467290247f642f07fc496e31e66be302 /lundump.c | |
parent | 2ae9c856cfd8db834e023ee0b00601d02df9b388 (diff) | |
download | lua-0e8855e171ffa957d08d1a1df707d917a029b39f.tar.gz lua-0e8855e171ffa957d08d1a1df707d917a029b39f.tar.bz2 lua-0e8855e171ffa957d08d1a1df707d917a029b39f.zip |
final version (by lhf)
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 133 |
1 files changed, 96 insertions, 37 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 1.18 2000/03/03 14:58:26 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 1.28 2000/04/24 19:32:58 lhf Exp $ |
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 | */ |
@@ -17,10 +17,17 @@ | |||
17 | #include "lundump.h" | 17 | #include "lundump.h" |
18 | 18 | ||
19 | #define LoadBlock(L,b,size,Z) ezread(L,Z,b,size) | 19 | #define LoadBlock(L,b,size,Z) ezread(L,Z,b,size) |
20 | #define LoadByte ezgetc | ||
21 | |||
22 | static const char* ZNAME(ZIO* Z) | ||
23 | { | ||
24 | const char* s=zname(Z); | ||
25 | return (*s=='@') ? s+1 : s; | ||
26 | } | ||
20 | 27 | ||
21 | static void unexpectedEOZ (lua_State* L, ZIO* Z) | 28 | static void unexpectedEOZ (lua_State* L, ZIO* Z) |
22 | { | 29 | { |
23 | luaL_verror(L,"unexpected end of file in %.255s",zname(Z)); | 30 | luaL_verror(L,"unexpected end of file in `%.255s'",ZNAME(Z)); |
24 | } | 31 | } |
25 | 32 | ||
26 | static int ezgetc (lua_State* L, ZIO* Z) | 33 | static int ezgetc (lua_State* L, ZIO* Z) |
@@ -56,25 +63,18 @@ static Number LoadNumber (lua_State* L, ZIO* Z) | |||
56 | int size=ezgetc(L,Z); | 63 | int size=ezgetc(L,Z); |
57 | LoadBlock(L,b,size,Z); | 64 | LoadBlock(L,b,size,Z); |
58 | b[size]=0; | 65 | b[size]=0; |
59 | return luaU_str2d(L,b,zname(Z)); | 66 | return luaU_str2d(L,b,ZNAME(Z)); |
60 | } | 67 | } |
61 | 68 | ||
62 | static int LoadInt (lua_State* L, ZIO* Z, const char* message) | 69 | static int LoadInt (lua_State* L, ZIO* Z, const char* message) |
63 | { | 70 | { |
64 | unsigned long l=LoadLong(L,Z); | 71 | unsigned long l=LoadLong(L,Z); |
65 | unsigned int i=l; | 72 | unsigned int i=l; |
66 | if (i!=l) luaL_verror(L,message,l,zname(Z)); | 73 | if (i!=l) luaL_verror(L,"%s in `%.255s';\n" |
74 | " read %lu; expected %u",message,ZNAME(Z),l,-1); | ||
67 | return i; | 75 | return i; |
68 | } | 76 | } |
69 | 77 | ||
70 | static void LoadCode (lua_State* L, Proto* tf, ZIO* Z) | ||
71 | { | ||
72 | int size=LoadInt(L,Z,"code too long (%lu bytes) in %.255s"); | ||
73 | tf->code=luaM_newvector(L,size,Instruction); | ||
74 | LoadBlock(L,tf->code,size*sizeof(tf->code[0]),Z); | ||
75 | if (tf->code[size-1]!=OP_END) luaL_verror(L,"bad code in %.255s",zname(Z)); | ||
76 | } | ||
77 | |||
78 | static TString* LoadString (lua_State* L, ZIO* Z) | 78 | static TString* LoadString (lua_State* L, ZIO* Z) |
79 | { | 79 | { |
80 | long size=LoadLong(L,Z); | 80 | long size=LoadLong(L,Z); |
@@ -88,14 +88,55 @@ static TString* LoadString (lua_State* L, ZIO* Z) | |||
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) | ||
92 | { | ||
93 | unsigned char* p; | ||
94 | int c; | ||
95 | if (sizeof(Instruction)==4) | ||
96 | while (size--) | ||
97 | { | ||
98 | p=(unsigned char *) code++; | ||
99 | c=p[0]; p[0]=p[3]; p[3]=c; | ||
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 | } | ||
112 | |||
113 | static void LoadCode (lua_State* L, Proto* tf, ZIO* Z) | ||
114 | { | ||
115 | int size=LoadInt(L,Z,"code too long"); | ||
116 | Instruction t=0,tt=TEST_CODE; | ||
117 | tf->code=luaM_newvector(L,size,Instruction); | ||
118 | LoadBlock(L,tf->code,size*sizeof(*tf->code),Z); | ||
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 | { | ||
123 | Instruction ot=t; | ||
124 | SwapCode(L,&t,1,Z); | ||
125 | if (t!=tt) luaL_verror(L,"cannot swap code in `%.255s';\n" | ||
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 | } | ||
130 | } | ||
131 | |||
91 | static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) | 132 | static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) |
92 | { | 133 | { |
93 | int i,n=LoadInt(L,Z,"too many locals (%lu) in %.255s"); | 134 | int i,n=LoadInt(L,Z,"too many locals"); |
94 | if (n==0) return; | 135 | if (n==0) return; |
95 | tf->locvars=luaM_newvector(L,n+1,LocVar); | 136 | tf->locvars=luaM_newvector(L,n+1,LocVar); |
96 | for (i=0; i<n; i++) | 137 | for (i=0; i<n; i++) |
97 | { | 138 | { |
98 | tf->locvars[i].line=LoadInt(L,Z,"too many lines (%lu) in %.255s"); | 139 | tf->locvars[i].line=LoadInt(L,Z,"too many lines"); |
99 | tf->locvars[i].varname=LoadString(L,Z); | 140 | tf->locvars[i].varname=LoadString(L,Z); |
100 | } | 141 | } |
101 | tf->locvars[i].line=-1; /* flag end of vector */ | 142 | tf->locvars[i].line=-1; /* flag end of vector */ |
@@ -107,22 +148,28 @@ static Proto* LoadFunction (lua_State* L, ZIO* Z, int native); | |||
107 | static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native) | 148 | static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native) |
108 | { | 149 | { |
109 | int i,n; | 150 | int i,n; |
110 | tf->nkstr=n=LoadInt(L,Z,"too many strings (%lu) in %.255s"); | 151 | tf->nkstr=n=LoadInt(L,Z,"too many strings"); |
111 | if (n>0) | 152 | if (n>0) |
112 | { | 153 | { |
113 | tf->kstr=luaM_newvector(L,n,TString*); | 154 | tf->kstr=luaM_newvector(L,n,TString*); |
114 | for (i=0; i<n; i++) tf->kstr[i]=LoadString(L,Z); | 155 | for (i=0; i<n; i++) |
156 | { | ||
157 | TString* s=LoadString(L,Z); | ||
158 | int isglobal=LoadByte(L,Z); | ||
159 | if (isglobal) luaS_assertglobal(L,s); | ||
160 | tf->kstr[i]=s; | ||
161 | } | ||
115 | } | 162 | } |
116 | tf->nknum=n=LoadInt(L,Z,"too many numbers (%lu) in %.255s"); | 163 | tf->nknum=n=LoadInt(L,Z,"too many numbers"); |
117 | if (n>0) | 164 | if (n>0) |
118 | { | 165 | { |
119 | tf->knum=luaM_newvector(L,n,Number); | 166 | tf->knum=luaM_newvector(L,n,Number); |
120 | if (native) | 167 | if (native) |
121 | LoadBlock(L,tf->knum,n*sizeof(tf->knum[0]),Z); | 168 | LoadBlock(L,tf->knum,n*sizeof(*tf->knum),Z); |
122 | else | 169 | else |
123 | for (i=0; i<n; i++) tf->knum[i]=LoadNumber(L,Z); | 170 | for (i=0; i<n; i++) tf->knum[i]=LoadNumber(L,Z); |
124 | } | 171 | } |
125 | tf->nkproto=n=LoadInt(L,Z,"too many functions (%lu) in %.255s"); | 172 | tf->nkproto=n=LoadInt(L,Z,"too many functions"); |
126 | if (n>0) | 173 | if (n>0) |
127 | { | 174 | { |
128 | tf->kproto=luaM_newvector(L,n,Proto*); | 175 | tf->kproto=luaM_newvector(L,n,Proto*); |
@@ -133,12 +180,12 @@ static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native) | |||
133 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int native) | 180 | static Proto* LoadFunction (lua_State* L, ZIO* Z, int native) |
134 | { | 181 | { |
135 | Proto* tf=luaF_newproto(L); | 182 | Proto* tf=luaF_newproto(L); |
136 | tf->lineDefined=LoadInt(L,Z,"lineDefined too large (%lu) in %.255s"); | ||
137 | tf->source=LoadString(L,Z); | 183 | tf->source=LoadString(L,Z); |
138 | if (tf->source==NULL) tf->source=luaS_new(L,zname(Z)); | 184 | if (tf->source==NULL) tf->source=luaS_new(L,zname(Z)); |
139 | tf->numparams=LoadInt(L,Z,"numparams too large (%lu) in %.255s"); | 185 | tf->lineDefined=LoadInt(L,Z,"lineDefined too large"); |
140 | tf->is_vararg=LoadInt(L,Z,"is_vararg too large (%lu) in %.255s"); | 186 | tf->numparams=LoadInt(L,Z,"too many parameters"); |
141 | tf->maxstacksize=LoadInt(L,Z,"maxstacksize too large (%lu) in %.255s"); | 187 | tf->is_vararg=LoadByte(L,Z); |
188 | tf->maxstacksize=LoadInt(L,Z,"too much stack needed"); | ||
142 | LoadCode(L,tf,Z); | 189 | LoadCode(L,tf,Z); |
143 | LoadLocals(L,tf,Z); | 190 | LoadLocals(L,tf,Z); |
144 | LoadConstants(L,tf,Z,native); | 191 | LoadConstants(L,tf,Z,native); |
@@ -150,7 +197,7 @@ static void LoadSignature (lua_State* L, ZIO* Z) | |||
150 | const char* s=SIGNATURE; | 197 | const char* s=SIGNATURE; |
151 | while (*s!=0 && ezgetc(L,Z)==*s) | 198 | while (*s!=0 && ezgetc(L,Z)==*s) |
152 | ++s; | 199 | ++s; |
153 | if (*s!=0) luaL_verror(L,"bad signature in %.255s",zname(Z)); | 200 | if (*s!=0) luaL_verror(L,"bad signature in `%.255s'",ZNAME(Z)); |
154 | } | 201 | } |
155 | 202 | ||
156 | #define V(v) v/16,v%16 | 203 | #define V(v) v/16,v%16 |
@@ -161,28 +208,40 @@ static int LoadHeader (lua_State* L, ZIO* Z) | |||
161 | LoadSignature(L,Z); | 208 | LoadSignature(L,Z); |
162 | version=ezgetc(L,Z); | 209 | version=ezgetc(L,Z); |
163 | if (version>VERSION) | 210 | if (version>VERSION) |
164 | luaL_verror(L, | 211 | luaL_verror(L,"`%.255s' too new:\n" |
165 | "%.255s too new: its version is %d.%d; expected at most %d.%d", | 212 | " read version %d.%d; expected at most %d.%d", |
166 | zname(Z),V(version),V(VERSION)); | 213 | ZNAME(Z),V(version),V(VERSION)); |
167 | if (version<VERSION0) /* check last major change */ | 214 | if (version<VERSION0) /* check last major change */ |
168 | luaL_verror(L, | 215 | luaL_verror(L,"`%.255s' too old:\n" |
169 | "%.255s too old: its version is %d.%d; expected at least %d.%d", | 216 | " read version %d.%d; expected at least %d.%d", |
170 | zname(Z),V(version),V(VERSION)); | 217 | ZNAME(Z),V(version),V(VERSION)); |
218 | { | ||
219 | int I=ezgetc(L,Z); | ||
220 | int i=ezgetc(L,Z); | ||
221 | int op=ezgetc(L,Z); | ||
222 | int b=ezgetc(L,Z); | ||
223 | if (I!=sizeof(Instruction) || i!=SIZE_INSTRUCTION || op!=SIZE_OP || b!=SIZE_B) | ||
224 | luaL_verror(L,"virtual machine mismatch in `%.255s':\n" | ||
225 | " read %d-bit,%d-byte instructions, %d-bit opcodes, %d-bit b-arguments;\n" | ||
226 | " expected %d-bit,%d-byte instructions, %d-bit opcodes, %d-bit b-arguments", | ||
227 | ZNAME(Z),i,I,op,b,SIZE_INSTRUCTION,(int)sizeof(Instruction),SIZE_OP,SIZE_B); | ||
228 | } | ||
171 | sizeofR=ezgetc(L,Z); | 229 | sizeofR=ezgetc(L,Z); |
172 | native=(sizeofR!=0); | 230 | native=(sizeofR!=0); |
173 | if (native) /* test number representation */ | 231 | if (native) /* test number representation */ |
174 | { | 232 | { |
175 | if (sizeofR!=sizeof(Number)) | 233 | if (sizeofR!=sizeof(Number)) |
176 | luaL_verror(L,"unknown number size in %.255s: read %d; expected %d", | 234 | luaL_verror(L,"native number size mismatch in `%.255s':\n" |
177 | zname(Z),sizeofR,(int)sizeof(Number)); | 235 | " read %d; expected %d", |
236 | ZNAME(Z),sizeofR,(int)sizeof(Number)); | ||
178 | else | 237 | else |
179 | { | 238 | { |
180 | Number f=0,tf=TEST_NUMBER; | 239 | Number f=0,tf=TEST_NUMBER; |
181 | LoadBlock(L,&f,sizeof(f),Z); | 240 | LoadBlock(L,&f,sizeof(f),Z); |
182 | if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */ | 241 | if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */ |
183 | luaL_verror(L,"unknown number format in %.255s: " | 242 | luaL_verror(L,"unknown number format in `%.255s':\n" |
184 | "read " NUMBER_FMT "; expected " NUMBER_FMT, | 243 | " read " NUMBER_FMT "; expected " NUMBER_FMT, |
185 | zname(Z),f,tf); | 244 | ZNAME(Z),f,tf); |
186 | } | 245 | } |
187 | } | 246 | } |
188 | return native; | 247 | return native; |
@@ -203,7 +262,7 @@ Proto* luaU_undump1 (lua_State* L, ZIO* Z) | |||
203 | if (c==ID_CHUNK) | 262 | if (c==ID_CHUNK) |
204 | return LoadChunk(L,Z); | 263 | return LoadChunk(L,Z); |
205 | else if (c!=EOZ) | 264 | else if (c!=EOZ) |
206 | luaL_verror(L,"%.255s is not a Lua binary file",zname(Z)); | 265 | luaL_verror(L,"`%.255s' is not a Lua binary file",ZNAME(Z)); |
207 | return NULL; | 266 | return NULL; |
208 | } | 267 | } |
209 | 268 | ||
@@ -214,6 +273,6 @@ double luaU_str2d (lua_State* L, const char* b, const char* where) | |||
214 | { | 273 | { |
215 | double x; | 274 | double x; |
216 | if (!luaO_str2d(b,&x)) | 275 | if (!luaO_str2d(b,&x)) |
217 | luaL_verror(L,"cannot convert number '%.255s' in %.255s",b,where); | 276 | luaL_verror(L,"cannot convert number `%.255s' in `%.255s'",b,where); |
218 | return x; | 277 | return x; |
219 | } | 278 | } |