summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-04-13 17:16:37 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-04-13 17:16:37 -0300
commitb4ad600b933b51701ac0556fa353b43d9bc69854 (patch)
tree4190604e17161e7f6def8c3d585cd267b39ce271
parentcb7f027380b9eebcf7ce2c00c6e1c5450d53b47a (diff)
downloadlua-b4ad600b933b51701ac0556fa353b43d9bc69854.tar.gz
lua-b4ad600b933b51701ac0556fa353b43d9bc69854.tar.bz2
lua-b4ad600b933b51701ac0556fa353b43d9bc69854.zip
numbers are stored in ascii format for better portability and simplicity
-rw-r--r--lundump.c101
-rw-r--r--lundump.h91
2 files changed, 52 insertions, 140 deletions
diff --git a/lundump.c b/lundump.c
index 8fd8f1d0..5e8ca893 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.8 1999/03/30 20:29:34 roberto Exp roberto $ 2** $Id: lundump.c,v 1.18 1999/04/09 03:10:40 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*/
@@ -14,12 +14,11 @@
14#include "lundump.h" 14#include "lundump.h"
15 15
16#define LoadBlock(b,size,Z) ezread(Z,b,size) 16#define LoadBlock(b,size,Z) ezread(Z,b,size)
17#define LoadNative(t,Z) LoadBlock(&t,sizeof(t),Z)
18 17
19#if ID_NUMBER==ID_NATIVE 18#if LUAC_NATIVE
20 #define doLoadNumber(f,Z) LoadNative(f,Z) 19 #define doLoadNumber(x,Z) LoadBlock(&x,sizeof(x),Z)
21#else 20#else
22 #define doLoadNumber(f,Z) f=LoadNumber(Z) 21 #define doLoadNumber(x,Z) x=LoadNumber(Z)
23#endif 22#endif
24 23
25static void unexpectedEOZ (ZIO* Z) 24static void unexpectedEOZ (ZIO* Z)
@@ -54,38 +53,17 @@ static unsigned long LoadLong (ZIO* Z)
54 return (hi<<16)|lo; 53 return (hi<<16)|lo;
55} 54}
56 55
57#if ID_NUMBER==ID_REAL4 /* LUA_NUMBER */ 56static real LoadNumber (ZIO* Z)
58/* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
59static float LoadFloat (ZIO* Z)
60{ 57{
61 unsigned long l=LoadLong(Z); 58 char b[256];
62 float f; 59 int size=ezgetc(Z);
63 memcpy(&f,&l,sizeof(f)); 60 LoadBlock(b,size,Z);
64 return f; 61 b[size]=0;
65} 62 if (b[0]=='-')
66#endif 63 return -luaO_str2d(b+1);
67 64 else
68#if ID_NUMBER==ID_REAL8 /* LUA_NUMBER */ 65 return luaO_str2d(b);
69/* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
70static double LoadDouble (ZIO* Z)
71{
72 unsigned long l[2];
73 double f;
74 int x=1;
75 if (*(char*)&x==1) /* little-endian */
76 {
77 l[1]=LoadLong(Z);
78 l[0]=LoadLong(Z);
79 }
80 else /* big-endian */
81 {
82 l[0]=LoadLong(Z);
83 l[1]=LoadLong(Z);
84 }
85 memcpy(&f,l,sizeof(f));
86 return f;
87} 66}
88#endif
89 67
90static int LoadInt (ZIO* Z, char* message) 68static int LoadInt (ZIO* Z, char* message)
91{ 69{
@@ -103,7 +81,7 @@ static Byte* LoadCode (ZIO* Z)
103 Byte* b=luaM_malloc(size+PAD); 81 Byte* b=luaM_malloc(size+PAD);
104 LoadBlock(b,size,Z); 82 LoadBlock(b,size,Z);
105 if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z)); 83 if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
106 memset(b+size,ENDCODE,PAD); /* pad for safety */ 84 memset(b+size,ENDCODE,PAD); /* pad code for safety */
107 return b; 85 return b;
108} 86}
109 87
@@ -188,9 +166,7 @@ static void LoadSignature (ZIO* Z)
188 166
189static void LoadHeader (ZIO* Z) 167static void LoadHeader (ZIO* Z)
190{ 168{
191 int version,id,sizeofR; 169 int version,sizeofR;
192 real f=-TEST_NUMBER,tf=TEST_NUMBER;
193 luaU_testnumber();
194 LoadSignature(Z); 170 LoadSignature(Z);
195 version=ezgetc(Z); 171 version=ezgetc(Z);
196 if (version>VERSION) 172 if (version>VERSION)
@@ -201,17 +177,30 @@ static void LoadHeader (ZIO* Z)
201 luaL_verror( 177 luaL_verror(
202 "%s too old: version=0x%02x; expected at least 0x%02x", 178 "%s too old: version=0x%02x; expected at least 0x%02x",
203 zname(Z),version,VERSION0); 179 zname(Z),version,VERSION0);
204 id=ezgetc(Z); /* test number representation */ 180 sizeofR=ezgetc(Z); /* test number representation */
205 sizeofR=ezgetc(Z); 181#if LUAC_NATIVE
206 if (id!=ID_NUMBER || sizeofR!=sizeof(real)) 182 if (sizeofR==0)
207 luaL_verror("unknown number signature in %s: " 183 luaL_verror("cannot read numbers in %s: "
208 "read 0x%02x%02x; expected 0x%02x%02x", 184 "support for decimal format not enabled",
209 zname(Z),id,sizeofR,ID_NUMBER,sizeof(real)); 185 zname(Z));
186 if (sizeofR!=sizeof(real))
187 luaL_verror("unknown number size in %s: read %d; expected %d",
188 zname(Z),sizeofR,sizeof(real));
189 else
190 {
191 real f=-TEST_NUMBER,tf=TEST_NUMBER;
210 doLoadNumber(f,Z); 192 doLoadNumber(f,Z);
211 if (f!=tf) 193 if (f!=tf)
212 luaL_verror("unknown number representation in %s: " 194 luaL_verror("unknown number representation in %s: "
213 "read " NUMBER_FMT "; expected " NUMBER_FMT, 195 "read " NUMBER_FMT "; expected " NUMBER_FMT,
214 zname(Z),f,tf); 196 zname(Z),f,tf);
197 }
198#else
199 if (sizeofR!=0)
200 luaL_verror("cannot read numbers in %s: "
201 "support for native format not enabled",
202 zname(Z));
203#endif
215} 204}
216 205
217static TProtoFunc* LoadChunk (ZIO* Z) 206static TProtoFunc* LoadChunk (ZIO* Z)
@@ -235,28 +224,6 @@ TProtoFunc* luaU_undump1 (ZIO* Z)
235} 224}
236 225
237/* 226/*
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 227* handle constants that cannot happen
261*/ 228*/
262void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf) 229void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
diff --git a/lundump.h b/lundump.h
index 399a72db..0446ccdf 100644
--- a/lundump.h
+++ b/lundump.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.h,v 1.6 1999/03/30 20:29:34 roberto Exp roberto $ 2** $Id: lundump.h,v 1.13 1999/03/29 16:16:18 lhf Exp lhf $
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,39 +10,7 @@
10#include "lobject.h" 10#include "lobject.h"
11#include "lzio.h" 11#include "lzio.h"
12 12
13/* -- start of user configuration ------------------------------------------ */
14
15/* LUA_NUMBER
16* choose below the number representation in precompiled chunks by choosing an
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*/
27
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
35
36/* format for numbers in listings and error messages */
37#ifndef NUMBER_FMT
38#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
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 */ 13TProtoFunc* 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); 14void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
47 /* handle cases that cannot happen */ 15 /* handle cases that cannot happen */
48 16
@@ -52,52 +20,29 @@ void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
52#define ID_CHUNK 27 /* binary files start with ESC... */ 20#define ID_CHUNK 27 /* binary files start with ESC... */
53#define SIGNATURE "Lua" /* ...followed by this signature */ 21#define SIGNATURE "Lua" /* ...followed by this signature */
54 22
55/* number representation */ 23/* formats for error messages */
56#define ID_INT4 'l' /* 4-byte integers */ 24#define SOURCE "<%s:%d>"
57#define ID_REAL4 'f' /* 4-byte reals */ 25#define IN " in %p " SOURCE
58#define ID_REAL8 'd' /* 8-byte reals */ 26#define INLOC tf,tf->source->str,tf->lineDefined
59#define ID_NATIVE '?' /* whatever your machine uses */
60 27
61/* the default is ID_REAL8 because the default for LUA_NUM_TYPE is double */ 28/* format for numbers in listings and error messages */
62#ifndef ID_NUMBER 29#ifndef NUMBER_FMT
63#define ID_NUMBER ID_REAL8 /* 8-byte reals */ 30#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
64#endif 31#endif
65 32
33/* LUA_NUMBER
34* by default, numbers are stored in precompiled chunks as decimal strings.
35* this is completely portable and fast enough for most applications.
36* if you want to use this default, do nothing.
37* if you want additional speed at the expense of portability, move the line
38* below out of this comment.
39#define LUAC_NATIVE
40*/
41
42#ifdef LUAC_NATIVE
66/* a multiple of PI for testing number representation */ 43/* a multiple of PI for testing number representation */
67/* multiplying by 1E8 gives non-trivial integer values */ 44/* multiplying by 1E8 gives non-trivial integer values */
68#define TEST_NUMBER 3.14159265358979323846E8 45#define TEST_NUMBER 3.14159265358979323846E8
69
70#if ID_NUMBER==ID_REAL4
71 #define DumpNumber DumpFloat
72 #define LoadNumber LoadFloat
73 #define SIZEOF_NUMBER 4
74 #define TYPEOF_NUMBER float
75 #define NAMEOF_NUMBER "float"
76#elif ID_NUMBER==ID_REAL8
77 #define DumpNumber DumpDouble
78 #define LoadNumber LoadDouble
79 #define SIZEOF_NUMBER 8
80 #define TYPEOF_NUMBER double
81 #define NAMEOF_NUMBER "double"
82#elif ID_NUMBER==ID_INT4
83 #define DumpNumber DumpLong
84 #define LoadNumber LoadLong
85 #define SIZEOF_NUMBER 4
86 #define TYPEOF_NUMBER long
87 #define NAMEOF_NUMBER "long"
88#elif ID_NUMBER==ID_NATIVE
89 #define DumpNumber DumpNative
90 #define LoadNumber LoadNative
91 #define SIZEOF_NUMBER sizeof(real)
92 #define TYPEOF_NUMBER real
93 #define NAMEOF_NUMBER "native"
94#else
95 #error bad ID_NUMBER
96#endif 46#endif
97 47
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 48#endif