aboutsummaryrefslogtreecommitdiff
path: root/lundump.c
diff options
context:
space:
mode:
Diffstat (limited to 'lundump.c')
-rw-r--r--lundump.c108
1 files changed, 75 insertions, 33 deletions
diff --git a/lundump.c b/lundump.c
index 941f8ae8..a0079e26 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,13 +1,15 @@
1/* 1/*
2** $Id: lundump.c,v 1.6 1998/12/27 20:23:22 roberto Exp roberto $ 2** $Id: lundump.c,v 1.17 1999/03/29 16:16:18 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*/
6 6
7#include <stdio.h> 7#include <stdio.h>
8#include <string.h>
8#include "lauxlib.h" 9#include "lauxlib.h"
9#include "lfunc.h" 10#include "lfunc.h"
10#include "lmem.h" 11#include "lmem.h"
12#include "lopcodes.h"
11#include "lstring.h" 13#include "lstring.h"
12#include "lundump.h" 14#include "lundump.h"
13 15
@@ -52,19 +54,18 @@ static unsigned long LoadLong (ZIO* Z)
52 return (hi<<16)|lo; 54 return (hi<<16)|lo;
53} 55}
54 56
55#if ID_NUMBER==ID_REAL4 57#if ID_NUMBER==ID_REAL4 /* LUA_NUMBER */
56/* LUA_NUMBER */
57/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */ 58/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
58static float LoadFloat (ZIO* Z) 59static float LoadFloat (ZIO* Z)
59{ 60{
60 unsigned long l=LoadLong(Z); 61 unsigned long l=LoadLong(Z);
61 float f=*(float*)&l; 62 float f;
63 memcpy(&f,&l,sizeof(f));
62 return f; 64 return f;
63} 65}
64#endif 66#endif
65 67
66#if ID_NUMBER==ID_REAL8 68#if ID_NUMBER==ID_REAL8 /* LUA_NUMBER */
67/* LUA_NUMBER */
68/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */ 69/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
69static double LoadDouble (ZIO* Z) 70static double LoadDouble (ZIO* Z)
70{ 71{
@@ -81,25 +82,34 @@ static double LoadDouble (ZIO* Z)
81 l[0]=LoadLong(Z); 82 l[0]=LoadLong(Z);
82 l[1]=LoadLong(Z); 83 l[1]=LoadLong(Z);
83 } 84 }
84 f=*(double*)l; 85 memcpy(&f,l,sizeof(f));
85 return f; 86 return f;
86} 87}
87#endif 88#endif
88 89
90static int LoadInt (ZIO* Z, char* message)
91{
92 unsigned long l=LoadLong(Z);
93 unsigned int i=l;
94 if (i!=l) luaL_verror(message,l,zname(Z));
95 return i;
96}
97
98#define PAD 5 /* two word operands plus opcode */
99
89static Byte* LoadCode (ZIO* Z) 100static Byte* LoadCode (ZIO* Z)
90{ 101{
91 unsigned long size=LoadLong(Z); 102 int size=LoadInt(Z,"code too long (%ld bytes) in %s");
92 unsigned int s=size; 103 Byte* b=luaM_malloc(size+PAD);
93 void* b;
94 if (s!=size) luaL_verror("code too long (%ld bytes) in %s",size,zname(Z));
95 b=luaM_malloc(size);
96 LoadBlock(b,size,Z); 104 LoadBlock(b,size,Z);
105 if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
106 memset(b+size,ENDCODE,PAD); /* pad for safety */
97 return b; 107 return b;
98} 108}
99 109
100static TaggedString* LoadTString (ZIO* Z) 110static TaggedString* LoadTString (ZIO* Z)
101{ 111{
102 int size=LoadWord(Z); 112 long size=LoadLong(Z);
103 if (size==0) 113 if (size==0)
104 return NULL; 114 return NULL;
105 else 115 else
@@ -112,46 +122,45 @@ static TaggedString* LoadTString (ZIO* Z)
112 122
113static void LoadLocals (TProtoFunc* tf, ZIO* Z) 123static void LoadLocals (TProtoFunc* tf, ZIO* Z)
114{ 124{
115 int i,n=LoadWord(Z); 125 int i,n=LoadInt(Z,"too many locals (%ld) in %s");
116 if (n==0) return; 126 if (n==0) return;
117 tf->locvars=luaM_newvector(n+1,LocVar); 127 tf->locvars=luaM_newvector(n+1,LocVar);
118 for (i=0; i<n; i++) 128 for (i=0; i<n; i++)
119 { 129 {
120 tf->locvars[i].line=LoadWord(Z); 130 tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
121 tf->locvars[i].varname=LoadTString(Z); 131 tf->locvars[i].varname=LoadTString(Z);
122 } 132 }
123 tf->locvars[i].line=-1; /* flag end of vector */ 133 tf->locvars[i].line=-1; /* flag end of vector */
124 tf->locvars[i].varname=NULL; 134 tf->locvars[i].varname=NULL;
125} 135}
126 136
127static TProtoFunc* LoadFunction (ZIO* Z); 137static TProtoFunc* LoadFunction(ZIO* Z);
128 138
129static void LoadConstants (TProtoFunc* tf, ZIO* Z) 139static void LoadConstants (TProtoFunc* tf, ZIO* Z)
130{ 140{
131 int i,n=LoadWord(Z); 141 int i,n=LoadInt(Z,"too many constants (%ld) in %s");
132 tf->nconsts=n; 142 tf->nconsts=n;
133 if (n==0) return; 143 if (n==0) return;
134 tf->consts=luaM_newvector(n,TObject); 144 tf->consts=luaM_newvector(n,TObject);
135 for (i=0; i<n; i++) 145 for (i=0; i<n; i++)
136 { 146 {
137 TObject* o=tf->consts+i; 147 TObject* o=tf->consts+i;
138 int c=ezgetc(Z); 148 ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
139 switch (c) 149 switch (ttype(o))
140 { 150 {
141 case ID_NUM: 151 case LUA_T_NUMBER:
142 ttype(o)=LUA_T_NUMBER;
143 doLoadNumber(nvalue(o),Z); 152 doLoadNumber(nvalue(o),Z);
144 break; 153 break;
145 case ID_STR: 154 case LUA_T_STRING:
146 ttype(o)=LUA_T_STRING;
147 tsvalue(o)=LoadTString(Z); 155 tsvalue(o)=LoadTString(Z);
148 break; 156 break;
149 case ID_FUN: 157 case LUA_T_PROTO:
150 ttype(o)=LUA_T_PROTO;
151 tfvalue(o)=LoadFunction(Z); 158 tfvalue(o)=LoadFunction(Z);
152 break; 159 break;
153 default: 160 case LUA_T_NIL:
154 luaL_verror("bad constant #%d in %s: type=%d ('%c')",i,zname(Z),c,c); 161 break;
162 default: /* cannot happen */
163 luaU_badconstant("load",i,o,tf);
155 break; 164 break;
156 } 165 }
157 } 166 }
@@ -160,8 +169,9 @@ static void LoadConstants (TProtoFunc* tf, ZIO* Z)
160static TProtoFunc* LoadFunction (ZIO* Z) 169static TProtoFunc* LoadFunction (ZIO* Z)
161{ 170{
162 TProtoFunc* tf=luaF_newproto(); 171 TProtoFunc* tf=luaF_newproto();
163 tf->lineDefined=LoadWord(Z); 172 tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
164 tf->source=LoadTString(Z); 173 tf->source=LoadTString(Z);
174 if (tf->source==NULL) tf->source=luaS_new(zname(Z));
165 tf->code=LoadCode(Z); 175 tf->code=LoadCode(Z);
166 LoadLocals(tf,Z); 176 LoadLocals(tf,Z);
167 LoadConstants(tf,Z); 177 LoadConstants(tf,Z);
@@ -180,6 +190,7 @@ static void LoadHeader (ZIO* Z)
180{ 190{
181 int version,id,sizeofR; 191 int version,id,sizeofR;
182 real f=-TEST_NUMBER,tf=TEST_NUMBER; 192 real f=-TEST_NUMBER,tf=TEST_NUMBER;
193 luaU_testnumber();
183 LoadSignature(Z); 194 LoadSignature(Z);
184 version=ezgetc(Z); 195 version=ezgetc(Z);
185 if (version>VERSION) 196 if (version>VERSION)
@@ -193,15 +204,14 @@ static void LoadHeader (ZIO* Z)
193 id=ezgetc(Z); /* test number representation */ 204 id=ezgetc(Z); /* test number representation */
194 sizeofR=ezgetc(Z); 205 sizeofR=ezgetc(Z);
195 if (id!=ID_NUMBER || sizeofR!=sizeof(real)) 206 if (id!=ID_NUMBER || sizeofR!=sizeof(real))
196 {
197 luaL_verror("unknown number signature in %s: " 207 luaL_verror("unknown number signature in %s: "
198 "read 0x%02x%02x; expected 0x%02x%02x", 208 "read 0x%02x%02x; expected 0x%02x%02x",
199 zname(Z),id,sizeofR,ID_NUMBER,sizeof(real)); 209 zname(Z),id,sizeofR,ID_NUMBER,sizeof(real));
200 }
201 doLoadNumber(f,Z); 210 doLoadNumber(f,Z);
202 if (f!=tf) 211 if (f!=tf)
203 luaL_verror("unknown number representation in %s: read %g; expected %g", 212 luaL_verror("unknown number representation in %s: "
204 zname(Z),(double)f,(double)tf); /* LUA_NUMBER */ 213 "read " NUMBER_FMT "; expected " NUMBER_FMT,
214 zname(Z),f,tf);
205} 215}
206 216
207static TProtoFunc* LoadChunk (ZIO* Z) 217static TProtoFunc* LoadChunk (ZIO* Z)
@@ -214,7 +224,7 @@ static TProtoFunc* LoadChunk (ZIO* Z)
214** load one chunk from a file or buffer 224** load one chunk from a file or buffer
215** return main if ok and NULL at EOF 225** return main if ok and NULL at EOF
216*/ 226*/
217TProtoFunc* luaU_undump1 (ZIO* Z) 227TProtoFunc* luaU_undump1(ZIO* Z)
218{ 228{
219 int c=zgetc(Z); 229 int c=zgetc(Z);
220 if (c==ID_CHUNK) 230 if (c==ID_CHUNK)
@@ -223,3 +233,35 @@ TProtoFunc* luaU_undump1 (ZIO* Z)
223 luaL_verror("%s is not a Lua binary file",zname(Z)); 233 luaL_verror("%s is not a Lua binary file",zname(Z));
224 return NULL; 234 return NULL;
225} 235}
236
237/*
238** test number representation
239*/
240void luaU_testnumber(void)
241{
242 if (sizeof(real)!=SIZEOF_NUMBER)
243 luaL_verror("numbers have %d bytes; expected %d. see lundump.h",
244 (int)sizeof(real),SIZEOF_NUMBER);
245#if ID_NUMBER==ID_REAL4 || ID_NUMBER==ID_REAL8
246 if (sizeof(long)!=4)
247 luaL_verror("longs have %d bytes; expected %d. see lundump.h",
248 (int)sizeof(long),4);
249#endif
250 {
251 real t=TEST_NUMBER;
252 TYPEOF_NUMBER v=TEST_NUMBER;
253 if (t!=v)
254 luaL_verror("unsupported number type; expected %d-byte " NAMEOF_NUMBER "."
255 " see config and lundump.h",SIZEOF_NUMBER);
256 }
257}
258
259/*
260* handle constants that cannot happen
261*/
262void luaU_badconstant(char* s, int i, TObject* o, TProtoFunc* tf)
263{
264 int t=ttype(o);
265 char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
266 luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
267}