diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-22 11:12:07 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-22 11:12:07 -0200 |
commit | 29ede6aa13144ff7b69c57a87be1ee93f57ae896 (patch) | |
tree | adcfb5dcff7db55481cd675349e23dec0e63c939 /lundump.c | |
parent | 951897c09319ae5474a4b86bb7d615136577caa0 (diff) | |
download | lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.gz lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.bz2 lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.zip |
first implementation of multiple states (reentrant code).
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 152 |
1 files changed, 77 insertions, 75 deletions
@@ -1,9 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 1.13 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 1.14 1999/09/06 13:55:09 roberto Exp roberto $ |
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 | */ |
6 | 6 | ||
7 | #define LUA_REENTRANT | ||
8 | |||
7 | #include <stdio.h> | 9 | #include <stdio.h> |
8 | #include <string.h> | 10 | #include <string.h> |
9 | #include "lauxlib.h" | 11 | #include "lauxlib.h" |
@@ -13,195 +15,195 @@ | |||
13 | #include "lstring.h" | 15 | #include "lstring.h" |
14 | #include "lundump.h" | 16 | #include "lundump.h" |
15 | 17 | ||
16 | #define LoadBlock(b,size,Z) ezread(Z,b,size) | 18 | #define LoadBlock(L, b,size,Z) ezread(L, Z,b,size) |
17 | 19 | ||
18 | static void unexpectedEOZ (ZIO* Z) | 20 | static void unexpectedEOZ (lua_State *L, ZIO* Z) |
19 | { | 21 | { |
20 | luaL_verror("unexpected end of file in %s",zname(Z)); | 22 | luaL_verror(L, "unexpected end of file in %s",zname(Z)); |
21 | } | 23 | } |
22 | 24 | ||
23 | static int ezgetc (ZIO* Z) | 25 | static int ezgetc (lua_State *L, ZIO* Z) |
24 | { | 26 | { |
25 | int c=zgetc(Z); | 27 | int c=zgetc(Z); |
26 | if (c==EOZ) unexpectedEOZ(Z); | 28 | if (c==EOZ) unexpectedEOZ(L, Z); |
27 | return c; | 29 | return c; |
28 | } | 30 | } |
29 | 31 | ||
30 | static void ezread (ZIO* Z, void* b, int n) | 32 | static void ezread (lua_State *L, ZIO* Z, void* b, int n) |
31 | { | 33 | { |
32 | int r=zread(Z,b,n); | 34 | int r=zread(Z,b,n); |
33 | if (r!=0) unexpectedEOZ(Z); | 35 | if (r!=0) unexpectedEOZ(L, Z); |
34 | } | 36 | } |
35 | 37 | ||
36 | static unsigned int LoadWord (ZIO* Z) | 38 | static unsigned int LoadWord (lua_State *L, ZIO* Z) |
37 | { | 39 | { |
38 | unsigned int hi=ezgetc(Z); | 40 | unsigned int hi=ezgetc(L, Z); |
39 | unsigned int lo=ezgetc(Z); | 41 | unsigned int lo=ezgetc(L, Z); |
40 | return (hi<<8)|lo; | 42 | return (hi<<8)|lo; |
41 | } | 43 | } |
42 | 44 | ||
43 | static unsigned long LoadLong (ZIO* Z) | 45 | static unsigned long LoadLong (lua_State *L, ZIO* Z) |
44 | { | 46 | { |
45 | unsigned long hi=LoadWord(Z); | 47 | unsigned long hi=LoadWord(L, Z); |
46 | unsigned long lo=LoadWord(Z); | 48 | unsigned long lo=LoadWord(L, Z); |
47 | return (hi<<16)|lo; | 49 | return (hi<<16)|lo; |
48 | } | 50 | } |
49 | 51 | ||
50 | /* | 52 | /* |
51 | * convert number from text | 53 | * convert number from text |
52 | */ | 54 | */ |
53 | real luaU_str2d (const char* b, const char* where) | 55 | real luaU_str2d (lua_State *L, const char* b, const char* where) |
54 | { | 56 | { |
55 | real x; | 57 | real x; |
56 | if (!luaO_str2d(b, &x)) | 58 | if (!luaO_str2d(b, &x)) |
57 | luaL_verror("cannot convert number '%s' in %s",b,where); | 59 | luaL_verror(L, "cannot convert number '%s' in %s",b,where); |
58 | return x; | 60 | return x; |
59 | } | 61 | } |
60 | 62 | ||
61 | static real LoadNumber (ZIO* Z, int native) | 63 | static real LoadNumber (lua_State *L, ZIO* Z, int native) |
62 | { | 64 | { |
63 | real x; | 65 | real x; |
64 | if (native) | 66 | if (native) |
65 | { | 67 | { |
66 | LoadBlock(&x,sizeof(x),Z); | 68 | LoadBlock(L, &x,sizeof(x),Z); |
67 | return x; | 69 | return x; |
68 | } | 70 | } |
69 | else | 71 | else |
70 | { | 72 | { |
71 | char b[256]; | 73 | char b[256]; |
72 | int size=ezgetc(Z); | 74 | int size=ezgetc(L, Z); |
73 | LoadBlock(b,size,Z); | 75 | LoadBlock(L, b,size,Z); |
74 | b[size]=0; | 76 | b[size]=0; |
75 | return luaU_str2d(b,zname(Z)); | 77 | return luaU_str2d(L, b,zname(Z)); |
76 | } | 78 | } |
77 | } | 79 | } |
78 | 80 | ||
79 | static int LoadInt (ZIO* Z, const char* message) | 81 | static int LoadInt (lua_State *L, ZIO* Z, const char* message) |
80 | { | 82 | { |
81 | unsigned long l=LoadLong(Z); | 83 | unsigned long l=LoadLong(L, Z); |
82 | unsigned int i=l; | 84 | unsigned int i=l; |
83 | if (i!=l) luaL_verror(message,l,zname(Z)); | 85 | if (i!=l) luaL_verror(L, message,l,zname(Z)); |
84 | return i; | 86 | return i; |
85 | } | 87 | } |
86 | 88 | ||
87 | #define PAD 5 /* two word operands plus opcode */ | 89 | #define PAD 5 /* two word operands plus opcode */ |
88 | 90 | ||
89 | static Byte* LoadCode (ZIO* Z) | 91 | static Byte* LoadCode (lua_State *L, ZIO* Z) |
90 | { | 92 | { |
91 | int size=LoadInt(Z,"code too long (%ld bytes) in %s"); | 93 | int size=LoadInt(L, Z,"code too long (%ld bytes) in %s"); |
92 | Byte* b=luaM_malloc(size+PAD); | 94 | Byte* b=luaM_malloc(L, size+PAD); |
93 | LoadBlock(b,size,Z); | 95 | LoadBlock(L, b,size,Z); |
94 | if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z)); | 96 | if (b[size-1]!=ENDCODE) luaL_verror(L, "bad code in %s",zname(Z)); |
95 | memset(b+size,ENDCODE,PAD); /* pad code for safety */ | 97 | memset(b+size,ENDCODE,PAD); /* pad code for safety */ |
96 | return b; | 98 | return b; |
97 | } | 99 | } |
98 | 100 | ||
99 | static TaggedString* LoadTString (ZIO* Z) | 101 | static TaggedString* LoadTString (lua_State *L, ZIO* Z) |
100 | { | 102 | { |
101 | long size=LoadLong(Z); | 103 | long size=LoadLong(L, Z); |
102 | if (size==0) | 104 | if (size==0) |
103 | return NULL; | 105 | return NULL; |
104 | else | 106 | else |
105 | { | 107 | { |
106 | char* s=luaL_openspace(size); | 108 | char* s=luaL_openspace(L, size); |
107 | LoadBlock(s,size,Z); | 109 | LoadBlock(L, s,size,Z); |
108 | return luaS_newlstr(s,size-1); | 110 | return luaS_newlstr(L, s,size-1); |
109 | } | 111 | } |
110 | } | 112 | } |
111 | 113 | ||
112 | static void LoadLocals (TProtoFunc* tf, ZIO* Z) | 114 | static void LoadLocals (lua_State *L, TProtoFunc* tf, ZIO* Z) |
113 | { | 115 | { |
114 | int i,n=LoadInt(Z,"too many locals (%ld) in %s"); | 116 | int i,n=LoadInt(L, Z,"too many locals (%ld) in %s"); |
115 | if (n==0) return; | 117 | if (n==0) return; |
116 | tf->locvars=luaM_newvector(n+1,LocVar); | 118 | tf->locvars=luaM_newvector(L, n+1,LocVar); |
117 | for (i=0; i<n; i++) | 119 | for (i=0; i<n; i++) |
118 | { | 120 | { |
119 | tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s"); | 121 | tf->locvars[i].line=LoadInt(L, Z,"too many lines (%ld) in %s"); |
120 | tf->locvars[i].varname=LoadTString(Z); | 122 | tf->locvars[i].varname=LoadTString(L, Z); |
121 | } | 123 | } |
122 | tf->locvars[i].line=-1; /* flag end of vector */ | 124 | tf->locvars[i].line=-1; /* flag end of vector */ |
123 | tf->locvars[i].varname=NULL; | 125 | tf->locvars[i].varname=NULL; |
124 | } | 126 | } |
125 | 127 | ||
126 | static TProtoFunc* LoadFunction (ZIO* Z, int native); | 128 | static TProtoFunc* LoadFunction (lua_State *L, ZIO* Z, int native); |
127 | 129 | ||
128 | static void LoadConstants (TProtoFunc* tf, ZIO* Z, int native) | 130 | static void LoadConstants (lua_State *L, TProtoFunc* tf, ZIO* Z, int native) |
129 | { | 131 | { |
130 | int i,n=LoadInt(Z,"too many constants (%ld) in %s"); | 132 | int i,n=LoadInt(L, Z,"too many constants (%ld) in %s"); |
131 | tf->nconsts=n; | 133 | tf->nconsts=n; |
132 | if (n==0) return; | 134 | if (n==0) return; |
133 | tf->consts=luaM_newvector(n,TObject); | 135 | tf->consts=luaM_newvector(L, n,TObject); |
134 | for (i=0; i<n; i++) | 136 | for (i=0; i<n; i++) |
135 | { | 137 | { |
136 | TObject* o=tf->consts+i; | 138 | TObject* o=tf->consts+i; |
137 | ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */ | 139 | ttype(o)=-ezgetc(L, Z); /* ttype(o) is negative - ORDER LUA_T */ |
138 | switch (ttype(o)) | 140 | switch (ttype(o)) |
139 | { | 141 | { |
140 | case LUA_T_NUMBER: | 142 | case LUA_T_NUMBER: |
141 | nvalue(o)=LoadNumber(Z,native); | 143 | nvalue(o)=LoadNumber(L, Z,native); |
142 | break; | 144 | break; |
143 | case LUA_T_STRING: | 145 | case LUA_T_STRING: |
144 | tsvalue(o)=LoadTString(Z); | 146 | tsvalue(o)=LoadTString(L, Z); |
145 | break; | 147 | break; |
146 | case LUA_T_PROTO: | 148 | case LUA_T_PROTO: |
147 | tfvalue(o)=LoadFunction(Z,native); | 149 | tfvalue(o)=LoadFunction(L, Z,native); |
148 | break; | 150 | break; |
149 | case LUA_T_NIL: | 151 | case LUA_T_NIL: |
150 | break; | 152 | break; |
151 | default: /* cannot happen */ | 153 | default: /* cannot happen */ |
152 | luaU_badconstant("load",i,o,tf); | 154 | luaU_badconstant(L, "load",i,o,tf); |
153 | break; | 155 | break; |
154 | } | 156 | } |
155 | } | 157 | } |
156 | } | 158 | } |
157 | 159 | ||
158 | static TProtoFunc* LoadFunction (ZIO* Z, int native) | 160 | static TProtoFunc* LoadFunction (lua_State *L, ZIO* Z, int native) |
159 | { | 161 | { |
160 | TProtoFunc* tf=luaF_newproto(); | 162 | TProtoFunc* tf=luaF_newproto(L); |
161 | tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s"); | 163 | tf->lineDefined=LoadInt(L, Z,"lineDefined too large (%ld) in %s"); |
162 | tf->source=LoadTString(Z); | 164 | tf->source=LoadTString(L, Z); |
163 | if (tf->source==NULL) tf->source=luaS_new(zname(Z)); | 165 | if (tf->source==NULL) tf->source=luaS_new(L, zname(Z)); |
164 | tf->code=LoadCode(Z); | 166 | tf->code=LoadCode(L, Z); |
165 | LoadLocals(tf,Z); | 167 | LoadLocals(L, tf,Z); |
166 | LoadConstants(tf,Z,native); | 168 | LoadConstants(L, tf,Z,native); |
167 | return tf; | 169 | return tf; |
168 | } | 170 | } |
169 | 171 | ||
170 | static void LoadSignature (ZIO* Z) | 172 | static void LoadSignature (lua_State *L, ZIO* Z) |
171 | { | 173 | { |
172 | const char* s=SIGNATURE; | 174 | const char* s=SIGNATURE; |
173 | while (*s!=0 && ezgetc(Z)==*s) | 175 | while (*s!=0 && ezgetc(L, Z)==*s) |
174 | ++s; | 176 | ++s; |
175 | if (*s!=0) luaL_verror("bad signature in %s",zname(Z)); | 177 | if (*s!=0) luaL_verror(L, "bad signature in %s",zname(Z)); |
176 | } | 178 | } |
177 | 179 | ||
178 | static int LoadHeader (ZIO* Z) | 180 | static int LoadHeader (lua_State *L, ZIO* Z) |
179 | { | 181 | { |
180 | int version,sizeofR; | 182 | int version,sizeofR; |
181 | int native; | 183 | int native; |
182 | LoadSignature(Z); | 184 | LoadSignature(L, Z); |
183 | version=ezgetc(Z); | 185 | version=ezgetc(L, Z); |
184 | if (version>VERSION) | 186 | if (version>VERSION) |
185 | luaL_verror( | 187 | luaL_verror(L, |
186 | "%s too new: version=0x%02x; expected at most 0x%02x", | 188 | "%s too new: version=0x%02x; expected at most 0x%02x", |
187 | zname(Z),version,VERSION); | 189 | zname(Z),version,VERSION); |
188 | if (version<VERSION0) /* check last major change */ | 190 | if (version<VERSION0) /* check last major change */ |
189 | luaL_verror( | 191 | luaL_verror(L, |
190 | "%s too old: version=0x%02x; expected at least 0x%02x", | 192 | "%s too old: version=0x%02x; expected at least 0x%02x", |
191 | zname(Z),version,VERSION0); | 193 | zname(Z),version,VERSION0); |
192 | sizeofR=ezgetc(Z); | 194 | sizeofR=ezgetc(L, Z); |
193 | native=(sizeofR!=0); | 195 | native=(sizeofR!=0); |
194 | if (native) /* test number representation */ | 196 | if (native) /* test number representation */ |
195 | { | 197 | { |
196 | if (sizeofR!=sizeof(real)) | 198 | if (sizeofR!=sizeof(real)) |
197 | luaL_verror("unknown number size in %s: read %d; expected %d", | 199 | luaL_verror(L, "unknown number size in %s: read %d; expected %d", |
198 | zname(Z),sizeofR,sizeof(real)); | 200 | zname(Z),sizeofR,sizeof(real)); |
199 | else | 201 | else |
200 | { | 202 | { |
201 | real tf=TEST_NUMBER; | 203 | real tf=TEST_NUMBER; |
202 | real f=LoadNumber(Z,native); | 204 | real f=LoadNumber(L, Z,native); |
203 | if ((long)f!=(long)tf) | 205 | if ((long)f!=(long)tf) |
204 | luaL_verror("unknown number format in %s: " | 206 | luaL_verror(L, "unknown number format in %s: " |
205 | "read " NUMBER_FMT "; expected " NUMBER_FMT, | 207 | "read " NUMBER_FMT "; expected " NUMBER_FMT, |
206 | zname(Z),f,tf); | 208 | zname(Z),f,tf); |
207 | } | 209 | } |
@@ -209,31 +211,31 @@ static int LoadHeader (ZIO* Z) | |||
209 | return native; | 211 | return native; |
210 | } | 212 | } |
211 | 213 | ||
212 | static TProtoFunc* LoadChunk (ZIO* Z) | 214 | static TProtoFunc* LoadChunk (lua_State *L, ZIO* Z) |
213 | { | 215 | { |
214 | return LoadFunction(Z,LoadHeader(Z)); | 216 | return LoadFunction(L, Z,LoadHeader(L, Z)); |
215 | } | 217 | } |
216 | 218 | ||
217 | /* | 219 | /* |
218 | ** load one chunk from a file or buffer | 220 | ** load one chunk from a file or buffer |
219 | ** return main if ok and NULL at EOF | 221 | ** return main if ok and NULL at EOF |
220 | */ | 222 | */ |
221 | TProtoFunc* luaU_undump1 (ZIO* Z) | 223 | TProtoFunc* luaU_undump1 (lua_State *L, ZIO* Z) |
222 | { | 224 | { |
223 | int c=zgetc(Z); | 225 | int c=zgetc(Z); |
224 | if (c==ID_CHUNK) | 226 | if (c==ID_CHUNK) |
225 | return LoadChunk(Z); | 227 | return LoadChunk(L, Z); |
226 | else if (c!=EOZ) | 228 | else if (c!=EOZ) |
227 | luaL_verror("%s is not a Lua binary file",zname(Z)); | 229 | luaL_verror(L, "%s is not a Lua binary file",zname(Z)); |
228 | return NULL; | 230 | return NULL; |
229 | } | 231 | } |
230 | 232 | ||
231 | /* | 233 | /* |
232 | * handle constants that cannot happen | 234 | * handle constants that cannot happen |
233 | */ | 235 | */ |
234 | void luaU_badconstant (const char* s, int i, const TObject* o, TProtoFunc* tf) | 236 | void luaU_badconstant (lua_State *L, const char* s, int i, const TObject* o, TProtoFunc* tf) |
235 | { | 237 | { |
236 | int t=ttype(o); | 238 | int t=ttype(o); |
237 | const char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t]; | 239 | const char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t]; |
238 | luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC); | 240 | luaL_verror(L, "cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC); |
239 | } | 241 | } |