[syslinux] [PATCH 07/21] lua: use integer arithmetic

Ferenc Wágner wferi at niif.hu
Tue Oct 15 11:03:35 PDT 2013


---
 com32/lua/src/linit.c    |    2 ++
 com32/lua/src/lmathlib.c |    2 ++
 com32/lua/src/loslib.c   |    4 +++
 com32/lua/src/ltable.c   |   15 +++++------
 com32/lua/src/luaconf.h  |   62 +++++++++++++++++++++++++++++++++++++++++++---
 com32/lua/src/lvm.c      |   20 +++++++++++++++
 6 files changed, 94 insertions(+), 11 deletions(-)

diff --git a/com32/lua/src/linit.c b/com32/lua/src/linit.c
index 8d3aa65..a2ca186 100644
--- a/com32/lua/src/linit.c
+++ b/com32/lua/src/linit.c
@@ -35,7 +35,9 @@ static const luaL_Reg loadedlibs[] = {
   {LUA_OSLIBNAME, luaopen_os},
   {LUA_STRLIBNAME, luaopen_string},
   {LUA_BITLIBNAME, luaopen_bit32},
+#ifndef LUA_NUMBER_INTEGRAL
   {LUA_MATHLIBNAME, luaopen_math},
+#endif
   {LUA_DBLIBNAME, luaopen_debug},
   {NULL, NULL}
 };
diff --git a/com32/lua/src/lmathlib.c b/com32/lua/src/lmathlib.c
index a49f1fd..97b935a 100644
--- a/com32/lua/src/lmathlib.c
+++ b/com32/lua/src/lmathlib.c
@@ -272,8 +272,10 @@ LUAMOD_API int luaopen_math (lua_State *L) {
   luaL_newlib(L, mathlib);
   lua_pushnumber(L, PI);
   lua_setfield(L, -2, "pi");
+#ifndef LUA_NUMBER_INTEGRAL
   lua_pushnumber(L, HUGE_VAL);
   lua_setfield(L, -2, "huge");
+#endif
   return 1;
 }
 
diff --git a/com32/lua/src/loslib.c b/com32/lua/src/loslib.c
index 5170fd0..04f8f9c 100644
--- a/com32/lua/src/loslib.c
+++ b/com32/lua/src/loslib.c
@@ -263,11 +263,13 @@ static int os_time (lua_State *L) {
 }
 
 
+#ifndef LUA_NUMBER_INTEGRAL
 static int os_difftime (lua_State *L) {
   lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
                              (time_t)(luaL_optnumber(L, 2, 0))));
   return 1;
 }
+#endif
 
 /* }====================================================== */
 
@@ -300,7 +302,9 @@ static int os_exit (lua_State *L) {
 static const luaL_Reg syslib[] = {
   {"clock",     os_clock},
   {"date",      os_date},
+#ifndef LUA_NUMBER_INTEGRAL
   {"difftime",  os_difftime},
+#endif
   {"execute",   os_execute},
   {"exit",      os_exit},
   {"getenv",    os_getenv},
diff --git a/com32/lua/src/ltable.c b/com32/lua/src/ltable.c
index 420391f..fca20a8 100644
--- a/com32/lua/src/ltable.c
+++ b/com32/lua/src/ltable.c
@@ -77,15 +77,16 @@ static const Node dummynode_ = {
 /*
 ** hash for lua_Numbers
 */
+/* Taken from Lua 5.1 to avoid frexp() */
+#define numints	cast_int(sizeof(lua_Number)/sizeof(int))
 static Node *hashnum (const Table *t, lua_Number n) {
+  unsigned int a[numints];
   int i;
-  luai_hashnum(i, n);
-  if (i < 0) {
-    if (cast(unsigned int, i) == 0u - i)  /* use unsigned to avoid overflows */
-      i = 0;  /* handle INT_MIN */
-    i = -i;  /* must be a positive value */
-  }
-  return hashmod(t, i);
+  if (luai_numeq(n, 0))  /* avoid problems with -0 */
+    return gnode(t, 0);
+  memcpy(a, &n, sizeof(a));
+  for (i = 1; i < numints; i++) a[0] += a[i];
+  return hashmod(t, a[0]);
 }
 
 
diff --git a/com32/lua/src/luaconf.h b/com32/lua/src/luaconf.h
index df802c9..fa6546b 100644
--- a/com32/lua/src/luaconf.h
+++ b/com32/lua/src/luaconf.h
@@ -383,14 +383,31 @@
 ** ===================================================================
 */
 
+/* Define LUA_NUMBER_INTEGRAL to produce a system that uses no
+   floating point operations by changing the type of Lua numbers from
+   double to long.  It implements division and modulus so that 
+
+   x == (x / y) * y + x % y.  
+   
+   The exponentiation function returns zero for negative exponents.
+   Defining LUA_NUMBER_INTEGRAL also removes the difftime function,
+   and the math module should not be used.  The string.format function
+   no longer handles the floating point directives %e, %E, %f, %g, and
+   %G. */
+
+#define LUA_NUMBER_INTEGRAL
+#ifdef LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER	long
+#else
 #define LUA_NUMBER_DOUBLE
 #define LUA_NUMBER	double
+#endif
 
 /*
 @@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
 @* over a number.
 */
-#define LUAI_UACNUMBER	double
+#define LUAI_UACNUMBER	LUA_NUMBER
 
 
 /*
@@ -399,8 +416,13 @@
 @@ lua_number2str converts a number to a string.
 @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
 */
+#ifdef LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER_SCAN		"%ld"
+#define LUA_NUMBER_FMT		"%ld"
+#else
 #define LUA_NUMBER_SCAN		"%lf"
 #define LUA_NUMBER_FMT		"%.14g"
+#endif
 #define lua_number2str(s,n)	sprintf((s), LUA_NUMBER_FMT, (n))
 #define LUAI_MAXNUMBER2STR	32 /* 16 digits, sign, point, and \0 */
 
@@ -419,10 +441,14 @@
 ** systems, you can leave 'lua_strx2number' undefined and Lua will
 ** provide its own implementation.
 */
+#ifdef LUA_NUMBER_INTEGRAL
+#define lua_str2number(s,p)	strtol((s), (p), 10)
+#else
 #define lua_str2number(s,p)	strtod((s), (p))
+#endif
 
-#if defined(LUA_USE_STRTODHEX)
-#define lua_strx2number(s,p)	strtod((s), (p))
+#ifdef SYSLINUX
+#define lua_strx2number(s,p)	strtol((s), (p), 16)
 #endif
 
 
@@ -430,19 +456,46 @@
 @@ The luai_num* macros define the primitive operations over numbers.
 */
 
+#ifndef LUA_NUMBER_INTEGRAL
 /* the following operations need the math library */
 #if defined(lobject_c) || defined(lvm_c)
 #include <math.h>
 #define luai_nummod(L,a,b)	((a) - l_mathop(floor)((a)/(b))*(b))
 #define luai_numpow(L,a,b)	(l_mathop(pow)(a,b))
 #endif
+#endif
 
 /* these are quite standard operations */
 #if defined(LUA_CORE)
 #define luai_numadd(L,a,b)	((a)+(b))
 #define luai_numsub(L,a,b)	((a)-(b))
 #define luai_nummul(L,a,b)	((a)*(b))
+#ifdef LUA_NUMBER_INTEGRAL
+#define luai_numdiv(L,a,b)		\
+  (-1/2?				\
+   (a)/(b):				\
+   (((a)<0)==((b)<0)||(a)%(b)==0?	\
+    (a)/(b):				\
+    (a)/(b)-1))
+#define luai_nummod(L,a,b)		\
+  (-1/2?				\
+   (a)%(b):				\
+   (((a)<0)==((b)<0)||(a)%(b)==0?	\
+    (a)%(b):				\
+    (a)%(b)+(b)))
+#define luai_lnumdiv(L,a,b)		\
+  ((b)==0?				\
+   (luaG_runerror(L,"divide by zero"),0): \
+   luai_numdiv(a,b))
+#define luai_lnummod(L,a,b)		\
+  ((b)==0?				\
+   (luaG_runerror(L,"modulo by zero"),0): \
+   luai_nummod(a,b))
+LUA_NUMBER luai_ipow(void *L, LUA_NUMBER, LUA_NUMBER);
+#define luai_numpow(L,a,b)	(luai_ipow(L,a,b))
+#else
 #define luai_numdiv(L,a,b)	((a)/(b))
+#endif
 #define luai_numunm(L,a)	(-(a))
 #define luai_numeq(a,b)		((a)==(b))
 #define luai_numlt(L,a,b)	((a)<(b))
@@ -457,7 +510,8 @@
 ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
 ** machines, ptrdiff_t gives a good choice between int or long.)
 */
-#define LUA_INTEGER	ptrdiff_t
+#define LUA_INTEGER	long
+/* Changed to long for use with integral Lua numbers. */
 
 /*
 @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
diff --git a/com32/lua/src/lvm.c b/com32/lua/src/lvm.c
index 657d5c4..9cb7571 100644
--- a/com32/lua/src/lvm.c
+++ b/com32/lua/src/lvm.c
@@ -27,6 +27,26 @@
 #include "lvm.h"
 
 
+#ifdef LUA_NUMBER_INTEGRAL
+LUA_NUMBER luai_ipow(void *L, LUA_NUMBER a, LUA_NUMBER b) {
+  (void)L;
+  if (b < 0)
+    return 0;
+  else if (b == 0)
+    return 1;
+  else {
+    LUA_NUMBER c = 1;
+    for (;;) {
+      if (b & 1)
+	c *= a;
+      b = b >> 1;
+      if (b == 0)
+	return c;
+      a *= a;
+    }
+  }
+}
+#endif
 
 /* limit for table tag-method chains (to avoid loops) */
 #define MAXTAGLOOP	100
-- 
1.7.10.4



More information about the Syslinux mailing list