diff options
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 118 |
1 files changed, 48 insertions, 70 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 1.16 1999/12/02 19:11:51 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 1.26 2000/02/17 19:17:44 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 | */ |
@@ -50,22 +50,13 @@ static unsigned long LoadLong (lua_State* L, ZIO* Z) | |||
50 | return (hi<<16)|lo; | 50 | return (hi<<16)|lo; |
51 | } | 51 | } |
52 | 52 | ||
53 | static real LoadNumber (lua_State* L, ZIO* Z, int native) | 53 | static real LoadNumber (lua_State* L, ZIO* Z) |
54 | { | 54 | { |
55 | if (native) | 55 | char b[256]; |
56 | { | 56 | int size=ezgetc(L,Z); |
57 | real x; | 57 | LoadBlock(L,b,size,Z); |
58 | LoadBlock(L,&x,sizeof(x),Z); | 58 | b[size]=0; |
59 | return x; | 59 | return luaU_str2d(L,b,zname(Z)); |
60 | } | ||
61 | else | ||
62 | { | ||
63 | char b[256]; | ||
64 | int size=ezgetc(L,Z); | ||
65 | LoadBlock(L,b,size,Z); | ||
66 | b[size]=0; | ||
67 | return luaU_str2d(L,b,zname(Z)); | ||
68 | } | ||
69 | } | 60 | } |
70 | 61 | ||
71 | static int LoadInt (lua_State* L, ZIO* Z, const char* message) | 62 | static int LoadInt (lua_State* L, ZIO* Z, const char* message) |
@@ -76,19 +67,15 @@ static int LoadInt (lua_State* L, ZIO* Z, const char* message) | |||
76 | return i; | 67 | return i; |
77 | } | 68 | } |
78 | 69 | ||
79 | #define PAD 5 /* two word operands plus opcode */ | 70 | static void LoadCode (lua_State* L, TProtoFunc* tf, ZIO* Z) |
80 | |||
81 | static Byte* LoadCode (lua_State* L, ZIO* Z) | ||
82 | { | 71 | { |
83 | int size=LoadInt(L,Z,"code too long (%lu bytes) in %.255s"); | 72 | int size=LoadInt(L,Z,"code too long (%lu bytes) in %.255s"); |
84 | Byte* b=luaM_malloc(L,size+PAD); | 73 | tf->code=luaM_newvector(L,size,Instruction); |
85 | LoadBlock(L,b,size,Z); | 74 | LoadBlock(L,tf->code,size*sizeof(tf->code[0]),Z); |
86 | if (b[size-1]!=ENDCODE) luaL_verror(L,"bad code in %.255s",zname(Z)); | 75 | if (tf->code[size-1]!=ENDCODE) luaL_verror(L,"bad code in %.255s",zname(Z)); |
87 | memset(b+size,ENDCODE,PAD); /* pad code for safety */ | ||
88 | return b; | ||
89 | } | 76 | } |
90 | 77 | ||
91 | static TaggedString* LoadTString (lua_State* L, ZIO* Z) | 78 | static TaggedString* LoadString (lua_State* L, ZIO* Z) |
92 | { | 79 | { |
93 | long size=LoadLong(L,Z); | 80 | long size=LoadLong(L,Z); |
94 | if (size==0) | 81 | if (size==0) |
@@ -97,7 +84,7 @@ static TaggedString* LoadTString (lua_State* L, ZIO* Z) | |||
97 | { | 84 | { |
98 | char* s=luaL_openspace(L,size); | 85 | char* s=luaL_openspace(L,size); |
99 | LoadBlock(L,s,size,Z); | 86 | LoadBlock(L,s,size,Z); |
100 | return luaS_newlstr(L,s,size-1); | 87 | return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */ |
101 | } | 88 | } |
102 | } | 89 | } |
103 | 90 | ||
@@ -109,7 +96,7 @@ static void LoadLocals (lua_State* L, TProtoFunc* tf, ZIO* Z) | |||
109 | for (i=0; i<n; i++) | 96 | for (i=0; i<n; i++) |
110 | { | 97 | { |
111 | tf->locvars[i].line=LoadInt(L,Z,"too many lines (%lu) in %.255s"); | 98 | tf->locvars[i].line=LoadInt(L,Z,"too many lines (%lu) in %.255s"); |
112 | tf->locvars[i].varname=LoadTString(L,Z); | 99 | tf->locvars[i].varname=LoadString(L,Z); |
113 | } | 100 | } |
114 | tf->locvars[i].line=-1; /* flag end of vector */ | 101 | tf->locvars[i].line=-1; /* flag end of vector */ |
115 | tf->locvars[i].varname=NULL; | 102 | tf->locvars[i].varname=NULL; |
@@ -119,31 +106,27 @@ static TProtoFunc* LoadFunction (lua_State* L, ZIO* Z, int native); | |||
119 | 106 | ||
120 | static void LoadConstants (lua_State* L, TProtoFunc* tf, ZIO* Z, int native) | 107 | static void LoadConstants (lua_State* L, TProtoFunc* tf, ZIO* Z, int native) |
121 | { | 108 | { |
122 | int i,n=LoadInt(L,Z,"too many constants (%lu) in %.255s"); | 109 | int i,n; |
123 | tf->nconsts=n; | 110 | tf->nkstr=n=LoadInt(L,Z,"too many strings (%lu) in %.255s"); |
124 | if (n==0) return; | 111 | if (n>0) |
125 | tf->consts=luaM_newvector(L,n,TObject); | ||
126 | for (i=0; i<n; i++) | ||
127 | { | 112 | { |
128 | TObject* o=tf->consts+i; | 113 | tf->kstr=luaM_newvector(L,n,TaggedString*); |
129 | ttype(o)=-ezgetc(L,Z); /* ttype(o) is negative - ORDER LUA_T */ | 114 | for (i=0; i<n; i++) tf->kstr[i]=LoadString(L,Z); |
130 | switch (ttype(o)) | 115 | } |
131 | { | 116 | tf->nknum=n=LoadInt(L,Z,"too many numbers (%lu) in %.255s"); |
132 | case LUA_T_NUMBER: | 117 | if (n>0) |
133 | nvalue(o)=LoadNumber(L,Z,native); | 118 | { |
134 | break; | 119 | tf->knum=luaM_newvector(L,n,real); |
135 | case LUA_T_STRING: | 120 | if (native) |
136 | tsvalue(o)=LoadTString(L,Z); | 121 | LoadBlock(L,tf->knum,n*sizeof(tf->knum[0]),Z); |
137 | break; | 122 | else |
138 | case LUA_T_LPROTO: | 123 | for (i=0; i<n; i++) tf->knum[i]=LoadNumber(L,Z); |
139 | tfvalue(o)=LoadFunction(L,Z,native); | 124 | } |
140 | break; | 125 | tf->nkproto=n=LoadInt(L,Z,"too many functions (%lu) in %.255s"); |
141 | case LUA_T_NIL: | 126 | if (n>0) |
142 | break; | 127 | { |
143 | default: /* cannot happen */ | 128 | tf->kproto=luaM_newvector(L,n,TProtoFunc*); |
144 | luaU_badconstant(L,"load",i,o,tf); | 129 | for (i=0; i<n; i++) tf->kproto[i]=LoadFunction(L,Z,native); |
145 | break; | ||
146 | } | ||
147 | } | 130 | } |
148 | } | 131 | } |
149 | 132 | ||
@@ -151,9 +134,12 @@ static TProtoFunc* LoadFunction (lua_State* L, ZIO* Z, int native) | |||
151 | { | 134 | { |
152 | TProtoFunc* tf=luaF_newproto(L); | 135 | TProtoFunc* tf=luaF_newproto(L); |
153 | tf->lineDefined=LoadInt(L,Z,"lineDefined too large (%lu) in %.255s"); | 136 | tf->lineDefined=LoadInt(L,Z,"lineDefined too large (%lu) in %.255s"); |
154 | tf->source=LoadTString(L,Z); | 137 | tf->source=LoadString(L,Z); |
155 | if (tf->source==NULL) tf->source=luaS_new(L,zname(Z)); | 138 | if (tf->source==NULL) tf->source=luaS_new(L,zname(Z)); |
156 | tf->code=LoadCode(L,Z); | 139 | tf->numparams=LoadInt(L,Z,"numparams too large (%lu) in %.255s"); |
140 | tf->is_vararg=LoadInt(L,Z,"is_vararg too large (%lu) in %.255s"); | ||
141 | tf->maxstacksize=LoadInt(L,Z,"maxstacksize too large (%lu) in %.255s"); | ||
142 | LoadCode(L,tf,Z); | ||
157 | LoadLocals(L,tf,Z); | 143 | LoadLocals(L,tf,Z); |
158 | LoadConstants(L,tf,Z,native); | 144 | LoadConstants(L,tf,Z,native); |
159 | return tf; | 145 | return tf; |
@@ -167,6 +153,8 @@ static void LoadSignature (lua_State* L, ZIO* Z) | |||
167 | if (*s!=0) luaL_verror(L,"bad signature in %.255s",zname(Z)); | 153 | if (*s!=0) luaL_verror(L,"bad signature in %.255s",zname(Z)); |
168 | } | 154 | } |
169 | 155 | ||
156 | #define V(v) v/16,v%16 | ||
157 | |||
170 | static int LoadHeader (lua_State* L, ZIO* Z) | 158 | static int LoadHeader (lua_State* L, ZIO* Z) |
171 | { | 159 | { |
172 | int version,sizeofR,native; | 160 | int version,sizeofR,native; |
@@ -174,12 +162,12 @@ static int LoadHeader (lua_State* L, ZIO* Z) | |||
174 | version=ezgetc(L,Z); | 162 | version=ezgetc(L,Z); |
175 | if (version>VERSION) | 163 | if (version>VERSION) |
176 | luaL_verror(L, | 164 | luaL_verror(L, |
177 | "%.255s too new: version=0x%02x; expected at most 0x%02x", | 165 | "%.255s too new: its version is %d.%d; expected at most %d.%d", |
178 | zname(Z),version,VERSION); | 166 | zname(Z),V(version),V(VERSION)); |
179 | if (version<VERSION0) /* check last major change */ | 167 | if (version<VERSION0) /* check last major change */ |
180 | luaL_verror(L, | 168 | luaL_verror(L, |
181 | "%.255s too old: version=0x%02x; expected at least 0x%02x", | 169 | "%.255s too old: its version is %d.%d; expected at least %d.%d", |
182 | zname(Z),version,VERSION0); | 170 | zname(Z),V(version),V(VERSION)); |
183 | sizeofR=ezgetc(L,Z); | 171 | sizeofR=ezgetc(L,Z); |
184 | native=(sizeofR!=0); | 172 | native=(sizeofR!=0); |
185 | if (native) /* test number representation */ | 173 | if (native) /* test number representation */ |
@@ -189,9 +177,9 @@ static int LoadHeader (lua_State* L, ZIO* Z) | |||
189 | zname(Z),sizeofR,(int)sizeof(real)); | 177 | zname(Z),sizeofR,(int)sizeof(real)); |
190 | else | 178 | else |
191 | { | 179 | { |
192 | real tf=TEST_NUMBER; | 180 | real f=0,tf=TEST_NUMBER; |
193 | real f=LoadNumber(L,Z,native); | 181 | LoadBlock(L,&f,sizeof(f),Z); |
194 | if ((long)f!=(long)tf) | 182 | if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */ |
195 | luaL_verror(L,"unknown number format in %.255s: " | 183 | luaL_verror(L,"unknown number format in %.255s: " |
196 | "read " NUMBER_FMT "; expected " NUMBER_FMT, | 184 | "read " NUMBER_FMT "; expected " NUMBER_FMT, |
197 | zname(Z),f,tf); | 185 | zname(Z),f,tf); |
@@ -220,16 +208,6 @@ TProtoFunc* luaU_undump1 (lua_State* L, ZIO* Z) | |||
220 | } | 208 | } |
221 | 209 | ||
222 | /* | 210 | /* |
223 | * handle constants that cannot happen | ||
224 | */ | ||
225 | void luaU_badconstant (lua_State* L, const char* s, int i, const TObject* o, const TProtoFunc* tf) | ||
226 | { | ||
227 | int t=ttype(o); | ||
228 | const char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t]; | ||
229 | luaL_verror(L,"cannot %.255s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * convert number from text | 211 | * convert number from text |
234 | */ | 212 | */ |
235 | double luaU_str2d (lua_State* L, const char* b, const char* where) | 213 | double luaU_str2d (lua_State* L, const char* b, const char* where) |