diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-11 11:10:50 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-11 11:10:50 -0300 |
| commit | 77cbd817d1a525a161f8f24e98459191edb9a181 (patch) | |
| tree | 0a5c621a34772b73b3b52559afccdc6decce9afa | |
| parent | 4ec7d6de95bcf9fa35a9b268a41154b142190691 (diff) | |
| download | lua-77cbd817d1a525a161f8f24e98459191edb9a181.tar.gz lua-77cbd817d1a525a161f8f24e98459191edb9a181.tar.bz2 lua-77cbd817d1a525a161f8f24e98459191edb9a181.zip | |
better(?) handling of '#define's for IEEE-related tricks + avoid using
IEEE trick for 64-bit integer types (lua_Integer on 64-bit machines)
| -rw-r--r-- | llimits.h | 15 | ||||
| -rw-r--r-- | lobject.h | 37 | ||||
| -rw-r--r-- | luaconf.h | 96 |
3 files changed, 82 insertions, 66 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.96 2012/01/25 21:05:40 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.97 2012/03/28 18:27:25 roberto Exp roberto $ |
| 3 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -209,31 +209,36 @@ typedef lu_int32 Instruction; | |||
| 209 | 209 | ||
| 210 | #elif defined(LUA_IEEE754TRICK) /* }{ */ | 210 | #elif defined(LUA_IEEE754TRICK) /* }{ */ |
| 211 | /* the next trick should work on any machine using IEEE754 with | 211 | /* the next trick should work on any machine using IEEE754 with |
| 212 | a 32-bit integer type */ | 212 | a 32-bit int type */ |
| 213 | 213 | ||
| 214 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; | 214 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; |
| 215 | 215 | ||
| 216 | #if !defined(LUA_IEEEENDIAN) /* { */ | 216 | #if !defined(LUA_IEEEENDIAN) /* { */ |
| 217 | #define LUAI_EXTRAIEEE \ | 217 | #define LUAI_EXTRAIEEE \ |
| 218 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; | 218 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; |
| 219 | #define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33) | 219 | #define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) |
| 220 | #else | 220 | #else |
| 221 | #define LUA_IEEEENDIANLOC LUA_IEEEENDIAN | ||
| 221 | #define LUAI_EXTRAIEEE /* empty */ | 222 | #define LUAI_EXTRAIEEE /* empty */ |
| 222 | #endif /* } */ | 223 | #endif /* } */ |
| 223 | 224 | ||
| 224 | #define lua_number2int32(i,n,t) \ | 225 | #define lua_number2int32(i,n,t) \ |
| 225 | { LUAI_EXTRAIEEE \ | 226 | { LUAI_EXTRAIEEE \ |
| 226 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ | 227 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ |
| 227 | (i) = (t)u.l_p[LUA_IEEEENDIAN]; } | 228 | (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } |
| 228 | 229 | ||
| 229 | #define luai_hashnum(i,n) \ | 230 | #define luai_hashnum(i,n) \ |
| 230 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ | 231 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ |
| 231 | (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ | 232 | (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ |
| 232 | 233 | ||
| 233 | #define lua_number2int(i,n) lua_number2int32(i, n, int) | 234 | #define lua_number2int(i,n) lua_number2int32(i, n, int) |
| 234 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) | ||
| 235 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) | 235 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) |
| 236 | 236 | ||
| 237 | /* the trick can be expanded to lua_Integer when it is a 32-bit value */ | ||
| 238 | #if defined(LUA_IEEELL) | ||
| 239 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) | ||
| 240 | #endif | ||
| 241 | |||
| 237 | #endif /* } */ | 242 | #endif /* } */ |
| 238 | 243 | ||
| 239 | 244 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.68 2012/01/25 21:05:40 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.69 2012/05/08 13:53:33 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -266,6 +266,8 @@ typedef struct lua_TValue TValue; | |||
| 266 | #define setsvalue2n setsvalue | 266 | #define setsvalue2n setsvalue |
| 267 | 267 | ||
| 268 | 268 | ||
| 269 | /* check whether a number is valid (useful only for NaN trick) */ | ||
| 270 | #define luai_checknum(L,o,c) { /* empty */ } | ||
| 269 | 271 | ||
| 270 | 272 | ||
| 271 | /* | 273 | /* |
| @@ -273,10 +275,7 @@ typedef struct lua_TValue TValue; | |||
| 273 | ** NaN Trick | 275 | ** NaN Trick |
| 274 | ** ======================================================= | 276 | ** ======================================================= |
| 275 | */ | 277 | */ |
| 276 | 278 | #if defined(LUA_NANTRICK) | |
| 277 | #if defined(LUA_NANTRICK) \ | ||
| 278 | || defined(LUA_NANTRICK_LE) \ | ||
| 279 | || defined(LUA_NANTRICK_BE) | ||
| 280 | 279 | ||
| 281 | /* | 280 | /* |
| 282 | ** numbers are represented in the 'd_' field. All other values have the | 281 | ** numbers are represented in the 'd_' field. All other values have the |
| @@ -284,15 +283,23 @@ typedef struct lua_TValue TValue; | |||
| 284 | ** a "signaled NaN", which is never generated by regular operations by | 283 | ** a "signaled NaN", which is never generated by regular operations by |
| 285 | ** the CPU (nor by 'strtod') | 284 | ** the CPU (nor by 'strtod') |
| 286 | */ | 285 | */ |
| 287 | #if !defined(NNMARK) | 286 | |
| 287 | /* allows for external implementation for part of the trick */ | ||
| 288 | #if !defined(NNMARK) /* { */ | ||
| 289 | |||
| 290 | |||
| 291 | #if !defined(LUA_IEEEENDIAN) | ||
| 292 | #error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' | ||
| 293 | #endif | ||
| 294 | |||
| 295 | |||
| 288 | #define NNMARK 0x7FF7A500 | 296 | #define NNMARK 0x7FF7A500 |
| 289 | #define NNMASK 0x7FFFFF00 | 297 | #define NNMASK 0x7FFFFF00 |
| 290 | #endif | ||
| 291 | 298 | ||
| 292 | #undef TValuefields | 299 | #undef TValuefields |
| 293 | #undef NILCONSTANT | 300 | #undef NILCONSTANT |
| 294 | 301 | ||
| 295 | #if defined(LUA_NANTRICK_LE) | 302 | #if (LUA_IEEEENDIAN == 0) /* { */ |
| 296 | 303 | ||
| 297 | /* little endian */ | 304 | /* little endian */ |
| 298 | #define TValuefields \ | 305 | #define TValuefields \ |
| @@ -303,7 +310,7 @@ typedef struct lua_TValue TValue; | |||
| 303 | #define d_(o) ((o)->u.d__) | 310 | #define d_(o) ((o)->u.d__) |
| 304 | #define tt_(o) ((o)->u.i.tt__) | 311 | #define tt_(o) ((o)->u.i.tt__) |
| 305 | 312 | ||
| 306 | #elif defined(LUA_NANTRICK_BE) | 313 | #else /* }{ */ |
| 307 | 314 | ||
| 308 | /* big endian */ | 315 | /* big endian */ |
| 309 | #define TValuefields \ | 316 | #define TValuefields \ |
| @@ -314,10 +321,9 @@ typedef struct lua_TValue TValue; | |||
| 314 | #define d_(o) ((o)->u.d__) | 321 | #define d_(o) ((o)->u.d__) |
| 315 | #define tt_(o) ((o)->u.i.tt__) | 322 | #define tt_(o) ((o)->u.i.tt__) |
| 316 | 323 | ||
| 317 | #elif !defined(TValuefields) | 324 | #endif /* } */ |
| 318 | #error option 'LUA_NANTRICK' needs declaration for 'TValuefields' | ||
| 319 | 325 | ||
| 320 | #endif | 326 | #endif /* } */ |
| 321 | 327 | ||
| 322 | 328 | ||
| 323 | /* correspondence with standard representation */ | 329 | /* correspondence with standard representation */ |
| @@ -367,14 +373,9 @@ typedef struct lua_TValue TValue; | |||
| 367 | (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) | 373 | (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) |
| 368 | 374 | ||
| 369 | 375 | ||
| 370 | 376 | #undef luai_checknum | |
| 371 | #define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } | 377 | #define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } |
| 372 | 378 | ||
| 373 | |||
| 374 | #else | ||
| 375 | |||
| 376 | #define luai_checknum(L,o,c) { /* empty */ } | ||
| 377 | |||
| 378 | #endif | 379 | #endif |
| 379 | /* }====================================================== */ | 380 | /* }====================================================== */ |
| 380 | 381 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1.169 2011/11/30 12:35:05 roberto Exp roberto $ | 2 | ** $Id: luaconf.h,v 1.170 2011/12/06 16:58:36 roberto Exp roberto $ |
| 3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -453,66 +453,76 @@ | |||
| 453 | #define LUA_UNSIGNED unsigned LUA_INT32 | 453 | #define LUA_UNSIGNED unsigned LUA_INT32 |
| 454 | 454 | ||
| 455 | 455 | ||
| 456 | #if defined(LUA_CORE) /* { */ | ||
| 457 | 456 | ||
| 458 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ | 457 | /* |
| 458 | ** Some tricks with doubles | ||
| 459 | */ | ||
| 460 | |||
| 461 | #if defined(LUA_CORE) && \ | ||
| 462 | defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ | ||
| 463 | /* | ||
| 464 | ** The next definitions activate some tricks to speed up the | ||
| 465 | ** conversion from doubles to integer types, mainly to LUA_UNSIGNED. | ||
| 466 | ** | ||
| 467 | @@ MS_ASMTRICK uses Microsoft assembler to avoid clashes with a | ||
| 468 | ** DirectX idiosyncrasy. | ||
| 469 | ** | ||
| 470 | @@ LUA_IEEE754TRICK uses a trick that should work on any machine | ||
| 471 | ** using IEEE754 with a 32-bit integer type. | ||
| 472 | ** | ||
| 473 | @@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be | ||
| 474 | ** defined when LUA_INTEGER is a 32-bit integer. | ||
| 475 | ** | ||
| 476 | @@ LUA_IEEEENDIAN is the endianness of doubles in your machine | ||
| 477 | ** (0 for little endian, 1 for big endian); if not defined, Lua will | ||
| 478 | ** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). | ||
| 479 | ** | ||
| 480 | @@ LUA_NANTRICK controls the use of a trick to pack all types into | ||
| 481 | ** a single double value, using NaN values to represent non-number | ||
| 482 | ** values. The trick only works on 32-bit machines (ints and pointers | ||
| 483 | ** are 32-bit values) with numbers represented as IEEE 754-2008 doubles | ||
| 484 | ** with conventional endianess (12345678 or 87654321), in CPUs that do | ||
| 485 | ** not produce signaling NaN values (all NaNs are quiet). | ||
| 486 | */ | ||
| 459 | 487 | ||
| 460 | /* On a Microsoft compiler on a Pentium, use assembler to avoid clashes | 488 | /* Microsoft compiler on a Pentium (32 bit) ? */ |
| 461 | with a DirectX idiosyncrasy */ | ||
| 462 | #if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ | 489 | #if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ |
| 463 | 490 | ||
| 464 | #define MS_ASMTRICK | 491 | #define MS_ASMTRICK |
| 492 | #define LUA_IEEEENDIAN 0 | ||
| 493 | #define LUA_NANTRICK | ||
| 465 | 494 | ||
| 466 | #else /* }{ */ | ||
| 467 | /* the next definition uses a trick that should work on any machine | ||
| 468 | using IEEE754 with a 32-bit integer type */ | ||
| 469 | |||
| 470 | #define LUA_IEEE754TRICK | ||
| 471 | |||
| 472 | /* | ||
| 473 | @@ LUA_IEEEENDIAN is the endianness of doubles in your machine | ||
| 474 | ** (0 for little endian, 1 for big endian); if not defined, Lua will | ||
| 475 | ** check it dynamically. | ||
| 476 | */ | ||
| 477 | /* check for known architectures */ | ||
| 478 | #if defined(__i386__) || defined(__i386) || defined(__X86__) || \ | ||
| 479 | defined (__x86_64) | ||
| 480 | #define LUA_IEEEENDIAN 0 | ||
| 481 | #elif defined(__POWERPC__) || defined(__ppc__) | ||
| 482 | #define LUA_IEEEENDIAN 1 | ||
| 483 | #endif | ||
| 484 | 495 | ||
| 485 | #endif /* } */ | 496 | /* pentium 32 bits? */ |
| 497 | #elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ | ||
| 486 | 498 | ||
| 487 | #endif /* } */ | 499 | #define LUA_IEEE754TRICK |
| 500 | #define LUA_IEEELL | ||
| 501 | #define LUA_IEEEENDIAN 0 | ||
| 502 | #define LUA_NANTRICK | ||
| 488 | 503 | ||
| 489 | #endif /* } */ | 504 | /* pentium 64 bits? */ |
| 505 | #elif defined(__x86_64) /* }{ */ | ||
| 490 | 506 | ||
| 491 | /* }================================================================== */ | 507 | #define LUA_IEEE754TRICK |
| 508 | #define LUA_IEEEENDIAN 0 | ||
| 492 | 509 | ||
| 510 | #elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ | ||
| 493 | 511 | ||
| 494 | /* | 512 | #define LUA_IEEE754TRICK |
| 495 | @@ LUA_NANTRICK_LE/LUA_NANTRICK_BE controls the use of a trick to | 513 | #define LUA_IEEEENDIAN 1 |
| 496 | ** pack all types into a single double value, using NaN values to | ||
| 497 | ** represent non-number values. The trick only works on 32-bit machines | ||
| 498 | ** (ints and pointers are 32-bit values) with numbers represented as | ||
| 499 | ** IEEE 754-2008 doubles with conventional endianess (12345678 or | ||
| 500 | ** 87654321), in CPUs that do not produce signaling NaN values (all NaNs | ||
| 501 | ** are quiet). | ||
| 502 | */ | ||
| 503 | #if defined(LUA_CORE) && \ | ||
| 504 | defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ | ||
| 505 | 514 | ||
| 506 | /* little-endian architectures that satisfy those conditions */ | 515 | #else /* }{ */ |
| 507 | #if defined(__i386__) || defined(__i386) || defined(__X86__) || \ | ||
| 508 | defined(_M_IX86) | ||
| 509 | 516 | ||
| 510 | #define LUA_NANTRICK_LE | 517 | /* assume IEEE754 and a 32-bit integer type */ |
| 518 | #define LUA_IEEE754TRICK | ||
| 511 | 519 | ||
| 512 | #endif | 520 | #endif /* } */ |
| 513 | 521 | ||
| 514 | #endif /* } */ | 522 | #endif /* } */ |
| 515 | 523 | ||
| 524 | /* }================================================================== */ | ||
| 525 | |||
| 516 | 526 | ||
| 517 | 527 | ||
| 518 | 528 | ||
