aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-30 17:29:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-30 17:29:34 -0300
commit7c9aee64c250e6f56b5788479d62ff9cbc6ad634 (patch)
tree7dde288ca7a62e06ec355ea4907ddb27ea94432a
parente0ff4e5d22bd2dbe74dd588f0710c18ae8a671ab (diff)
downloadlua-7c9aee64c250e6f56b5788479d62ff9cbc6ad634.tar.gz
lua-7c9aee64c250e6f56b5788479d62ff9cbc6ad634.tar.bz2
lua-7c9aee64c250e6f56b5788479d62ff9cbc6ad634.zip
new version by lhf.
-rw-r--r--lundump.c108
-rw-r--r--lundump.h96
2 files changed, 134 insertions, 70 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}
diff --git a/lundump.h b/lundump.h
index c9c4c417..6b3d1101 100644
--- a/lundump.h
+++ b/lundump.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.h,v 1.4 1998/06/25 16:48:44 roberto Exp roberto $ 2** $Id: lundump.h,v 1.13 1999/03/29 16:16:18 lhf Exp $
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*/
@@ -10,18 +10,47 @@
10#include "lobject.h" 10#include "lobject.h"
11#include "lzio.h" 11#include "lzio.h"
12 12
13TProtoFunc *luaU_undump1 (ZIO* Z); /* load one chunk */ 13/* -- start of user configuration ------------------------------------------ */
14 14
15#define SIGNATURE "Lua" 15/* LUA_NUMBER
16#define VERSION 0x31 /* last format change was in 3.1 */ 16* choose below the number representation in precompiled chunks by choosing an
17#define VERSION0 0x31 /* last major change was in 3.1 */ 17* an adequate definition for ID_NUMBER.
18* if you change LUA_NUM_TYPE, you must set ID_NUMBER accordingly.
19* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double.
20* if you want to use this default, do nothing.
21* if your machine does not use the IEEE 754 floating-point standard, use
22* ID_NATIVE, but precompiled chunks may not be portable to all architectures.
23*
24* for types other than the ones listed below, you'll have to write your own
25* dump and undump routines, specially if sizeof(long)!=4.
26*/
18 27
19#define IsMain(f) (f->lineDefined==0) 28/* choose one definition for ID_NUMBER and move it to after #endif */
29#if 0
30#define ID_NUMBER ID_INT4 /* 4-byte integers */
31#define ID_NUMBER ID_REAL4 /* 4-byte reals */
32#define ID_NUMBER ID_REAL8 /* 8-byte reals */
33#define ID_NUMBER ID_NATIVE /* whatever your machine uses */
34#endif
20 35
21#define ID_CHUNK 27 /* ESC */ 36/* format for numbers in listings and error messages */
22#define ID_NUM 'N' 37#ifndef NUMBER_FMT
23#define ID_STR 'S' 38#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
24#define ID_FUN 'F' 39#endif
40
41/* -- end of user configuration -- DO NOT CHANGE ANYTHING BELOW THIS LINE -- */
42
43
44TProtoFunc* luaU_undump1(ZIO* Z); /* load one chunk */
45void luaU_testnumber(void); /* test number representation */
46void luaU_badconstant(char* s, int i, TObject* o, TProtoFunc* tf);
47 /* handle cases that cannot happen */
48
49/* definitions for headers of binary files */
50#define VERSION 0x32 /* last format change was in 3.2 */
51#define VERSION0 0x32 /* last major change was in 3.2 */
52#define ID_CHUNK 27 /* binary files start with ESC... */
53#define SIGNATURE "Lua" /* ...followed by this signature */
25 54
26/* number representation */ 55/* number representation */
27#define ID_INT4 'l' /* 4-byte integers */ 56#define ID_INT4 'l' /* 4-byte integers */
@@ -29,53 +58,46 @@ TProtoFunc *luaU_undump1 (ZIO* Z); /* load one chunk */
29#define ID_REAL8 'd' /* 8-byte reals */ 58#define ID_REAL8 'd' /* 8-byte reals */
30#define ID_NATIVE '?' /* whatever your machine uses */ 59#define ID_NATIVE '?' /* whatever your machine uses */
31 60
32/* 61/* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double */
33* use a multiple of PI for testing number representation.
34* multiplying by 1E8 gives notrivial integer values.
35*/
36#define TEST_NUMBER 3.14159265358979323846E8
37
38/* LUA_NUMBER
39* choose one below for the number representation in precompiled chunks.
40* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double.
41* if your machine does not use IEEE 754, use ID_NATIVE.
42* the next version will support conversion to/from IEEE 754.
43*
44* if you change LUA_NUM_TYPE, make sure you set ID_NUMBER accordingly,
45* specially if sizeof(long)!=4.
46* for types other than the ones listed below, you'll have to write your own
47* dump and undump routines.
48*/
49
50#ifndef ID_NUMBER 62#ifndef ID_NUMBER
51#define ID_NUMBER ID_NATIVE 63#define ID_NUMBER ID_REAL8 /* 8-byte reals */
52#endif
53
54#if 0
55#define ID_NUMBER ID_INT4
56#define ID_NUMBER ID_REAL4
57#define ID_NUMBER ID_REAL8
58#define ID_NUMBER ID_NATIVE
59#endif 64#endif
60 65
61#endif 66/* a multiple of PI for testing number representation */
67/* multiplying by 1E8 gives non-trivial integer values */
68#define TEST_NUMBER 3.14159265358979323846E8
62 69
63#if ID_NUMBER==ID_REAL4 70#if ID_NUMBER==ID_REAL4
64 #define DumpNumber DumpFloat 71 #define DumpNumber DumpFloat
65 #define LoadNumber LoadFloat 72 #define LoadNumber LoadFloat
66 #define SIZEOF_NUMBER 4 73 #define SIZEOF_NUMBER 4
74 #define TYPEOF_NUMBER float
75 #define NAMEOF_NUMBER "float"
67#elif ID_NUMBER==ID_REAL8 76#elif ID_NUMBER==ID_REAL8
68 #define DumpNumber DumpDouble 77 #define DumpNumber DumpDouble
69 #define LoadNumber LoadDouble 78 #define LoadNumber LoadDouble
70 #define SIZEOF_NUMBER 8 79 #define SIZEOF_NUMBER 8
80 #define TYPEOF_NUMBER double
81 #define NAMEOF_NUMBER "double"
71#elif ID_NUMBER==ID_INT4 82#elif ID_NUMBER==ID_INT4
72 #define DumpNumber DumpLong 83 #define DumpNumber DumpLong
73 #define LoadNumber LoadLong 84 #define LoadNumber LoadLong
74 #define SIZEOF_NUMBER 4 85 #define SIZEOF_NUMBER 4
86 #define TYPEOF_NUMBER long
87 #define NAMEOF_NUMBER "long"
75#elif ID_NUMBER==ID_NATIVE 88#elif ID_NUMBER==ID_NATIVE
76 #define DumpNumber DumpNative 89 #define DumpNumber DumpNative
77 #define LoadNumber LoadNative 90 #define LoadNumber LoadNative
78 #define SIZEOF_NUMBER sizeof(real) 91 #define SIZEOF_NUMBER sizeof(real)
92 #define TYPEOF_NUMBER real
93 #define NAMEOF_NUMBER "native"
79#else 94#else
80 #error bad ID_NUMBER 95 #error bad ID_NUMBER
81#endif 96#endif
97
98/* formats for error messages */
99#define SOURCE "<%s:%d>"
100#define IN " in %p " SOURCE
101#define INLOC tf,tf->source->str,tf->lineDefined
102
103#endif