diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-10-26 17:32:19 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-10-26 17:32:19 -0200 |
commit | 6098e06e09e82409710c52eeaefb11395345e194 (patch) | |
tree | b21a71f26d4a2c88c207fc2b1f7b2b125f88e1a5 | |
parent | c6b64ffe65549b179bfa565e8329430857e335ee (diff) | |
download | lua-6098e06e09e82409710c52eeaefb11395345e194.tar.gz lua-6098e06e09e82409710c52eeaefb11395345e194.tar.bz2 lua-6098e06e09e82409710c52eeaefb11395345e194.zip |
better organization for coercion functions between lua_Number and
integer types + IEEE trick to be used in most platforms, by default
-rw-r--r-- | lua.h | 4 | ||||
-rw-r--r-- | luaconf.h | 96 |
2 files changed, 70 insertions, 30 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.274 2010/09/03 14:14:01 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.275 2010/10/25 20:31:11 roberto Exp roberto $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
@@ -107,7 +107,7 @@ typedef LUA_NUMBER lua_Number; | |||
107 | typedef LUA_INTEGER lua_Integer; | 107 | typedef LUA_INTEGER lua_Integer; |
108 | 108 | ||
109 | /* unsigned integer type */ | 109 | /* unsigned integer type */ |
110 | typedef unsigned LUA_INT32 lua_Unsigned; | 110 | typedef LUA_UNSIGNED lua_Unsigned; |
111 | 111 | ||
112 | 112 | ||
113 | 113 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: luaconf.h,v 1.142 2010/07/28 15:51:59 roberto Exp roberto $ | 2 | ** $Id: luaconf.h,v 1.143 2010/09/07 19:21:39 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 | */ |
@@ -438,26 +438,28 @@ | |||
438 | */ | 438 | */ |
439 | #define LUA_INTEGER ptrdiff_t | 439 | #define LUA_INTEGER ptrdiff_t |
440 | 440 | ||
441 | /* | ||
442 | @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. | ||
443 | ** It must have at least 32 bits. | ||
444 | */ | ||
445 | #define LUA_UNSIGNED unsigned LUA_INT32 | ||
446 | |||
441 | 447 | ||
442 | /* | 448 | /* |
443 | @@ lua_number2int is a macro to convert lua_Number to int. | 449 | @@ lua_number2int is a macro to convert lua_Number to int. |
444 | @@ lua_number2integer is a macro to convert lua_Number to LUA_INTEGER. | 450 | @@ lua_number2integer is a macro to convert lua_Number to LUA_INTEGER. |
445 | @@ lua_number2uint is a macro to convert a lua_Number to an unsigned | 451 | @@ lua_number2uint is a macro to convert a lua_Number to a LUA_UNSIGNED. |
446 | @* LUA_INT32. | 452 | @@ lua_uint2number is a macro to convert a LUA_UNSIGNED to a lua_Number. |
447 | @@ lua_uint2number is a macro to convert an unsigned LUA_INT32 | ||
448 | @* to a lua_Number. | ||
449 | ** CHANGE them if you know a faster way to convert a lua_Number to | ||
450 | ** int (with any rounding method and without throwing errors) in your | ||
451 | ** system. In Pentium machines, a naive typecast from double to int | ||
452 | ** in C is extremely slow, so any alternative is worth trying. | ||
453 | */ | 453 | */ |
454 | 454 | ||
455 | /* On a Pentium, resort to a trick */ | 455 | #if defined(LUA_CORE) /* { */ |
456 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ | 456 | |
457 | (defined(__i386) || defined (_M_IX86) || defined(__i386__)) /* { */ | 457 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && \ |
458 | !defined(LUA_NOIEEE754TRICK) /* { */ | ||
458 | 459 | ||
459 | /* On a Microsoft compiler, use assembler */ | 460 | /* On a Microsoft compiler on a Pentium, use assembler to avoid chashes |
460 | #if defined(_MSC_VER) /* { */ | 461 | with a DirectX idiosyncrasy */ |
462 | #if defined(_MSC_VER) && defined(M_IX86) /* { */ | ||
461 | 463 | ||
462 | #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} | 464 | #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} |
463 | #define lua_number2integer(i,n) lua_number2int(i, n) | 465 | #define lua_number2integer(i,n) lua_number2int(i, n) |
@@ -465,31 +467,69 @@ | |||
465 | {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} | 467 | {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} |
466 | 468 | ||
467 | #else /* }{ */ | 469 | #else /* }{ */ |
468 | /* the next trick should work on any Pentium, but sometimes clashes | 470 | /* the next trick should work on any machine using IEEE754 with |
469 | with a DirectX idiosyncrasy */ | 471 | a 32-bit integer type */ |
470 | 472 | ||
471 | union luai_Cast { double l_d; long l_l; }; | 473 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; |
472 | #define lua_number2int(i,n) \ | 474 | |
473 | { volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; (i) = u.l_l; } | 475 | /* |
474 | #define lua_number2integer(i,n) lua_number2int(i, n) | 476 | @@ LUA_IEEEENDIAN is the endianess of doubles in your machine |
475 | #define lua_number2uint(i,n) lua_number2int(i, n) | 477 | @@ (0 for little endian, 1 for big endian); if not defined, Lua will |
478 | @@ check it dynamically. | ||
479 | */ | ||
480 | |||
481 | #if !defined(LUA_IEEEENDIAN) /* { */ | ||
482 | #define LUAI_EXTRAIEEE \ | ||
483 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; | ||
484 | #define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33) | ||
485 | #else | ||
486 | #define LUAI_EXTRAIEEE /* empty */ | ||
487 | #endif /* } */ | ||
488 | |||
489 | #define lua_number2int32(i,n,t) \ | ||
490 | { LUAI_EXTRAIEEE \ | ||
491 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ | ||
492 | (i) = (t)u.l_p[LUA_IEEEENDIAN]; } | ||
493 | |||
494 | #define lua_number2int(i,n) lua_number2int32(i, n, int) | ||
495 | #define lua_number2integer(i,n) lua_number2int32(i, n, LUA_INTEGER) | ||
496 | #define lua_number2uint(i,n) lua_number2int32(i, n, LUA_UNSIGNED) | ||
476 | 497 | ||
477 | #endif /* } */ | 498 | #endif /* } */ |
478 | 499 | ||
479 | 500 | ||
480 | #else /* }{ */ | 501 | #endif /* } */ |
481 | /* this option always works, but may be slow */ | 502 | |
503 | |||
504 | /* the following definitions always work, but may be slow */ | ||
505 | |||
506 | #if !defined(lua_number2int) | ||
482 | #define lua_number2int(i,n) ((i)=(int)(n)) | 507 | #define lua_number2int(i,n) ((i)=(int)(n)) |
483 | #define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) | 508 | #endif |
484 | #define lua_number2uint(i,n) ((i)=(unsigned LUA_INT32)(n)) | ||
485 | 509 | ||
486 | #endif /* } */ | 510 | #if !defined(lua_number2integer) |
511 | #define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) | ||
512 | #endif | ||
487 | 513 | ||
514 | #if !defined(lua_number2uint) && (defined(lapi_c) || defined(luaall_c)) /* { */ | ||
515 | /* the following definition assures proper modulo behavior */ | ||
516 | #if defined(LUA_NUMBER_DOUBLE) | ||
517 | #include <math.h> | ||
518 | #define lua_number2uint(i,n) \ | ||
519 | ((i)=(LUA_UNSIGNED)((n) - floor((n)/4294967296.0)*4294967296.0)) | ||
520 | #else | ||
521 | #define lua_number2uint(i,n) ((i)=(LUA_UNSIGNED)(n)) | ||
522 | #endif | ||
523 | #endif /* } */ | ||
488 | 524 | ||
489 | /* on several machines, coercion from unsigned to double is too slow, | 525 | #if !defined(lua_uint2number) |
490 | so avoid that if possible */ | 526 | /* on several machines, coercion from unsigned to double is slow, |
527 | so it may be worth to avoid */ | ||
491 | #define lua_uint2number(u) \ | 528 | #define lua_uint2number(u) \ |
492 | ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) | 529 | ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) |
530 | #endif | ||
531 | |||
532 | #endif /* } */ | ||
493 | 533 | ||
494 | 534 | ||
495 | /* | 535 | /* |