aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-10-26 17:32:19 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-10-26 17:32:19 -0200
commit6098e06e09e82409710c52eeaefb11395345e194 (patch)
treeb21a71f26d4a2c88c207fc2b1f7b2b125f88e1a5
parentc6b64ffe65549b179bfa565e8329430857e335ee (diff)
downloadlua-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.h4
-rw-r--r--luaconf.h96
2 files changed, 70 insertions, 30 deletions
diff --git a/lua.h b/lua.h
index a5b6086c..aab6a4ec 100644
--- a/lua.h
+++ b/lua.h
@@ -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;
107typedef LUA_INTEGER lua_Integer; 107typedef LUA_INTEGER lua_Integer;
108 108
109/* unsigned integer type */ 109/* unsigned integer type */
110typedef unsigned LUA_INT32 lua_Unsigned; 110typedef LUA_UNSIGNED lua_Unsigned;
111 111
112 112
113 113
diff --git a/luaconf.h b/luaconf.h
index 1b881475..59ee71af 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -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
471union luai_Cast { double l_d; long l_l; }; 473union 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/*