diff options
| -rw-r--r-- | tools/Makefile | 2 | ||||
| -rw-r--r-- | tools/lua/Makefile | 42 | ||||
| -rw-r--r-- | tools/lua/patches/010-lua-5.1.3-lnum-full-260308.patch | 3806 | ||||
| -rw-r--r-- | tools/lua/patches/020-shared_liblua.patch | 154 | ||||
| -rw-r--r-- | tools/lua/patches/030-archindependent-bytecode.patch | 113 | ||||
| -rw-r--r-- | tools/lua/patches/100-no_readline.patch | 53 | ||||
| -rw-r--r-- | tools/lua/patches/200-lua-path.patch | 15 | 
7 files changed, 4184 insertions, 1 deletions
diff --git a/tools/Makefile b/tools/Makefile index 0511a4804..7216d5b15 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -9,7 +9,7 @@  curdir:=tools  # subdirectories to descend into -$(curdir)/builddirs := sed sstrip ipkg-utils genext2fs squashfs mtd-utils lzma mkimage firmware-utils patch-cmdline pkg-config automake $(if $(CONFIG_CCACHE),ccache) bison $(if $(CONFIG_powerpc),dtc) +$(curdir)/builddirs := sed sstrip ipkg-utils genext2fs squashfs mtd-utils lzma mkimage firmware-utils patch-cmdline pkg-config automake $(if $(CONFIG_CCACHE),ccache) bison $(if $(CONFIG_powerpc),dtc) lua  # builddir dependencies  $(curdir)/squashfs/compile := $(curdir)/lzma/install diff --git a/tools/lua/Makefile b/tools/lua/Makefile new file mode 100644 index 000000000..7b1f28faf --- /dev/null +++ b/tools/lua/Makefile @@ -0,0 +1,42 @@ +#  +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=lua +PKG_VERSION:=5.1.3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://www.lua.org/ftp/ \ +	http://ftp.gwdg.de/pub/languages/lua/ \ +	http://mirrors.dotsrc.org/lua/ \ +	http://www.tecgraf.puc-rio.br/lua/ftp/ +PKG_MD5SUM:=a70a8dfaa150e047866dc01a46272599 + +include $(INCLUDE_DIR)/host-build.mk + +define Build/Configure +endef + +TARGET_CFLAGS += -DLUA_USE_LINUX + +define Build/Compile +	$(MAKE) -C $(PKG_BUILD_DIR)/src luac-host +endef + +define Build/Install +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/luac-host $(STAGING_DIR_HOST)/bin/luac +endef + +define Build/Clean +	$(MAKE) -C $(PKG_BUILD_DIR)/src clean +	rm -f $(PKG_BUILD_DIR)/src/luac-host +	$(call Build/Clean/Default) +endef + +$(eval $(call HostBuild)) diff --git a/tools/lua/patches/010-lua-5.1.3-lnum-full-260308.patch b/tools/lua/patches/010-lua-5.1.3-lnum-full-260308.patch new file mode 100644 index 000000000..a9cc95f75 --- /dev/null +++ b/tools/lua/patches/010-lua-5.1.3-lnum-full-260308.patch @@ -0,0 +1,3806 @@ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/Makefile lua-5.1.3-patched/src/Makefile +--- ../lua-5.1.3/src/Makefile	2008-01-19 21:37:58.000000000 +0200 ++++ lua-5.1.3-patched/src/Makefile	2008-03-26 13:05:24.000000000 +0200 +@@ -25,7 +25,7 @@ + LUA_A=	liblua.a + CORE_O=	lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + 	lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o  \ +-	lundump.o lvm.o lzio.o ++	lundump.o lvm.o lzio.o lnum.o + LIB_O=	lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ + 	lstrlib.o loadlib.o linit.o +  +@@ -148,6 +148,7 @@ + lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h + lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ +   ltm.h lzio.h lmem.h ldo.h ++lnum.o: lnum.c lua.h llex.h lnum.h + loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h + lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ +   ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +@@ -179,4 +180,18 @@ + print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ +   ltm.h lzio.h lmem.h lopcodes.h lundump.h +  ++luaconf.h: lnum_config.h ++lapi.c: lnum.h ++lauxlib.c: llimits.h ++lbaselib.c: llimits.h lobject.h lapi.h ++lcode.c: lnum.h ++liolib.c: lnum.h llex.h ++llex.c: lnum.h ++lnum.h: lobject.h ++lobject.c: llex.h lnum.h ++ltable.c: lnum.h ++lua.c: llimits.h ++lvm.c: llex.h lnum.h ++print.c: lnum.h ++ + # (end of Makefile) +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lapi.c lua-5.1.3-patched/src/lapi.c +--- ../lua-5.1.3/src/lapi.c	2008-01-03 17:20:39.000000000 +0200 ++++ lua-5.1.3-patched/src/lapi.c	2008-03-19 09:52:15.000000000 +0200 +@@ -28,7 +28,7 @@ + #include "ltm.h" + #include "lundump.h" + #include "lvm.h" +- ++#include "lnum.h" +  +  + const char lua_ident[] = +@@ -242,12 +242,13 @@ +  + LUA_API int lua_type (lua_State *L, int idx) { +   StkId o = index2adr(L, idx); +-  return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); ++  return (o == luaO_nilobject) ? LUA_TNONE : ttype_ext(o); + } +  +  + LUA_API const char *lua_typename (lua_State *L, int t) { +   UNUSED(L); ++  lua_assert( t!= LUA_TINT ); +   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; + } +  +@@ -265,6 +266,14 @@ + } +  +  ++LUA_API int lua_isinteger (lua_State *L, int idx) { ++  TValue tmp; ++  lua_Integer dum; ++  const TValue *o = index2adr(L, idx); ++  return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum)); ++} ++ ++ + LUA_API int lua_isstring (lua_State *L, int idx) { +   int t = lua_type(L, idx); +   return (t == LUA_TSTRING || t == LUA_TNUMBER); +@@ -310,31 +319,66 @@ + } +  +  +- + LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { +   TValue n; +   const TValue *o = index2adr(L, idx); +-  if (tonumber(o, &n)) ++  if (tonumber(o, &n)) { ++#ifdef LNUM_COMPLEX ++    if (nvalue_img(o) != 0) ++      luaG_runerror(L, "expecting a real number"); ++#endif +     return nvalue(o); +-  else +-    return 0; ++  } ++  return 0; + } +  +  + LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { +   TValue n; ++    /* Lua 5.1 documented behaviour is to return nonzero for non-integer: ++     * "If the number is not an integer, it is truncated in some non-specified way."  ++     * I would suggest to change this, to return 0 for anything that would ++     * not fit in 'lua_Integer'. ++     */ ++#ifdef LUA_COMPAT_TOINTEGER ++  /* Lua 5.1 compatible */ +   const TValue *o = index2adr(L, idx); +   if (tonumber(o, &n)) { +-    lua_Integer res; +-    lua_Number num = nvalue(o); +-    lua_number2integer(res, num); +-    return res; ++    lua_Integer i; ++    lua_Number d; ++    if (ttisint(o)) return ivalue(o); ++    d= nvalue_fast(o); ++# ifdef LNUM_COMPLEX ++    if (nvalue_img_fast(o) != 0) ++      luaG_runerror(L, "expecting a real number"); ++# endif ++    lua_number2integer(i, d); ++    return i; +   } +-  else +-    return 0; ++#else ++  /* New suggestion */ ++  const TValue *o = index2adr(L, idx); ++  if (tonumber(o, &n)) { ++    lua_Integer i; ++    if (ttisint(o)) return ivalue(o); ++    if (tt_integer_valued(o,&i)) return i; ++  } ++#endif ++  return 0; + } +  +  ++#ifdef LNUM_COMPLEX ++LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) { ++  TValue tmp; ++  const TValue *o = index2adr(L, idx); ++  if (tonumber(o, &tmp)) ++    return nvalue_complex(o); ++  return 0; ++} ++#endif ++ ++ + LUA_API int lua_toboolean (lua_State *L, int idx) { +   const TValue *o = index2adr(L, idx); +   return !l_isfalse(o); +@@ -365,6 +409,7 @@ +     case LUA_TSTRING: return tsvalue(o)->len; +     case LUA_TUSERDATA: return uvalue(o)->len; +     case LUA_TTABLE: return luaH_getn(hvalue(o)); ++    case LUA_TINT: +     case LUA_TNUMBER: { +       size_t l; +       lua_lock(L);  /* `luaV_tostring' may create a new string */ +@@ -427,6 +472,8 @@ + } +  +  ++/* 'lua_pushnumber()' may lose accuracy on integers, 'lua_pushinteger' will not. ++ */ + LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { +   lua_lock(L); +   setnvalue(L->top, n); +@@ -435,12 +482,22 @@ + } +  +  +-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { ++LUA_API void lua_pushinteger (lua_State *L, lua_Integer i) { ++  lua_lock(L); ++  setivalue(L->top, i); ++  api_incr_top(L); ++  lua_unlock(L); ++} ++ ++ ++#ifdef LNUM_COMPLEX ++LUA_API void lua_pushcomplex (lua_State *L, lua_Complex v) { +   lua_lock(L); +-  setnvalue(L->top, cast_num(n)); ++  setnvalue_complex( L->top, v ); +   api_incr_top(L); +   lua_unlock(L); + } ++#endif +  +  + LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { +@@ -570,7 +627,7 @@ +   lua_lock(L); +   o = index2adr(L, idx); +   api_check(L, ttistable(o)); +-  setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); ++  setobj2s(L, L->top, luaH_getint(hvalue(o), n)); +   api_incr_top(L); +   lua_unlock(L); + } +@@ -598,6 +655,9 @@ +     case LUA_TUSERDATA: +       mt = uvalue(obj)->metatable; +       break; ++    case LUA_TINT: ++      mt = G(L)->mt[LUA_TNUMBER]; ++      break; +     default: +       mt = G(L)->mt[ttype(obj)]; +       break; +@@ -688,7 +748,7 @@ +   api_checknelems(L, 1); +   o = index2adr(L, idx); +   api_check(L, ttistable(o)); +-  setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); ++  setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1); +   luaC_barriert(L, hvalue(o), L->top-1); +   L->top--; +   lua_unlock(L); +@@ -722,7 +782,7 @@ +       break; +     } +     default: { +-      G(L)->mt[ttype(obj)] = mt; ++      G(L)->mt[ttype_ext(obj)] = mt; +       break; +     } +   } +@@ -1083,3 +1143,32 @@ +   return name; + } +  ++ ++/* Help function for 'luaB_tonumber()', avoids multiple str->number ++ * conversions for Lua "tonumber()". ++ * ++ * Also pushes floating point numbers with integer value as integer, which ++ * can be used by 'tonumber()' in scripts to bring values back to integer ++ * realm. ++ * ++ * Note: The 'back to integer realm' is _not_ to affect string conversions: ++ * 'tonumber("4294967295.1")' should give a floating point value, although ++ * the value would be 4294967296 (and storable in int64 realm). ++ */ ++int lua_pushvalue_as_number (lua_State *L, int idx) ++{ ++  const TValue *o = index2adr(L, idx); ++  TValue tmp; ++  lua_Integer i; ++  if (ttisnumber(o)) { ++    if ( (!ttisint(o)) && tt_integer_valued(o,&i)) { ++      lua_pushinteger( L, i ); ++      return 1; ++    } ++  } else if (!tonumber(o, &tmp)) { ++    return 0; ++  } ++  if (ttisint(o)) lua_pushinteger( L, ivalue(o) ); ++  else lua_pushnumber( L, nvalue_fast(o) ); ++  return 1; ++} +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lapi.h lua-5.1.3-patched/src/lapi.h +--- ../lua-5.1.3/src/lapi.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lapi.h	2008-03-03 12:47:53.000000000 +0200 +@@ -13,4 +13,6 @@ +  + LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); +  ++int lua_pushvalue_as_number (lua_State *L, int idx); ++ + #endif +Binary files ../lua-5.1.3/src/lapi.o and lua-5.1.3-patched/src/lapi.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lauxlib.c lua-5.1.3-patched/src/lauxlib.c +--- ../lua-5.1.3/src/lauxlib.c	2008-01-21 15:20:51.000000000 +0200 ++++ lua-5.1.3-patched/src/lauxlib.c	2008-03-19 09:51:27.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "lua.h" +  + #include "lauxlib.h" +- ++#include "llimits.h" +  + #define FREELIST_REF	0	/* free list of references */ +  +@@ -66,7 +66,7 @@ +  +  + static void tag_error (lua_State *L, int narg, int tag) { +-  luaL_typerror(L, narg, lua_typename(L, tag)); ++  luaL_typerror(L, narg, tag==LUA_TINT ? "integer" : lua_typename(L, tag)); + } +  +  +@@ -188,8 +188,8 @@ +  + LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { +   lua_Integer d = lua_tointeger(L, narg); +-  if (d == 0 && !lua_isnumber(L, narg))  /* avoid extra test when d is not 0 */ +-    tag_error(L, narg, LUA_TNUMBER); ++  if (d == 0 && !lua_isinteger(L, narg))  /* avoid extra test when d is not 0 */ ++    tag_error(L, narg, LUA_TINT); +   return d; + } +  +@@ -200,6 +200,16 @@ + } +  +  ++#ifdef LNUM_COMPLEX ++LUALIB_API lua_Complex luaL_checkcomplex (lua_State *L, int narg) { ++  lua_Complex c = lua_tocomplex(L, narg); ++  if (c == 0 && !lua_isnumber(L, narg))  /* avoid extra test when c is not 0 */ ++    tag_error(L, narg, LUA_TNUMBER); ++  return c; ++} ++#endif ++ ++ + LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { +   if (!lua_getmetatable(L, obj))  /* no metatable? */ +     return 0; +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lauxlib.h lua-5.1.3-patched/src/lauxlib.h +--- ../lua-5.1.3/src/lauxlib.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lauxlib.h	2008-03-12 23:15:22.000000000 +0200 +@@ -57,6 +57,12 @@ + LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); + LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, +                                           lua_Integer def); ++#define luaL_checkint32(L,narg) ((int)luaL_checkinteger(L,narg)) ++#define luaL_optint32(L,narg,def) ((int)luaL_optinteger(L,narg,def)) ++ ++#ifdef LNUM_COMPLEX ++  LUALIB_API lua_Complex (luaL_checkcomplex) (lua_State *L, int narg); ++#endif +  + LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); + LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +Binary files ../lua-5.1.3/src/lauxlib.o and lua-5.1.3-patched/src/lauxlib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lbaselib.c lua-5.1.3-patched/src/lbaselib.c +--- ../lua-5.1.3/src/lbaselib.c	2008-01-20 15:53:22.000000000 +0200 ++++ lua-5.1.3-patched/src/lbaselib.c	2008-03-13 10:42:50.000000000 +0200 +@@ -18,7 +18,9 @@ +  + #include "lauxlib.h" + #include "lualib.h" +- ++#include "llimits.h" ++#include "lobject.h" ++#include "lapi.h" +  +  +  +@@ -54,20 +56,25 @@ +   int base = luaL_optint(L, 2, 10); +   if (base == 10) {  /* standard conversion */ +     luaL_checkany(L, 1); +-    if (lua_isnumber(L, 1)) { +-      lua_pushnumber(L, lua_tonumber(L, 1)); ++    if (lua_isnumber(L, 1)) {       /* numeric string, or a number */ ++      lua_pushvalue_as_number(L,1);     /* API extension (not to lose accuracy here) */ +       return 1; +-    } ++	} +   } +   else { +     const char *s1 = luaL_checkstring(L, 1); +     char *s2; +-    unsigned long n; ++    unsigned LUA_INTEGER n; +     luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); +-    n = strtoul(s1, &s2, base); ++    n = lua_str2ul(s1, &s2, base); +     if (s1 != s2) {  /* at least one valid digit? */ +       while (isspace((unsigned char)(*s2))) s2++;  /* skip trailing spaces */ +       if (*s2 == '\0') {  /* no invalid trailing characters? */ ++	   ++		/* Push as number, there needs to be separate 'luaB_tointeger' for ++		 * when the caller wants to preserve the bits (matters if unsigned ++		 * values are used). ++		 */ +         lua_pushnumber(L, (lua_Number)n); +         return 1; +       } +@@ -144,7 +151,7 @@ +   luaL_checktype(L, 2, LUA_TTABLE); +   getfunc(L, 0); +   lua_pushvalue(L, 2); +-  if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { ++  if (lua_isnumber(L, 1) && lua_tointeger(L, 1) == 0) { +     /* change environment of current thread */ +     lua_pushthread(L); +     lua_insert(L, -2); +@@ -209,7 +216,7 @@ +       return 1; +     } +     default: { +-      lua_pushnumber(L, res); ++      lua_pushinteger(L, res); +       return 1; +     } +   } +@@ -629,6 +636,8 @@ +   luaL_register(L, "_G", base_funcs); +   lua_pushliteral(L, LUA_VERSION); +   lua_setglobal(L, "_VERSION");  /* set global _VERSION */ ++  lua_pushliteral(L, LUA_LNUM); ++  lua_setglobal(L, "_LNUM");  /* "[complex] double|float|ldouble int32|int64" */ +   /* `ipairs' and `pairs' need auxliliary functions as upvalues */ +   auxopen(L, "ipairs", luaB_ipairs, ipairsaux); +   auxopen(L, "pairs", luaB_pairs, luaB_next); +Binary files ../lua-5.1.3/src/lbaselib.o and lua-5.1.3-patched/src/lbaselib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lcode.c lua-5.1.3-patched/src/lcode.c +--- ../lua-5.1.3/src/lcode.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/lcode.c	2008-03-19 10:02:51.000000000 +0200 +@@ -22,13 +22,18 @@ + #include "lopcodes.h" + #include "lparser.h" + #include "ltable.h" ++#include "lnum.h" +  +  + #define hasjumps(e)	((e)->t != (e)->f) +  +- + static int isnumeral(expdesc *e) { +-  return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); ++  int ek= ++#ifdef LNUM_COMPLEX ++    (e->k == VKNUM2) || ++#endif ++    (e->k == VKINT) || (e->k == VKNUM); ++  return (ek && e->t == NO_JUMP && e->f == NO_JUMP); + } +  +  +@@ -231,12 +236,16 @@ +   TValue *idx = luaH_set(L, fs->h, k); +   Proto *f = fs->f; +   int oldsize = f->sizek; +-  if (ttisnumber(idx)) { +-    lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); +-    return cast_int(nvalue(idx)); ++  if (ttype(idx)==LUA_TNUMBER) { ++    luai_normalize(idx); ++    lua_assert( ttype(idx)==LUA_TINT );     /* had no fraction */ ++  } ++  if (ttisint(idx)) { ++    lua_assert(luaO_rawequalObj(&fs->f->k[ivalue(idx)], v)); ++    return cast_int(ivalue(idx)); +   } +   else {  /* constant not found; create a new entry */ +-    setnvalue(idx, cast_num(fs->nk)); ++    setivalue(idx, fs->nk); +     luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, +                     MAXARG_Bx, "constant table overflow"); +     while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); +@@ -261,6 +270,21 @@ + } +  +  ++int luaK_integerK (FuncState *fs, lua_Integer r) { ++  TValue o; ++  setivalue(&o, r); ++  return addk(fs, &o, &o); ++} ++ ++ ++#ifdef LNUM_COMPLEX ++static int luaK_imagK (FuncState *fs, lua_Number r) { ++  TValue o; ++  setnvalue_complex(&o, r*I); ++  return addk(fs, &o, &o); ++} ++#endif ++ + static int boolK (FuncState *fs, int b) { +   TValue o; +   setbvalue(&o, b); +@@ -359,6 +383,16 @@ +       luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); +       break; +     } ++    case VKINT: { ++      luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival)); ++      break; ++    } ++#ifdef LNUM_COMPLEX ++    case VKNUM2: { ++      luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval)); ++      break; ++    } ++#endif +     case VRELOCABLE: { +       Instruction *pc = &getcode(fs, e); +       SETARG_A(*pc, reg); +@@ -444,6 +478,10 @@ + int luaK_exp2RK (FuncState *fs, expdesc *e) { +   luaK_exp2val(fs, e); +   switch (e->k) { ++#ifdef LNUM_COMPLEX ++    case VKNUM2: ++#endif ++    case VKINT: +     case VKNUM: +     case VTRUE: +     case VFALSE: +@@ -451,6 +489,10 @@ +       if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */ +         e->u.s.info = (e->k == VNIL)  ? nilK(fs) : +                       (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : ++                      (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) : ++#ifdef LNUM_COMPLEX ++                      (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) : ++#endif +                                         boolK(fs, (e->k == VTRUE)); +         e->k = VK; +         return RKASK(e->u.s.info); +@@ -540,7 +582,10 @@ +   int pc;  /* pc of last jump */ +   luaK_dischargevars(fs, e); +   switch (e->k) { +-    case VK: case VKNUM: case VTRUE: { ++#ifdef LNUM_COMPLEX ++    case VKNUM2: ++#endif ++    case VKINT: case VK: case VKNUM: case VTRUE: { +       pc = NO_JUMP;  /* always true; do nothing */ +       break; +     } +@@ -598,7 +643,10 @@ +       e->k = VTRUE; +       break; +     } +-    case VK: case VKNUM: case VTRUE: { ++#ifdef LNUM_COMPLEX ++    case VKNUM2: ++#endif ++    case VKINT: case VK: case VKNUM: case VTRUE: { +       e->k = VFALSE; +       break; +     } +@@ -634,25 +682,70 @@ +  + static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { +   lua_Number v1, v2, r; ++  int vkres= VKNUM; +   if (!isnumeral(e1) || !isnumeral(e2)) return 0; +-  v1 = e1->u.nval; +-  v2 = e2->u.nval; ++ ++  /* real and imaginary parts don't mix. */ ++#ifdef LNUM_COMPLEX ++  if (e1->k == VKNUM2) { ++    if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0;  ++    vkres= VKNUM2; } ++  else if (e2->k == VKNUM2) { return 0; } ++#endif ++  if ((e1->k == VKINT) && (e2->k == VKINT)) { ++    lua_Integer i1= e1->u.ival, i2= e2->u.ival; ++    lua_Integer rr; ++    int done= 0; ++    /* Integer/integer calculations (may end up producing floating point) */ ++    switch (op) { ++      case OP_ADD: done= try_addint( &rr, i1, i2 ); break; ++      case OP_SUB: done= try_subint( &rr, i1, i2 ); break; ++      case OP_MUL: done= try_mulint( &rr, i1, i2 ); break; ++      case OP_DIV: done= try_divint( &rr, i1, i2 ); break; ++      case OP_MOD: done= try_modint( &rr, i1, i2 ); break; ++      case OP_POW: done= try_powint( &rr, i1, i2 ); break; ++      case OP_UNM: done= try_unmint( &rr, i1 ); break; ++      default:     done= 0; break; ++    } ++    if (done) { ++      e1->u.ival = rr;  /* remained within integer range */ ++      return 1; ++    } ++  } ++  v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval; ++  v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval; ++ +   switch (op) { +     case OP_ADD: r = luai_numadd(v1, v2); break; +     case OP_SUB: r = luai_numsub(v1, v2); break; +-    case OP_MUL: r = luai_nummul(v1, v2); break; ++    case OP_MUL:  ++#ifdef LNUM_COMPLEX ++        if (vkres==VKNUM2) return 0;    /* leave to runtime (could do here, but not worth it?) */ ++#endif ++        r = luai_nummul(v1, v2); break; +     case OP_DIV: +       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */ +-      r = luai_numdiv(v1, v2); break; ++#ifdef LNUM_COMPLEX ++        if (vkres==VKNUM2) return 0;    /* leave to runtime */ ++#endif ++        r = luai_numdiv(v1, v2); break; +     case OP_MOD: +       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */ ++#ifdef LNUM_COMPLEX ++      if (vkres==VKNUM2) return 0;    /* leave to runtime */ ++#endif +       r = luai_nummod(v1, v2); break; +-    case OP_POW: r = luai_numpow(v1, v2); break; ++    case OP_POW:  ++#ifdef LNUM_COMPLEX ++      if (vkres==VKNUM2) return 0;    /* leave to runtime */ ++#endif ++      r = luai_numpow(v1, v2); break; +     case OP_UNM: r = luai_numunm(v1); break; +     case OP_LEN: return 0;  /* no constant folding for 'len' */ +     default: lua_assert(0); r = 0; break; +   } +   if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */ ++  e1->k = cast(expkind,vkres); +   e1->u.nval = r; +   return 1; + } +@@ -696,7 +789,8 @@ +  + void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { +   expdesc e2; +-  e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; ++  e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; ++ +   switch (op) { +     case OPR_MINUS: { +       if (!isnumeral(e)) +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lcode.h lua-5.1.3-patched/src/lcode.h +--- ../lua-5.1.3/src/lcode.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lcode.h	2008-03-03 12:47:53.000000000 +0200 +@@ -71,6 +71,6 @@ + LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); + LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); + LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +- ++LUAI_FUNC int luaK_integerK (FuncState *fs, lua_Integer r); +  + #endif +Binary files ../lua-5.1.3/src/lcode.o and lua-5.1.3-patched/src/lcode.o differ +Binary files ../lua-5.1.3/src/ldblib.o and lua-5.1.3-patched/src/ldblib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ldebug.c lua-5.1.3-patched/src/ldebug.c +--- ../lua-5.1.3/src/ldebug.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/ldebug.c	2008-03-06 22:41:08.000000000 +0200 +@@ -183,7 +183,7 @@ +     int *lineinfo = f->l.p->lineinfo; +     int i; +     for (i=0; i<f->l.p->sizelineinfo; i++) +-      setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); ++      setbvalue(luaH_setint(L, t, lineinfo[i]), 1); +     sethvalue(L, L->top, t);  +   } +   incr_top(L); +@@ -550,7 +550,7 @@ +  + void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { +   const char *name = NULL; +-  const char *t = luaT_typenames[ttype(o)]; ++  const char *t = luaT_typenames[ttype_ext(o)]; +   const char *kind = (isinstack(L->ci, o)) ? +                          getobjname(L, L->ci, cast_int(o - L->base), &name) : +                          NULL; +@@ -578,8 +578,8 @@ +  +  + int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { +-  const char *t1 = luaT_typenames[ttype(p1)]; +-  const char *t2 = luaT_typenames[ttype(p2)]; ++  const char *t1 = luaT_typenames[ttype_ext(p1)]; ++  const char *t2 = luaT_typenames[ttype_ext(p2)]; +   if (t1[2] == t2[2]) +     luaG_runerror(L, "attempt to compare two %s values", t1); +   else +Binary files ../lua-5.1.3/src/ldebug.o and lua-5.1.3-patched/src/ldebug.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ldo.c lua-5.1.3-patched/src/ldo.c +--- ../lua-5.1.3/src/ldo.c	2008-01-19 00:31:22.000000000 +0200 ++++ lua-5.1.3-patched/src/ldo.c	2008-03-06 22:41:31.000000000 +0200 +@@ -219,9 +219,9 @@ +     luaC_checkGC(L); +     htab = luaH_new(L, nvar, 1);  /* create `arg' table */ +     for (i=0; i<nvar; i++)  /* put extra arguments into `arg' table */ +-      setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); ++      setobj2n(L, luaH_setint(L, htab, i+1), L->top - nvar + i); +     /* store counter in field `n' */ +-    setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); ++    setivalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), nvar); +   } + #endif +   /* move fixed parameters to final position */ +Binary files ../lua-5.1.3/src/ldo.o and lua-5.1.3-patched/src/ldo.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ldump.c lua-5.1.3-patched/src/ldump.c +--- ../lua-5.1.3/src/ldump.c	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/ldump.c	2008-03-03 12:47:53.000000000 +0200 +@@ -52,6 +52,11 @@ +  DumpVar(x,D); + } +  ++static void DumpInteger(lua_Integer x, DumpState* D) ++{ ++ DumpVar(x,D); ++} ++ + static void DumpVector(const void* b, int n, size_t size, DumpState* D) + { +  DumpInt(n,D); +@@ -93,8 +98,11 @@ + 	DumpChar(bvalue(o),D); + 	break; +    case LUA_TNUMBER: +-	DumpNumber(nvalue(o),D); ++	DumpNumber(nvalue_fast(o),D); + 	break; ++   case LUA_TINT: ++	DumpInteger(ivalue(o),D); ++    break; +    case LUA_TSTRING: + 	DumpString(rawtsvalue(o),D); + 	break; +Binary files ../lua-5.1.3/src/ldump.o and lua-5.1.3-patched/src/ldump.o differ +Binary files ../lua-5.1.3/src/lfunc.o and lua-5.1.3-patched/src/lfunc.o differ +Binary files ../lua-5.1.3/src/lgc.o and lua-5.1.3-patched/src/lgc.o differ +Binary files ../lua-5.1.3/src/liblua.a and lua-5.1.3-patched/src/liblua.a differ +Binary files ../lua-5.1.3/src/linit.o and lua-5.1.3-patched/src/linit.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/liolib.c lua-5.1.3-patched/src/liolib.c +--- ../lua-5.1.3/src/liolib.c	2008-01-18 19:47:43.000000000 +0200 ++++ lua-5.1.3-patched/src/liolib.c	2008-03-19 10:10:09.000000000 +0200 +@@ -9,6 +9,7 @@ + #include <stdio.h> + #include <stdlib.h> + #include <string.h> ++#include <ctype.h> +  + #define liolib_c + #define LUA_LIB +@@ -18,7 +19,8 @@ + #include "lauxlib.h" + #include "lualib.h" +  +- ++#include "lnum.h" ++#include "llex.h" +  + #define IO_INPUT	1 + #define IO_OUTPUT	2 +@@ -269,6 +271,13 @@ + ** ======================================================= + */ +  ++/* ++* Many problems if we intend the same 'n' format specifier (see 'file:read()') ++* to work for both FP and integer numbers, without losing their accuracy. So ++* we don't. 'n' reads numbers as floating points, 'i' as integers. Old code ++* remains valid, but won't provide full integer accuracy (this only matters ++* with float FP and/or 64-bit integers). ++*/ +  + static int read_number (lua_State *L, FILE *f) { +   lua_Number d; +@@ -279,6 +288,43 @@ +   else return 0;  /* read fails */ + } +  ++static int read_integer (lua_State *L, FILE *f) { ++  lua_Integer i; ++  if (fscanf(f, LUA_INTEGER_SCAN, &i) == 1) { ++    lua_pushinteger(L, i); ++    return 1; ++  } ++  else return 0;  /* read fails */ ++} ++ ++#ifdef LNUM_COMPLEX ++static int read_complex (lua_State *L, FILE *f) { ++  /* NNN / NNNi / NNN+MMMi / NNN-MMMi */ ++  lua_Number a,b; ++  if (fscanf(f, LUA_NUMBER_SCAN, &a) == 1) { ++    int c=fgetc(f); ++    switch(c) { ++        case 'i': ++            lua_pushcomplex(L, a*I); ++            return 1; ++        case '+': ++        case '-': ++            /* "i" is consumed if at the end; just 'NNN+MMM' will most likely ++             * behave as if "i" was there? (TBD: test) ++             */ ++            if (fscanf(f, LUA_NUMBER_SCAN "i", &b) == 1) { ++                lua_pushcomplex(L, a+ (c=='+' ? b:-b)*I); ++                return 1; ++            } ++    } ++    ungetc( c,f ); ++    lua_pushnumber(L,a);  /*real part only*/ ++    return 1; ++  } ++  return 0;  /* read fails */ ++} ++#endif ++ +  + static int test_eof (lua_State *L, FILE *f) { +   int c = getc(f); +@@ -352,6 +398,14 @@ +           case 'n':  /* number */ +             success = read_number(L, f); +             break; ++          case 'i':  /* integer (full accuracy) */ ++            success = read_integer(L, f); ++            break; ++#ifdef LNUM_COMPLEX ++          case 'c':  /* complex */ ++            success = read_complex(L, f); ++            break; ++#endif +           case 'l':  /* line */ +             success = read_line(L, f); +             break; +@@ -412,9 +466,10 @@ +   int status = 1; +   for (; nargs--; arg++) { +     if (lua_type(L, arg) == LUA_TNUMBER) { +-      /* optimization: could be done exactly as for strings */ +-      status = status && +-          fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; ++      if (lua_isinteger(L,arg)) ++          status = status && fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) > 0; ++      else ++          status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; +     } +     else { +       size_t l; +@@ -457,7 +512,7 @@ +   static const char *const modenames[] = {"no", "full", "line", NULL}; +   FILE *f = tofile(L); +   int op = luaL_checkoption(L, 2, NULL, modenames); +-  lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); ++  size_t sz = luaL_optint32(L, 3, LUAL_BUFFERSIZE); +   int res = setvbuf(f, NULL, mode[op], sz); +   return pushresult(L, res == 0, NULL); + } +Binary files ../lua-5.1.3/src/liolib.o and lua-5.1.3-patched/src/liolib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/llex.c lua-5.1.3-patched/src/llex.c +--- ../lua-5.1.3/src/llex.c	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/llex.c	2008-03-04 11:10:30.000000000 +0200 +@@ -22,6 +22,7 @@ + #include "lstring.h" + #include "ltable.h" + #include "lzio.h" ++#include "lnum.h" +  +  +  +@@ -34,13 +35,17 @@ +  +  + /* ORDER RESERVED */ +-const char *const luaX_tokens [] = { ++static const char *const luaX_tokens [] = { +     "and", "break", "do", "else", "elseif", +     "end", "false", "for", "function", "if", +     "in", "local", "nil", "not", "or", "repeat", +     "return", "then", "true", "until", "while", +     "..", "...", "==", ">=", "<=", "~=", +     "<number>", "<name>", "<string>", "<eof>", ++    "<integer>", ++#ifdef LNUM_COMPLEX ++    "<number2>", ++#endif +     NULL + }; +  +@@ -90,7 +95,11 @@ +   switch (token) { +     case TK_NAME: +     case TK_STRING: ++    case TK_INT: +     case TK_NUMBER: ++#ifdef LNUM_COMPLEX ++    case TK_NUMBER2: ++#endif +       save(ls, '\0'); +       return luaZ_buffer(ls->buff); +     default: +@@ -173,23 +182,27 @@ +     if (p[n] == from) p[n] = to; + } +  +- +-static void trydecpoint (LexState *ls, SemInfo *seminfo) { ++/* TK_NUMBER (/ TK_NUMBER2) */ ++static int trydecpoint (LexState *ls, SemInfo *seminfo) { +   /* format error: try to update decimal point separator */ +   struct lconv *cv = localeconv(); +   char old = ls->decpoint; ++  int ret; +   ls->decpoint = (cv ? cv->decimal_point[0] : '.'); +   buffreplace(ls, old, ls->decpoint);  /* try updated decimal separator */ +-  if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { ++  ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, NULL); ++  if (!ret) { +     /* format error with correct decimal point: no more options */ +     buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */ +     luaX_lexerror(ls, "malformed number", TK_NUMBER); +   } ++  return ret; + } +  +  +-/* LUA_NUMBER */ +-static void read_numeral (LexState *ls, SemInfo *seminfo) { ++/* TK_NUMBER / TK_INT (/TK_NUMBER2) */ ++static int read_numeral (LexState *ls, SemInfo *seminfo) { ++  int ret; +   lua_assert(isdigit(ls->current)); +   do { +     save_and_next(ls); +@@ -200,8 +213,9 @@ +     save_and_next(ls); +   save(ls, '\0'); +   buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */ +-  if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r))  /* format error? */ +-    trydecpoint(ls, seminfo); /* try to update decimal point separator */ ++  ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, &seminfo->i ); ++  if (!ret) return trydecpoint(ls, seminfo); /* try to update decimal point separator */ ++  return ret; + } +  +  +@@ -329,6 +343,7 @@ + } +  +  ++/* char / TK_* */ + static int llex (LexState *ls, SemInfo *seminfo) { +   luaZ_resetbuffer(ls->buff); +   for (;;) { +@@ -400,8 +415,7 @@ +         } +         else if (!isdigit(ls->current)) return '.'; +         else { +-          read_numeral(ls, seminfo); +-          return TK_NUMBER; ++          return read_numeral(ls, seminfo); +         } +       } +       case EOZ: { +@@ -414,8 +428,7 @@ +           continue; +         } +         else if (isdigit(ls->current)) { +-          read_numeral(ls, seminfo); +-          return TK_NUMBER; ++          return read_numeral(ls, seminfo); +         } +         else if (isalpha(ls->current) || ls->current == '_') { +           /* identifier or reserved word */ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/llex.h lua-5.1.3-patched/src/llex.h +--- ../lua-5.1.3/src/llex.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/llex.h	2008-03-04 11:12:08.000000000 +0200 +@@ -29,19 +29,22 @@ +   TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, +   /* other terminal symbols */ +   TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, +-  TK_NAME, TK_STRING, TK_EOS ++  TK_NAME, TK_STRING, TK_EOS, TK_INT ++#ifdef LNUM_COMPLEX ++  , TK_NUMBER2   /* imaginary constants: Ni */  ++#endif + }; +  + /* number of reserved words */ + #define NUM_RESERVED	(cast(int, TK_WHILE-FIRST_RESERVED+1)) +  +  +-/* array with token `names' */ +-LUAI_DATA const char *const luaX_tokens []; +- +- ++/* SemInfo is a local data structure of 'llex.c', used for carrying a string ++ * or a number. A separate token (TK_*) will tell, how to interpret the data. ++ */       + typedef union { +   lua_Number r; ++  lua_Integer i; +   TString *ts; + } SemInfo;  /* semantics information */ +  +Binary files ../lua-5.1.3/src/llex.o and lua-5.1.3-patched/src/llex.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/llimits.h lua-5.1.3-patched/src/llimits.h +--- ../lua-5.1.3/src/llimits.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/llimits.h	2008-03-04 11:16:43.000000000 +0200 +@@ -49,6 +49,7 @@ +  + /* result of a `usual argument conversion' over lua_Number */ + typedef LUAI_UACNUMBER l_uacNumber; ++typedef LUAI_UACINTEGER l_uacInteger; +  +  + /* internal assertions for in-house debugging */ +@@ -80,7 +81,6 @@ + #define cast_int(i)	cast(int, (i)) +  +  +- + /* + ** type for virtual-machine instructions + ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lmathlib.c lua-5.1.3-patched/src/lmathlib.c +--- ../lua-5.1.3/src/lmathlib.c	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lmathlib.c	2008-03-26 11:32:25.000000000 +0200 +@@ -4,7 +4,6 @@ + ** See Copyright Notice in lua.h + */ +  +- + #include <stdlib.h> + #include <math.h> +  +@@ -16,113 +15,210 @@ + #include "lauxlib.h" + #include "lualib.h" +  ++/* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we ++ * don't intrude the code libs internal functions. ++ */ ++#ifdef LNUM_COMPLEX ++# include "lnum.h"     ++#endif +  + #undef PI +-#define PI (3.14159265358979323846) +-#define RADIANS_PER_DEGREE (PI/180.0) +- ++#ifdef LNUM_FLOAT ++# define PI (3.14159265358979323846F) ++#elif defined(M_PI) ++# define PI M_PI ++#else ++# define PI (3.14159265358979323846264338327950288) ++#endif ++#define RADIANS_PER_DEGREE (PI/180) +  ++#undef HUGE ++#ifdef LNUM_FLOAT ++# define HUGE HUGE_VALF ++#elif defined(LNUM_LDOUBLE) ++# define HUGE HUGE_VALL ++#else ++# define HUGE HUGE_VAL ++#endif +  + static int math_abs (lua_State *L) { +-  lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_sin (lua_State *L) { +-  lua_pushnumber(L, sin(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_sinh (lua_State *L) { +-  lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_cos (lua_State *L) { +-  lua_pushnumber(L, cos(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_cosh (lua_State *L) { +-  lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_tan (lua_State *L) { +-  lua_pushnumber(L, tan(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_tanh (lua_State *L) { +-  lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_asin (lua_State *L) { +-  lua_pushnumber(L, asin(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_acos (lua_State *L) { +-  lua_pushnumber(L, acos(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_atan (lua_State *L) { +-  lua_pushnumber(L, atan(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_atan2 (lua_State *L) { +-  lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); ++  /* scalars only */ ++  lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); +   return 1; + } +  + static int math_ceil (lua_State *L) { +-  lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_Complex v= luaL_checkcomplex(L, 1); ++  lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I); ++#else ++  lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_floor (lua_State *L) { +-  lua_pushnumber(L, floor(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_Complex v= luaL_checkcomplex(L, 1); ++  lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I); ++#else ++  lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  +-static int math_fmod (lua_State *L) { +-  lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); ++static int math_fmod (lua_State *L) {   ++  /* scalars only */ ++  lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); +   return 1; + } +  + static int math_modf (lua_State *L) { +-  double ip; +-  double fp = modf(luaL_checknumber(L, 1), &ip); ++  /* scalars only */ ++  lua_Number ip; ++  lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip); +   lua_pushnumber(L, ip); +   lua_pushnumber(L, fp); +   return 2; + } +  + static int math_sqrt (lua_State *L) { +-  lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_pow (lua_State *L) { +-  lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); ++#ifdef LNUM_COMPLEX ++  /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).  ++  * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h". ++  */ ++  lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2))); ++#else ++  lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2))); ++#endif +   return 1; + } +  + static int math_log (lua_State *L) { +-  lua_pushnumber(L, log(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_log10 (lua_State *L) { +-  lua_pushnumber(L, log10(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)  ++  */ ++  lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10)); ++#else ++  lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  + static int math_exp (lua_State *L) { +-  lua_pushnumber(L, exp(luaL_checknumber(L, 1))); ++#ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1))); ++#else ++  lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1))); ++#endif +   return 1; + } +  +@@ -138,19 +234,20 @@ +  + static int math_frexp (lua_State *L) { +   int e; +-  lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); ++  lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e)); +   lua_pushinteger(L, e); +   return 2; + } +  + static int math_ldexp (lua_State *L) { +-  lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); ++  lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2))); +   return 1; + } +  +  +  + static int math_min (lua_State *L) { ++  /* scalars only */ +   int n = lua_gettop(L);  /* number of arguments */ +   lua_Number dmin = luaL_checknumber(L, 1); +   int i; +@@ -165,6 +262,7 @@ +  +  + static int math_max (lua_State *L) { ++  /* scalars only */ +   int n = lua_gettop(L);  /* number of arguments */ +   lua_Number dmax = luaL_checknumber(L, 1); +   int i; +@@ -182,25 +280,20 @@ +   /* the `%' avoids the (rare) case of r==1, and is needed also because on +      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ +   lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; +-  switch (lua_gettop(L)) {  /* check number of arguments */ +-    case 0: {  /* no arguments */ +-      lua_pushnumber(L, r);  /* Number between 0 and 1 */ +-      break; +-    } +-    case 1: {  /* only upper limit */ +-      int u = luaL_checkint(L, 1); +-      luaL_argcheck(L, 1<=u, 1, "interval is empty"); +-      lua_pushnumber(L, floor(r*u)+1);  /* int between 1 and `u' */ +-      break; +-    } +-    case 2: {  /* lower and upper limits */ +-      int l = luaL_checkint(L, 1); +-      int u = luaL_checkint(L, 2); +-      luaL_argcheck(L, l<=u, 2, "interval is empty"); +-      lua_pushnumber(L, floor(r*(u-l+1))+l);  /* int between `l' and `u' */ +-      break; +-    } +-    default: return luaL_error(L, "wrong number of arguments"); ++  int n= lua_gettop(L);  /* number of arguments */ ++  if (n==0) {	/* no arguments: range [0,1) */ ++    lua_pushnumber(L, r); ++  } else if (n<=2) {	/* int range [1,u] or [l,u] */ ++    int l= n==1 ? 1 : luaL_checkint(L, 1); ++    int u = luaL_checkint(L, n); ++    int tmp; ++    lua_Number d; ++    luaL_argcheck(L, l<=u, n, "interval is empty"); ++    d= _LF(floor)(r*(u-l+1)); ++    lua_number2int(tmp,d); ++    lua_pushinteger(L, l+tmp); ++  } else { ++    return luaL_error(L, "wrong number of arguments"); +   } +   return 1; + } +@@ -211,6 +304,66 @@ +   return 0; + } +  ++/*  ++* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C) ++*/ ++#if __STDC_VERSION__ >= 199901L ++static int math_acosh (lua_State *L) { ++# ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1))); ++# else ++  lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1))); ++# endif ++  return 1; ++} ++static int math_asinh (lua_State *L) { ++# ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1))); ++# else ++  lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1))); ++# endif ++  return 1; ++} ++static int math_atanh (lua_State *L) { ++# ifdef LNUM_COMPLEX ++  lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1))); ++# else ++  lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1))); ++# endif ++  return 1; ++} ++#endif ++ ++/*  ++ * C99 complex functions, not covered above. ++*/ ++#ifdef LNUM_COMPLEX ++static int math_arg (lua_State *L) { ++  lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1))); ++  return 1; ++} ++ ++static int math_imag (lua_State *L) { ++  lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1))); ++  return 1; ++} ++ ++static int math_real (lua_State *L) { ++  lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1))); ++  return 1; ++} ++ ++static int math_conj (lua_State *L) { ++  lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1))); ++  return 1; ++} ++ ++static int math_proj (lua_State *L) { ++  lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1))); ++  return 1; ++} ++#endif ++ +  + static const luaL_Reg mathlib[] = { +   {"abs",   math_abs}, +@@ -241,6 +394,18 @@ +   {"sqrt",  math_sqrt}, +   {"tanh",   math_tanh}, +   {"tan",   math_tan}, ++#if __STDC_VERSION__ >= 199901L ++  {"acosh",  math_acosh}, ++  {"asinh",  math_asinh}, ++  {"atanh",  math_atanh}, ++#endif ++#ifdef LNUM_COMPLEX ++  {"arg",   math_arg}, ++  {"imag",  math_imag}, ++  {"real",  math_real}, ++  {"conj",  math_conj}, ++  {"proj",  math_proj}, ++#endif +   {NULL, NULL} + }; +  +@@ -252,8 +417,10 @@ +   luaL_register(L, LUA_MATHLIBNAME, mathlib); +   lua_pushnumber(L, PI); +   lua_setfield(L, -2, "pi"); +-  lua_pushnumber(L, HUGE_VAL); ++  lua_pushnumber(L, HUGE); +   lua_setfield(L, -2, "huge"); ++  lua_pushinteger(L, LUA_INTEGER_MAX ); ++  lua_setfield(L, -2, "hugeint"); + #if defined(LUA_COMPAT_MOD) +   lua_getfield(L, -1, "fmod"); +   lua_setfield(L, -2, "mod"); +Binary files ../lua-5.1.3/src/lmathlib.o and lua-5.1.3-patched/src/lmathlib.o differ +Binary files ../lua-5.1.3/src/lmem.o and lua-5.1.3-patched/src/lmem.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lnum.c lua-5.1.3-patched/src/lnum.c +--- ../lua-5.1.3/src/lnum.c	1970-01-01 02:00:00.000000000 +0200 ++++ lua-5.1.3-patched/src/lnum.c	2008-03-26 11:32:25.000000000 +0200 +@@ -0,0 +1,312 @@ ++/* ++** $Id: lnum.c,v ... $ ++** Internal number model ++** See Copyright Notice in lua.h ++*/ ++ ++#include <stdlib.h> ++#include <math.h> ++#include <ctype.h> ++#include <string.h> ++#include <stdio.h> ++#include <errno.h> ++ ++#define lnum_c ++#define LUA_CORE ++ ++#include "lua.h" ++#include "llex.h" ++#include "lnum.h" ++ ++/* ++** lua_real2str converts a (non-complex) number to a string. ++** lua_str2real converts a string to a (non-complex) number. ++*/ ++#define lua_real2str(s,n)  sprintf((s), LUA_NUMBER_FMT, (n)) ++ ++/* ++* Note: Only 'strtod()' is part of ANSI C; others are C99 and ++* may need '--std=c99' compiler setting (at least on Ubuntu 7.10). ++*  ++* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'. ++* References to '_strtold()' exist but don't compile. It seems best ++* to leave Windows users with DOUBLE only (or compile with MinGW). ++* ++* In practise, using '(long double)strtod' is a risky thing, since ++* it will cause accuracy loss in reading in numbers, and such losses ++* will pile up in later processing. Get a real 'strtold()' or don't ++* use that mode at all. ++*/ ++#ifdef LNUM_DOUBLE ++# define lua_str2real	strtod ++#elif defined(LNUM_FLOAT) ++# define lua_str2real	strtof ++#elif defined(LNUM_LDOUBLE) ++# define lua_str2real	strtold ++#endif ++ ++#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v)) ++ ++/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number) ++*/ ++void luaO_num2buf( char *s, const TValue *o ) ++{ ++  lua_Number n; ++  lua_assert( ttisnumber(o) ); ++ ++  /* Reason to handle integers differently is not only speed, but accuracy as ++   * well. We want to make any integer tostring() without roundings, at all. ++   */ ++  if (ttisint(o)) { ++    lua_integer2str( s, ivalue(o) ); ++    return; ++  } ++  n= nvalue_fast(o); ++  lua_real2str(s, n); ++ ++#ifdef LNUM_COMPLEX ++  lua_Number n2= nvalue_img_fast(o); ++  if (n2!=0) {   /* Postfix with +-Ni */ ++      int re0= (n == 0); ++      char *s2= re0 ? s : strchr(s,'\0');  ++      if ((!re0) && (n2>0)) *s2++= '+'; ++      lua_real2str( s2, n2 ); ++      strcat(s2,"i"); ++  } ++#endif ++} ++ ++/* ++* If a LUA_TNUMBER has integer value, give it. ++*/ ++int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) { ++  lua_Number d; ++  lua_Integer i; ++ ++  lua_assert( ttype(o)==LUA_TNUMBER ); ++  lua_assert( ref ); ++#ifdef LNUM_COMPLEX ++  if (nvalue_img_fast(o)!=0) return 0; ++#endif ++  d= nvalue_fast(o); ++  lua_number2integer(i, d); ++  if (cast_num(i) == d) { ++    *ref= i; return 1; ++  } ++  return 0; ++} ++ ++/*  ++ * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good, ++ * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason. ++ * ++ * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not ++ * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to ++ * require hex values to fit 'lua_Integer' or give an error that they don't? ++ * ++ * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits. ++ * Numerical value of 0xff..ff will be -1, if used in calculations. ++ *  ++ * Returns: TK_INT for a valid integer, '*endptr_ref' updated ++ *          TK_NUMBER for seemingly numeric, to be parsed as floating point ++ *          0 for bad characters, not a number (or '0x' out of range) ++ */ ++static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) { ++  char *endptr; ++  /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX); ++   * we don't have to check 'errno' here. ++   */ ++  unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10); ++  if (endptr == s) return 0;  /* nothing numeric */ ++  if (v==0 && *endptr=='x') { ++    errno= 0;   /* needs to be set, 'strtoul[l]' does not clear it */ ++    v= lua_str2ul(endptr+1, &endptr, 16);  /* retry as hex, unsigned range */ ++    if (errno==ERANGE) {   /* clamped to 0xff..ff */ ++#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE) ++      return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */ ++#else ++      return 0;  /* Reject the number */ ++#endif ++    } ++  } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) { ++    return TK_NUMBER;	/* not in signed range, or has '.', 'e' etc. trailing */ ++  } ++  *res= (lua_Integer)v; ++  *endptr_ref= endptr; ++  return TK_INT; ++} ++ ++/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */ ++int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) { ++  char *endptr; ++  int ret= TK_NUMBER; ++  /* Check integers first, if caller is allowing.  ++   * If 'res2'==NULL, they're only looking for floating point.  ++   */ ++  if (res_i) { ++    ret= luaO_str2i(s,res_i,&endptr); ++    if (ret==0) return 0; ++  } ++  if (ret==TK_NUMBER) { ++    lua_assert(res_n); ++    /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..." ++     *       numbers; it will read '0' and spit 'x' as endptr. ++     *       This means hex constants not fitting in 'lua_Integer' won't  ++     *       be read in at all. What to do? ++     */ ++    *res_n = lua_str2real(s, &endptr); ++    if (endptr == s) return 0;  /* conversion failed */ ++    /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */ ++#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64) ++    if (*res_n==0 && *endptr=='x') { ++      /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number' ++       * integer bits  ++       */ ++      unsigned __int64 v= _strtoui64( s, &endptr, 16 ); ++      /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */ ++      *res_n= cast_num(v); ++      if (*res_n != v) return 0;    /* Would have lost accuracy */ ++    } ++#endif ++#ifdef LNUM_COMPLEX ++    if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; } ++#endif ++  } ++  if (*endptr) { ++    while (isspace(cast(unsigned char, *endptr))) endptr++; ++    if (*endptr) return 0;  /* invalid trail */ ++  } ++  return ret; ++} ++ ++ ++/* Functions for finding out, when integer operations remain in range ++ * (and doing them). ++ */ ++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++  lua_Integer v= ib+ic; /* may overflow */ ++  if (ib>0 && ic>0)      { if (v < 0) return 0; /*overflow, use floats*/ } ++  else if (ib<0 && ic<0) { if (v >= 0) return 0; } ++  *r= v; ++  return 1; ++} ++ ++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++  lua_Integer v= ib-ic; /* may overflow */ ++  if (ib>=0 && ic<0)     { if (v < 0) return 0; /*overflow, use floats*/ } ++  else if (ib<0 && ic>0) { if (v >= 0) return 0; } ++  *r= v; ++  return 1; ++} ++ ++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++  if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) { ++    lua_Integer b= luai_abs(ib), c= luai_abs(ic); ++    if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) { ++      *r= ib*ic;  /* no overflow */ ++      return 1; ++    } ++  } else if (ib==0 || ic==0) { ++    *r= 0; return 1; ++  } ++ ++  /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating  ++   * point will not cause accuracy loss. ++   */ ++  if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) { ++    *r= LUA_INTEGER_MIN; ++    return 1; ++  } ++  return 0; ++} ++ ++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++  /* N/0: leave to float side, to give an error ++  */ ++  if (ic==0) return 0; ++ ++  /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1 ++  */ ++  if (ic==LUA_INTEGER_MIN) { ++    if (ib==LUA_INTEGER_MIN) { *r=1; return 1; } ++    if (ib==0) { *r=0; return 1; } ++ ++  /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division  ++   *    causes non-integer results, or there is no accuracy loss in int->fp->int ++   *    conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23). ++   */ ++  } else if (ib==LUA_INTEGER_MIN) { ++    lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) ); ++    lua_Integer i; lua_number2integer(i,d); ++    if (cast_num(i)==d) { *r= i; return 1; } ++   ++  } else { ++    /* Note: We _can_ use ANSI C mod here, even on negative values, since ++     *       we only test for == 0 (the sign would be implementation dependent). ++     */ ++     if (ib%ic == 0) { *r= ib/ic; return 1; } ++  } ++ ++  return 0; ++} ++ ++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++  if (ic!=0) { ++    /* ANSI C can be trusted when b%c==0, or when values are non-negative.  ++     * b - (floor(b/c) * c) ++     *   --> ++     * + +: b - (b/c) * c (b % c can be used) ++     * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C) ++     * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C) ++     * - +: b - (b/c-1) * c (when b!=-c) ++     * + -: b - (b/c-1) * c (when b!=-c) ++     * ++     * o MIN%MIN ends up 0, via overflow in calcs but that does not matter. ++     * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow, ++     *   but that does not matter, results do. ++     */ ++    lua_Integer v= ib % ic; ++    if ( v!=0 && (ib<0 || ic<0) ) { ++      v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic; ++    }       ++    /* Result should always have same sign as 2nd argument. (PIL2) */ ++    lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 ); ++    *r= v; ++    return 1; ++  } ++  return 0;  /* let float side return NaN */ ++} ++ ++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { ++ ++    /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers  ++     * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32 ++     * but not 23-bit float mantissa).  ++     * ++     * The current solution is dumb, but it works and uses little code. Use of ++     * integer powers is not anticipated to be very frequent (apart from 2^x, ++     * which is separately optimized). ++     */ ++  if (ib==0) *r=0; ++  else if (ic<0) return 0;  /* FP realm */ ++  else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic;   /* 1,2,4,...2^30 | 2^62 optimization */ ++  else if (ic==0) *r=1; ++  else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1; ++  else { ++    lua_Integer x= ib; ++    while( --ic ) { ++      if (!try_mulint( &x, x, ib )) ++        return 0; /* FP realm */ ++    } ++    *r= x; ++  } ++  return 1; ++} ++ ++int try_unmint( lua_Integer *r, lua_Integer ib ) { ++  /* Negating LUA_INTEGER_MIN leaves the range. */ ++  if ( ib != LUA_INTEGER_MIN )   ++    { *r= -ib; return 1; } ++  return 0; ++} ++ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lnum.h lua-5.1.3-patched/src/lnum.h +--- ../lua-5.1.3/src/lnum.h	1970-01-01 02:00:00.000000000 +0200 ++++ lua-5.1.3-patched/src/lnum.h	2008-03-19 11:35:51.000000000 +0200 +@@ -0,0 +1,116 @@ ++/* ++** $Id: lnum.h,v ... $ ++** Internal Number model ++** See Copyright Notice in lua.h ++*/ ++ ++#ifndef lnum_h ++#define lnum_h ++ ++#include <math.h> ++ ++#include "lobject.h" ++ ++/* ++** The luai_num* macros define the primitive operations over 'lua_Number's ++** (not 'lua_Integer's, not 'lua_Complex'). ++*/ ++#define luai_numadd(a,b)	((a)+(b)) ++#define luai_numsub(a,b)	((a)-(b)) ++#define luai_nummul(a,b)	((a)*(b)) ++#define luai_numdiv(a,b)	((a)/(b)) ++#define luai_nummod(a,b)	((a) - _LF(floor)((a)/(b))*(b)) ++#define luai_numpow(a,b)	(_LF(pow)(a,b)) ++#define luai_numunm(a)		(-(a)) ++#define luai_numeq(a,b)	    ((a)==(b)) ++#define luai_numlt(a,b)	    ((a)<(b)) ++#define luai_numle(a,b)	    ((a)<=(b)) ++#define luai_numisnan(a)	(!luai_numeq((a), (a))) ++ ++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ); ++int try_unmint( lua_Integer *r, lua_Integer ib ); ++ ++#ifdef LNUM_COMPLEX ++  static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; } ++  static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; } ++  static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; } ++  static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; } ++  static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; } ++ ++/*  ++ * C99 does not provide modulus for complex numbers. It most likely is not ++ * meaningful at all. ++ */ ++ ++/*  ++ * Complex power ++ * ++ * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 ->  ++ * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367) ++ *  ++ * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) + ++ *                 = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i ++ * r = sqrt(a^2+b^2), t = arctan( b/a ) ++ *  ++ * Reference: <http://home.att.net/~srschmitt/complexnumbers.html> ++ * Could also be calculated using: x^y = exp(ln(x)*y) ++ * ++ * Note: Defined here (and not in .c) so 'lmathlib.c' can share the  ++ *       implementation. ++ */ ++  static inline ++  lua_Complex luai_vectpow( lua_Complex a, lua_Complex b ) ++  { ++# if 1 ++    lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a); ++    lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b); ++     ++    if (ai==0 && bi==0) {     /* a^c (real) */ ++        return luai_numpow( ar, br ); ++    }  ++ ++    int br_int= (int)br; ++     ++    if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) {  ++        /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX }  ++        */ ++        lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br ); ++        lua_Number cos_z, sin_z; ++ ++        /* Situation depends upon c (N) in the following manner: ++         *  ++         * N%4==0                                => cos(c*t)=1, sin(c*t)=0 ++         * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1 ++         * N%4==2 or N%4==-2                     => cos(c*t)=-1, sin(c*t)=0 ++         * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1 ++         */ ++      int br_int_abs = br_int<0 ? -br_int:br_int; ++       ++      switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) { ++        case 0:             cos_z=1, sin_z=0; break; ++        case 2: case -2:    cos_z=-1, sin_z=0; break; ++        case 1: case -3:    cos_z=0, sin_z=1; break; ++        case 3: case -1:    cos_z=0, sin_z=-1; break; ++        default:            lua_assert(0); return 0; ++      } ++      return k*cos_z + (k*sin_z)*I; ++    } ++# endif ++    return _LF(cpow) ( a, b ); ++  } ++#endif ++ ++LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2); ++LUAI_FUNC void luaO_num2buf( char *s, const TValue *o ); ++ ++LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ); ++ ++#define luai_normalize(o) \ ++{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); } ++ ++#endif +Binary files ../lua-5.1.3/src/lnum.o and lua-5.1.3-patched/src/lnum.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lnum_config.h lua-5.1.3-patched/src/lnum_config.h +--- ../lua-5.1.3/src/lnum_config.h	1970-01-01 02:00:00.000000000 +0200 ++++ lua-5.1.3-patched/src/lnum_config.h	2008-03-26 11:32:25.000000000 +0200 +@@ -0,0 +1,221 @@ ++/* ++** $Id: lnum_config.h,v ... $ ++** Internal Number model ++** See Copyright Notice in lua.h ++*/ ++ ++#ifndef lnum_config_h ++#define lnum_config_h ++ ++/* ++** Default number modes ++*/ ++#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE) ++# define LNUM_DOUBLE ++#endif ++#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64) ++# define LNUM_INT32 ++#endif ++ ++/* ++** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C). ++*/ ++#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L) ++# error "Need C99 for complex (use '--std=c99' or similar)" ++#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER) ++# error "Need C99 for 'long double' (use '--std=c99' or similar)" ++#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L) ++/* LNUM_FLOAT not supported on Windows */ ++# error "Need C99 for 'float' (use '--std=c99' or similar)" ++#endif ++  ++/* ++** Number mode identifier to accompany the version string. ++*/ ++#ifdef LNUM_COMPLEX ++# define _LNUM1 "complex " ++#else ++# define _LNUM1 "" ++#endif ++#ifdef LNUM_DOUBLE ++# define _LNUM2 "double" ++#elif defined(LNUM_FLOAT) ++# define _LNUM2 "float" ++#elif defined(LNUM_LDOUBLE) ++# define _LNUM2 "ldouble" ++#endif ++#ifdef LNUM_INT32 ++# define _LNUM3 "int32" ++#elif defined(LNUM_INT64) ++# define _LNUM3 "int64" ++#elif defined(LNUM_INT16) ++# define _LNUM3 "int16" ++#endif ++#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3 ++ ++/* ++** LUA_NUMBER is the type of floating point number in Lua ++** LUA_NUMBER_SCAN is the format for reading numbers. ++** LUA_NUMBER_FMT is the format for writing numbers. ++*/ ++#ifdef LNUM_FLOAT ++# define LUA_NUMBER         float ++# define LUA_NUMBER_SCAN    "%f" ++# define LUA_NUMBER_FMT     "%g"   ++#elif (defined LNUM_DOUBLE) ++# define LUA_NUMBER	        double ++# define LUA_NUMBER_SCAN    "%lf" ++# define LUA_NUMBER_FMT     "%.14g" ++#elif (defined LNUM_LDOUBLE) ++# define LUA_NUMBER         long double ++# define LUA_NUMBER_SCAN    "%Lg" ++# define LUA_NUMBER_FMT     "%.20Lg" ++#endif ++ ++ ++/*  ++** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result. ++** ++**  double:  24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0) ++**  int64:   21 (19 digits, sign, and \0) ++**  long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0) ++**           30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0) ++*/ ++#ifdef LNUM_LDOUBLE ++# define _LUAI_MN2S 44 ++#else ++# define _LUAI_MN2S 24 ++#endif ++ ++#ifdef LNUM_COMPLEX ++# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S) ++#else ++# define LUAI_MAXNUMBER2STR _LUAI_MN2S ++#endif ++ ++/* ++** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger. ++** LUA_INTEGER_SCAN is the format for reading integers ++** LUA_INTEGER_FMT is the format for writing integers ++** ++** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead. ++*/ ++#ifdef LNUM_INT32 ++# if LUAI_BITSINT > 16 ++#  define LUA_INTEGER   int ++#  define LUA_INTEGER_SCAN "%d" ++#  define LUA_INTEGER_FMT "%d" ++# else ++/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with ++ *       'printf()' operations. Also 'unsigned ptrdiff_t' is invalid. ++ */ ++#  define LUA_INTEGER   long ++#  define LUA_INTEGER_SCAN "%ld" ++#  define LUA_INTEGER_FMT "%ld" ++# endif ++# define LUA_INTEGER_MAX 0x7FFFFFFF             /* 2^31-1 */ ++/* */ ++#elif defined(LNUM_INT64) ++# define LUA_INTEGER	long long ++# ifdef _MSC_VER ++#  define lua_str2ul    _strtoui64 ++# else ++#  define lua_str2ul    strtoull ++# endif ++# define LUA_INTEGER_SCAN "%lld" ++# define LUA_INTEGER_FMT "%lld" ++# define LUA_INTEGER_MAX 0x7fffffffffffffffLL       /* 2^63-1 */  ++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL)   /* -2^63 */ ++/* */ ++#elif defined(LNUM_INT16) ++# if LUAI_BITSINT > 16 ++#  define LUA_INTEGER    short ++#  define LUA_INTEGER_SCAN "%hd" ++#  define LUA_INTEGER_FMT "%hd" ++# else ++#  define LUA_INTEGER    int ++#  define LUA_INTEGER_SCAN "%d" ++#  define LUA_INTEGER_FMT "%d" ++# endif ++# define LUA_INTEGER_MAX 0x7FFF             /* 2^16-1 */ ++#endif ++ ++#ifndef lua_str2ul ++# define lua_str2ul (unsigned LUA_INTEGER)strtoul ++#endif ++#ifndef LUA_INTEGER_MIN ++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1)  /* -2^16|32 */ ++#endif ++ ++/* ++@@ lua_number2int is a macro to convert lua_Number to int. ++@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. ++** CHANGE them if you know a faster way to convert a lua_Number to ++** int (with any rounding method and without throwing errors) in your ++** system. In Pentium machines, a naive typecast from double to int ++** in C is extremely slow, so any alternative is worth trying. ++*/ ++ ++/* On a Pentium, resort to a trick */ ++#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ ++    (defined(__i386) || defined (_M_IX86) || defined(__i386__)) ++ ++/* On a Microsoft compiler, use assembler */ ++# if defined(_MSC_VER) ++#  define lua_number2int(i,d)   __asm fld d   __asm fistp i ++# else ++ ++/* the next trick should work on any Pentium, but sometimes clashes ++   with a DirectX idiosyncrasy */ ++union luai_Cast { double l_d; long l_l; }; ++#  define lua_number2int(i,d) \ ++  { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } ++# endif ++ ++# ifndef LNUM_INT64 ++#  define lua_number2integer    lua_number2int ++# endif ++ ++/* this option always works, but may be slow */ ++#else ++# define lua_number2int(i,d)        ((i)=(int)(d)) ++#endif ++ ++/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion  ++ *       since it can lose precision. Others do require 'long long' there.   ++ */ ++#ifndef lua_number2integer ++# define lua_number2integer(i,d)    ((i)=(lua_Integer)(d)) ++#endif ++ ++/* ++** 'luai_abs()' to give absolute value of 'lua_Integer' ++*/ ++#ifdef LNUM_INT32 ++# define luai_abs abs ++#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L) ++# define luai_abs llabs ++#else ++# define luai_abs(v) ((v) >= 0 ? (v) : -(v)) ++#endif ++ ++/* ++** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number. ++** LUAI_UACINTEGER the same, over an integer. ++*/ ++#define LUAI_UACNUMBER	double ++#define LUAI_UACINTEGER long ++ ++/* ANSI C only has math funcs for 'double. C99 required for float and long double ++ * variants. ++ */ ++#ifdef LNUM_DOUBLE ++# define _LF(name) name ++#elif defined(LNUM_FLOAT) ++# define _LF(name) name ## f ++#elif defined(LNUM_LDOUBLE) ++# define _LF(name) name ## l ++#endif ++ ++#endif ++ +Binary files ../lua-5.1.3/src/loadlib.o and lua-5.1.3-patched/src/loadlib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lobject.c lua-5.1.3-patched/src/lobject.c +--- ../lua-5.1.3/src/lobject.c	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lobject.c	2008-03-14 11:08:49.000000000 +0200 +@@ -21,7 +21,8 @@ + #include "lstate.h" + #include "lstring.h" + #include "lvm.h" +- ++#include "llex.h" ++#include "lnum.h" +  +  + const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; +@@ -70,12 +71,31 @@ +  +  + int luaO_rawequalObj (const TValue *t1, const TValue *t2) { +-  if (ttype(t1) != ttype(t2)) return 0; ++  if (!ttype_ext_same(t1,t2)) return 0; +   else switch (ttype(t1)) { +     case LUA_TNIL: +       return 1; ++    case LUA_TINT: ++      if (ttype(t2)==LUA_TINT) ++        return ivalue(t1) == ivalue(t2); ++      else {  /* t1:int, t2:num */ ++#ifdef LNUM_COMPLEX ++        if (nvalue_img_fast(t2) != 0) return 0; ++#endif ++        /* Avoid doing accuracy losing cast, if possible. */ ++        lua_Integer tmp; ++        if (tt_integer_valued(t2,&tmp))  ++          return ivalue(t1) == tmp; ++        else ++          return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) ); ++        } +     case LUA_TNUMBER: +-      return luai_numeq(nvalue(t1), nvalue(t2)); ++        if (ttype(t2)==LUA_TINT) ++          return luaO_rawequalObj(t2, t1);  /* swap LUA_TINT to left */ ++#ifdef LNUM_COMPLEX ++        if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0; ++#endif ++        return luai_numeq(nvalue_fast(t1), nvalue_fast(t2)); +     case LUA_TBOOLEAN: +       return bvalue(t1) == bvalue(t2);  /* boolean true must be 1 !! */ +     case LUA_TLIGHTUSERDATA: +@@ -86,21 +106,6 @@ +   } + } +  +- +-int luaO_str2d (const char *s, lua_Number *result) { +-  char *endptr; +-  *result = lua_str2number(s, &endptr); +-  if (endptr == s) return 0;  /* conversion failed */ +-  if (*endptr == 'x' || *endptr == 'X')  /* maybe an hexadecimal constant? */ +-    *result = cast_num(strtoul(s, &endptr, 16)); +-  if (*endptr == '\0') return 1;  /* most common case */ +-  while (isspace(cast(unsigned char, *endptr))) endptr++; +-  if (*endptr != '\0') return 0;  /* invalid trailing characters? */ +-  return 1; +-} +- +- +- + static void pushstr (lua_State *L, const char *str) { +   setsvalue2s(L, L->top, luaS_new(L, str)); +   incr_top(L); +@@ -131,7 +136,11 @@ +         break; +       } +       case 'd': { +-        setnvalue(L->top, cast_num(va_arg(argp, int))); ++        /* This is tricky for 64-bit integers; maybe they even cannot be ++         * supported on all compilers; depends on the conversions applied to ++         * variable argument lists. TBD: test! ++         */ ++        setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger)); +         incr_top(L); +         break; +       } +@@ -212,3 +221,4 @@ +     } +   } + } ++ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lobject.h lua-5.1.3-patched/src/lobject.h +--- ../lua-5.1.3/src/lobject.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lobject.h	2008-03-19 11:40:13.000000000 +0200 +@@ -17,7 +17,11 @@ +  +  + /* tags for values visible from Lua */ +-#define LAST_TAG	LUA_TTHREAD ++#if LUA_TINT > LUA_TTHREAD ++# define LAST_TAG   LUA_TINT ++#else ++# define LAST_TAG	LUA_TTHREAD ++#endif +  + #define NUM_TAGS	(LAST_TAG+1) +  +@@ -59,7 +63,12 @@ + typedef union { +   GCObject *gc; +   void *p; ++#ifdef LNUM_COMPLEX ++  lua_Complex n; ++#else +   lua_Number n; ++#endif ++  lua_Integer i; +   int b; + } Value; +  +@@ -77,7 +86,11 @@ +  + /* Macros to test type */ + #define ttisnil(o)	(ttype(o) == LUA_TNIL) +-#define ttisnumber(o)	(ttype(o) == LUA_TNUMBER) ++#define ttisint(o) (ttype(o) == LUA_TINT) ++#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER)) ++#ifdef LNUM_COMPLEX ++# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0)) ++#endif + #define ttisstring(o)	(ttype(o) == LUA_TSTRING) + #define ttistable(o)	(ttype(o) == LUA_TTABLE) + #define ttisfunction(o)	(ttype(o) == LUA_TFUNCTION) +@@ -90,7 +103,25 @@ + #define ttype(o)	((o)->tt) + #define gcvalue(o)	check_exp(iscollectable(o), (o)->value.gc) + #define pvalue(o)	check_exp(ttislightuserdata(o), (o)->value.p) +-#define nvalue(o)	check_exp(ttisnumber(o), (o)->value.n) ++ ++#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) ) ++#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) ) ++ ++/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER. ++ */ ++#ifdef LNUM_COMPLEX ++#  define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )    ++#  define nvalue_fast(o)     ( _LF(creal) ( nvalue_complex_fast(o) ) ) ++#  define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) ) ++#  define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n ) ++#  define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) )  ++#  define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) )  ++#else ++# define nvalue(o)	check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n ) ++# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )    ++#endif ++#define ivalue(o)	check_exp( ttype(o)==LUA_TINT, (o)->value.i ) ++ + #define rawtsvalue(o)	check_exp(ttisstring(o), &(o)->value.gc->ts) + #define tsvalue(o)	(&rawtsvalue(o)->tsv) + #define rawuvalue(o)	check_exp(ttisuserdata(o), &(o)->value.gc->u) +@@ -116,8 +147,27 @@ + /* Macros to set values */ + #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) +  +-#define setnvalue(obj,x) \ +-  { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } ++/* Must not have side effects, 'x' may be expression. ++*/ ++#define setivalue(obj,x) \ ++    { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; } ++ ++# define setnvalue(obj,x) \ ++    { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; } ++ ++/* Note: Complex always has "inline", both are C99. ++*/ ++#ifdef LNUM_COMPLEX ++  static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) { ++    lua_assert( _LF(cimag)(x) != 0 ); ++    obj->value.n= x; obj->tt= LUA_TNUMBER; ++  } ++  static inline void setnvalue_complex( TValue *obj, lua_Complex x ) { ++    if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); } ++    else { obj->value.n= x; obj->tt= LUA_TNUMBER; } ++  } ++#endif ++ +  + #define setpvalue(obj,x) \ +   { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } +@@ -155,9 +205,6 @@ +     i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ +     checkliveness(G(L),i_o); } +  +- +- +- + #define setobj(L,obj1,obj2) \ +   { const TValue *o2=(obj2); TValue *o1=(obj1); \ +     o1->value = o2->value; o1->tt=o2->tt; \ +@@ -185,8 +232,11 @@ +  + #define setttype(obj, tt) (ttype(obj) = (tt)) +  +- +-#define iscollectable(o)	(ttype(o) >= LUA_TSTRING) ++#if LUA_TINT >= LUA_TSTRING ++# define iscollectable(o)	((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT)) ++#else ++# define iscollectable(o)	(ttype(o) >= LUA_TSTRING) ++#endif +  +  +  +@@ -370,12 +420,10 @@ + LUAI_FUNC int luaO_int2fb (unsigned int x); + LUAI_FUNC int luaO_fb2int (int x); + LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); + LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, +                                                        va_list argp); + LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); + LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); +  +- + #endif +  +Binary files ../lua-5.1.3/src/lobject.o and lua-5.1.3-patched/src/lobject.o differ +Binary files ../lua-5.1.3/src/lopcodes.o and lua-5.1.3-patched/src/lopcodes.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/loslib.c lua-5.1.3-patched/src/loslib.c +--- ../lua-5.1.3/src/loslib.c	2008-01-18 18:38:18.000000000 +0200 ++++ lua-5.1.3-patched/src/loslib.c	2008-03-19 11:02:22.000000000 +0200 +@@ -186,15 +186,30 @@ +   } +   if (t == (time_t)(-1)) +     lua_pushnil(L); +-  else +-    lua_pushnumber(L, (lua_Number)t); ++  else { ++     /* On float systems the pushed value must be an integer, NOT a number. ++      * Otherwise, accuracy is lost in the time_t->float conversion. ++      */ ++#ifdef LNUM_FLOAT ++     lua_pushinteger(L, (lua_Integer) t); ++#else ++     lua_pushnumber(L, (lua_Number) t); ++#endif ++     } +   return 1; + } +  +  + static int os_difftime (lua_State *L) { ++#ifdef LNUM_FLOAT ++  lua_Integer i= (lua_Integer) ++    difftime( (time_t)(luaL_checkinteger(L, 1)), ++              (time_t)(luaL_optinteger(L, 2, 0))); ++  lua_pushinteger(L, i); ++#else +   lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), +                              (time_t)(luaL_optnumber(L, 2, 0)))); ++#endif +   return 1; + } +  +Binary files ../lua-5.1.3/src/loslib.o and lua-5.1.3-patched/src/loslib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lparser.c lua-5.1.3-patched/src/lparser.c +--- ../lua-5.1.3/src/lparser.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/lparser.c	2008-03-06 21:58:41.000000000 +0200 +@@ -33,7 +33,6 @@ +  + #define luaY_checklimit(fs,v,l,m)	if ((v)>(l)) errorlimit(fs,l,m) +  +- + /* + ** nodes for block list (list of active blocks) + */ +@@ -72,7 +71,7 @@ +   const char *msg = (fs->f->linedefined == 0) ? +     luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : +     luaO_pushfstring(fs->L, "function at line %d has more than %d %s", +-                            fs->f->linedefined, limit, what); ++                            (fs->f->linedefined), limit, what); +   luaX_lexerror(fs->ls, msg, 0); + } +  +@@ -733,6 +732,18 @@ +       v->u.nval = ls->t.seminfo.r; +       break; +     } ++    case TK_INT: { ++      init_exp(v, VKINT, 0); ++      v->u.ival = ls->t.seminfo.i; ++      break; ++    } ++#ifdef LNUM_COMPLEX ++    case TK_NUMBER2: { ++      init_exp(v, VKNUM2, 0); ++      v->u.nval = ls->t.seminfo.r; ++      break; ++    } ++#endif +     case TK_STRING: { +       codestring(ls, v, ls->t.seminfo.ts); +       break; +@@ -1079,7 +1090,7 @@ +   if (testnext(ls, ',')) +     exp1(ls);  /* optional step */ +   else {  /* default step = 1 */ +-    luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); ++    luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1)); +     luaK_reserveregs(fs, 1); +   } +   forbody(ls, base, line, 1, 1); +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lparser.h lua-5.1.3-patched/src/lparser.h +--- ../lua-5.1.3/src/lparser.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lparser.h	2008-03-06 22:01:11.000000000 +0200 +@@ -31,7 +31,11 @@ +   VRELOCABLE,	/* info = instruction pc */ +   VNONRELOC,	/* info = result register */ +   VCALL,	/* info = instruction pc */ +-  VVARARG	/* info = instruction pc */ ++  VVARARG,	/* info = instruction pc */ ++  VKINT     /* ival = integer value */ ++#ifdef LNUM_COMPLEX ++  ,VKNUM2   /* nval = imaginary value */ ++#endif + } expkind; +  + typedef struct expdesc { +@@ -39,6 +43,7 @@ +   union { +     struct { int info, aux; } s; +     lua_Number nval; ++    lua_Integer ival; +   } u; +   int t;  /* patch list of `exit when true' */ +   int f;  /* patch list of `exit when false' */ +Binary files ../lua-5.1.3/src/lparser.o and lua-5.1.3-patched/src/lparser.o differ +Binary files ../lua-5.1.3/src/lstate.o and lua-5.1.3-patched/src/lstate.o differ +Binary files ../lua-5.1.3/src/lstring.o and lua-5.1.3-patched/src/lstring.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lstrlib.c lua-5.1.3-patched/src/lstrlib.c +--- ../lua-5.1.3/src/lstrlib.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/lstrlib.c	2008-03-12 23:15:22.000000000 +0200 +@@ -42,8 +42,8 @@ + static int str_sub (lua_State *L) { +   size_t l; +   const char *s = luaL_checklstring(L, 1, &l); +-  ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); +-  ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); ++  ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l); ++  ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l); +   if (start < 1) start = 1; +   if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; +   if (start <= end) +@@ -105,8 +105,8 @@ + static int str_byte (lua_State *L) { +   size_t l; +   const char *s = luaL_checklstring(L, 1, &l); +-  ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); +-  ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); ++  ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l); ++  ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l); +   int n, i; +   if (posi <= 0) posi = 1; +   if ((size_t)pose > l) pose = l; +@@ -495,7 +495,7 @@ +   size_t l1, l2; +   const char *s = luaL_checklstring(L, 1, &l1); +   const char *p = luaL_checklstring(L, 2, &l2); +-  ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; ++  ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1; +   if (init < 0) init = 0; +   else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; +   if (find && (lua_toboolean(L, 4) ||  /* explicit request? */ +@@ -689,7 +689,7 @@ + ** maximum size of each format specification (such as '%-099.99d') + ** (+10 accounts for %99.99x plus margin of error) + */ +-#define MAX_FORMAT	(sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) ++#define MAX_FORMAT	(sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10) +  +  + static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { +@@ -746,9 +746,9 @@ + static void addintlen (char *form) { +   size_t l = strlen(form); +   char spec = form[l - 1]; +-  strcpy(form + l - 1, LUA_INTFRMLEN); +-  form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; +-  form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; ++  const char *tmp= LUA_INTEGER_FMT;   /* "%lld" or "%ld" */ ++  strcpy(form + l - 1, tmp+1); ++  form[l + sizeof(LUA_INTEGER_FMT)-4] = spec; + } +  +  +@@ -776,12 +776,12 @@ +         } +         case 'd':  case 'i': { +           addintlen(form); +-          sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); ++          sprintf(buff, form, luaL_checkinteger(L, arg)); +           break; +         } +         case 'o':  case 'u':  case 'x':  case 'X': { +           addintlen(form); +-          sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); ++          sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg)); +           break; +         } +         case 'e':  case 'E': case 'f': +Binary files ../lua-5.1.3/src/lstrlib.o and lua-5.1.3-patched/src/lstrlib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ltable.c lua-5.1.3-patched/src/ltable.c +--- ../lua-5.1.3/src/ltable.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/ltable.c	2008-03-26 13:04:20.000000000 +0200 +@@ -33,6 +33,7 @@ + #include "lobject.h" + #include "lstate.h" + #include "ltable.h" ++#include "lnum.h" +  +  + /* +@@ -51,25 +52,15 @@ +    + #define hashstr(t,str)  hashpow2(t, (str)->tsv.hash) + #define hashboolean(t,p)        hashpow2(t, p) +- ++#define hashint(t,i)    hashpow2(t,i) +  + /* + ** for some types, it is better to avoid modulus by power of 2, as + ** they tend to have many 2 factors. + */ + #define hashmod(t,n)	(gnode(t, ((n) % ((sizenode(t)-1)|1)))) +- +- + #define hashpointer(t,p)	hashmod(t, IntPoint(p)) +  +- +-/* +-** number of ints inside a lua_Number +-*/ +-#define numints		cast_int(sizeof(lua_Number)/sizeof(int)) +- +- +- + #define dummynode		(&dummynode_) +  + static const Node dummynode_ = { +@@ -80,27 +71,46 @@ +  + /* + ** hash for lua_Numbers ++** ++** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0) + */ + static Node *hashnum (const Table *t, lua_Number n) { +-  unsigned int a[numints]; +-  int 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]); ++  const unsigned int *p= cast(const unsigned int *,&n); ++  unsigned int sum= *p; ++  unsigned int m= sizeof(lua_Number)/sizeof(int); ++  unsigned int i; ++  /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of  ++   * 'n' is read; the actual size of long double is only 80 bits = 10 bytes. ++   * Linux x86 has 'm'==3, and does not require reduction. ++   */ ++#if defined(LNUM_LDOUBLE) && defined(__i386__) ++  if (m>3) m--; ++#endif ++  for (i = 1; i < m; i++) sum += p[i]; ++  return hashmod(t, sum); + } +  +  +- + /* + ** returns the `main' position of an element in a table (that is, the index + ** of its hash value) ++** ++** Floating point numbers with integer value give the hash position of the ++** integer (so they use the same table position). + */ + static Node *mainposition (const Table *t, const TValue *key) { ++  lua_Integer i; +   switch (ttype(key)) { +     case LUA_TNUMBER: +-      return hashnum(t, nvalue(key)); ++      if (tt_integer_valued(key,&i))  ++        return hashint(t, i); ++#ifdef LNUM_COMPLEX ++      if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0)) ++        return gnode(t, 0);  /* 0 and -0 to give same hash */ ++#endif ++      return hashnum(t, nvalue_fast(key)); ++    case LUA_TINT: ++      return hashint(t, ivalue(key)); +     case LUA_TSTRING: +       return hashstr(t, rawtsvalue(key)); +     case LUA_TBOOLEAN: +@@ -116,16 +126,20 @@ + /* + ** returns the index for `key' if `key' is an appropriate key to live in + ** the array part of the table, -1 otherwise. ++** ++** Anything <=0 is taken as not being in the array part. + */ +-static int arrayindex (const TValue *key) { +-  if (ttisnumber(key)) { +-    lua_Number n = nvalue(key); +-    int k; +-    lua_number2int(k, n); +-    if (luai_numeq(cast_num(k), n)) +-      return k; ++static int arrayindex (const TValue *key, int max) { ++  lua_Integer k; ++  switch( ttype(key) ) { ++    case LUA_TINT: ++      k= ivalue(key); break; ++    case LUA_TNUMBER: ++      if (tt_integer_valued(key,&k)) break; ++    default: ++      return -1;  /* not to be used as array index */ +   } +-  return -1;  /* `key' did not match some condition */ ++  return ((k>0) && (k <= max)) ? cast_int(k) : -1; + } +  +  +@@ -137,8 +151,8 @@ + static int findindex (lua_State *L, Table *t, StkId key) { +   int i; +   if (ttisnil(key)) return -1;  /* first iteration */ +-  i = arrayindex(key); +-  if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */ ++  i = arrayindex(key, t->sizearray); ++  if (i>0)  /* inside array part? */ +     return i-1;  /* yes; that's the index (corrected to C) */ +   else { +     Node *n = mainposition(t, key); +@@ -163,7 +177,7 @@ +   int i = findindex(L, t, key);  /* find original element */ +   for (i++; i < t->sizearray; i++) {  /* try first array part */ +     if (!ttisnil(&t->array[i])) {  /* a non-nil value? */ +-      setnvalue(key, cast_num(i+1)); ++      setivalue(key, i+1); +       setobj2s(L, key+1, &t->array[i]); +       return 1; +     } +@@ -209,8 +223,8 @@ +  +  + static int countint (const TValue *key, int *nums) { +-  int k = arrayindex(key); +-  if (0 < k && k <= MAXASIZE) {  /* is `key' an appropriate array index? */ ++  int k = arrayindex(key,MAXASIZE); ++  if (k>0) {  /* appropriate array index? */ +     nums[ceillog2(k)]++;  /* count as such */ +     return 1; +   } +@@ -308,7 +322,7 @@ +     /* re-insert elements from vanishing slice */ +     for (i=nasize; i<oldasize; i++) { +       if (!ttisnil(&t->array[i])) +-        setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); ++        setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]); +     } +     /* shrink array */ +     luaM_reallocvector(L, t->array, oldasize, nasize, TValue); +@@ -409,7 +423,9 @@ +     othern = mainposition(t, key2tval(mp)); +     if (othern != mp) {  /* is colliding node out of its main position? */ +       /* yes; move colliding node into free position */ +-      while (gnext(othern) != mp) othern = gnext(othern);  /* find previous */ ++      while (gnext(othern) != mp) { ++        othern = gnext(othern);  /* find previous */ ++      } +       gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */ +       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */ +       gnext(mp) = NULL;  /* now `mp' is free */ +@@ -432,17 +448,18 @@ + /* + ** search function for integers + */ +-const TValue *luaH_getnum (Table *t, int key) { ++const TValue *luaH_getint (Table *t, lua_Integer key) { +   /* (1 <= key && key <= t->sizearray) */ +   if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) +     return &t->array[key-1]; +   else { +-    lua_Number nk = cast_num(key); +-    Node *n = hashnum(t, nk); ++    Node *n = hashint(t, key); +     do {  /* check whether `key' is somewhere in the chain */ +-      if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) ++      if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) { +         return gval(n);  /* that's it */ +-      else n = gnext(n); ++      } else {  ++      n = gnext(n); ++    } +     } while (n); +     return luaO_nilobject; +   } +@@ -470,14 +487,12 @@ +   switch (ttype(key)) { +     case LUA_TNIL: return luaO_nilobject; +     case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); ++    case LUA_TINT: return luaH_getint(t, ivalue(key)); +     case LUA_TNUMBER: { +-      int k; +-      lua_Number n = nvalue(key); +-      lua_number2int(k, n); +-      if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ +-        return luaH_getnum(t, k);  /* use specialized version */ +-      /* else go through */ +-    } ++      lua_Integer i; ++      if (tt_integer_valued(key,&i)) ++        return luaH_getint(t,i); ++    } /* pass through */ +     default: { +       Node *n = mainposition(t, key); +       do {  /* check whether `key' is somewhere in the chain */ +@@ -498,20 +513,25 @@ +     return cast(TValue *, p); +   else { +     if (ttisnil(key)) luaG_runerror(L, "table index is nil"); +-    else if (ttisnumber(key) && luai_numisnan(nvalue(key))) +-      luaG_runerror(L, "table index is NaN"); ++    else if (ttype(key)==LUA_TNUMBER) { ++      lua_Integer k; ++      if (luai_numisnan(nvalue_fast(key))) ++        luaG_runerror(L, "table index is NaN"); ++      if (tt_integer_valued(key,&k)) ++        return luaH_setint(L, t, k); ++    } +     return newkey(L, t, key); +   } + } +  +  +-TValue *luaH_setnum (lua_State *L, Table *t, int key) { +-  const TValue *p = luaH_getnum(t, key); ++TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) { ++  const TValue *p = luaH_getint(t, key); +   if (p != luaO_nilobject) +     return cast(TValue *, p); +   else { +     TValue k; +-    setnvalue(&k, cast_num(key)); ++    setivalue(&k, key); +     return newkey(L, t, &k); +   } + } +@@ -533,20 +553,21 @@ +   unsigned int i = j;  /* i is zero or a present index */ +   j++; +   /* find `i' and `j' such that i is present and j is not */ +-  while (!ttisnil(luaH_getnum(t, j))) { ++  while (!ttisnil(luaH_getint(t, j))) { +     i = j; +     j *= 2; +     if (j > cast(unsigned int, MAX_INT)) {  /* overflow? */ +       /* table was built with bad purposes: resort to linear search */ +-      i = 1; +-      while (!ttisnil(luaH_getnum(t, i))) i++; +-      return i - 1; ++      for( i = 1; i<MAX_INT+1; i++ ) { ++        if (ttisnil(luaH_getint(t, i))) break; ++      } ++      return i - 1;  /* up to MAX_INT */ +     } +   } +   /* now do a binary search between them */ +   while (j - i > 1) { +     unsigned int m = (i+j)/2; +-    if (ttisnil(luaH_getnum(t, m))) j = m; ++    if (ttisnil(luaH_getint(t, m))) j = m; +     else i = m; +   } +   return i; +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ltable.h lua-5.1.3-patched/src/ltable.h +--- ../lua-5.1.3/src/ltable.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/ltable.h	2008-03-16 20:49:18.000000000 +0200 +@@ -18,8 +18,8 @@ + #define key2tval(n)	(&(n)->i_key.tvk) +  +  +-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); ++LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); ++LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key); + LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); + LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); + LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +Binary files ../lua-5.1.3/src/ltable.o and lua-5.1.3-patched/src/ltable.o differ +Binary files ../lua-5.1.3/src/ltablib.o and lua-5.1.3-patched/src/ltablib.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/ltm.c lua-5.1.3-patched/src/ltm.c +--- ../lua-5.1.3/src/ltm.c	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/ltm.c	2008-03-06 22:47:33.000000000 +0200 +@@ -19,7 +19,6 @@ + #include "ltm.h" +  +  +- + const char *const luaT_typenames[] = { +   "nil", "boolean", "userdata", "number", +   "string", "table", "function", "userdata", "thread", +@@ -67,6 +66,9 @@ +     case LUA_TUSERDATA: +       mt = uvalue(o)->metatable; +       break; ++    case LUA_TINT: ++      mt = G(L)->mt[LUA_TNUMBER]; ++      break; +     default: +       mt = G(L)->mt[ttype(o)]; +   } +Binary files ../lua-5.1.3/src/ltm.o and lua-5.1.3-patched/src/ltm.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lua.c lua-5.1.3-patched/src/lua.c +--- ../lua-5.1.3/src/lua.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/lua.c	2008-03-26 11:32:25.000000000 +0200 +@@ -16,7 +16,7 @@ +  + #include "lauxlib.h" + #include "lualib.h" +- ++#include "llimits.h" +  +  + static lua_State *globalL = NULL; +@@ -382,6 +382,15 @@ +     l_message(argv[0], "cannot create state: not enough memory"); +     return EXIT_FAILURE; +   } ++  /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers. ++  */ ++#ifdef LNUM_INT16 ++  lua_assert( sizeof(lua_Integer) == 2 ); ++#elif defined(LNUM_INT32) ++  lua_assert( sizeof(lua_Integer) == 4 ); ++#elif defined(LNUM_INT64) ++  lua_assert( sizeof(lua_Integer) == 8 ); ++#endif +   s.argc = argc; +   s.argv = argv; +   status = lua_cpcall(L, &pmain, &s); +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lua.h lua-5.1.3-patched/src/lua.h +--- ../lua-5.1.3/src/lua.h	2008-01-03 17:41:15.000000000 +0200 ++++ lua-5.1.3-patched/src/lua.h	2008-03-19 11:19:34.000000000 +0200 +@@ -19,7 +19,7 @@ + #define LUA_VERSION	"Lua 5.1" + #define LUA_RELEASE	"Lua 5.1.3" + #define LUA_VERSION_NUM	501 +-#define LUA_COPYRIGHT	"Copyright (C) 1994-2008 Lua.org, PUC-Rio" ++#define LUA_COPYRIGHT	"Copyright (C) 1994-2008 Lua.org, PUC-Rio" " (" LUA_LNUM ")" + #define LUA_AUTHORS 	"R. Ierusalimschy, L. H. de Figueiredo & W. Celes" +  +  +@@ -71,6 +71,16 @@ + */ + #define LUA_TNONE		(-1) +  ++/* LUA_TINT is an internal type, not visible to applications. There are three ++ * potential values where it can be tweaked to (code autoadjusts to these): ++ * ++ * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API ++ * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility ++ *     not acceptable for 5.1, maybe 5.2 onwards? ++ *  9: greater than existing (5.1) type values. ++*/ ++#define LUA_TINT (-2) ++ + #define LUA_TNIL		0 + #define LUA_TBOOLEAN		1 + #define LUA_TLIGHTUSERDATA	2 +@@ -139,6 +149,8 @@ + LUA_API int             (lua_type) (lua_State *L, int idx); + LUA_API const char     *(lua_typename) (lua_State *L, int tp); +  ++LUA_API int             (lua_isinteger) (lua_State *L, int idx); ++ + LUA_API int            (lua_equal) (lua_State *L, int idx1, int idx2); + LUA_API int            (lua_rawequal) (lua_State *L, int idx1, int idx2); + LUA_API int            (lua_lessthan) (lua_State *L, int idx1, int idx2); +@@ -244,6 +256,19 @@ + LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); +  +  ++/* ++* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just ++* because the Lua number type is complex. Most C modules would use scalars ++* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when ++* the module really wants to use them. ++*/ ++#ifdef LNUM_COMPLEX ++  #include <complex.h> ++  typedef LUA_NUMBER complex lua_Complex; ++  LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx); ++  LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v); ++#endif ++ +  + /*  + ** =============================================================== +@@ -268,7 +293,12 @@ + #define lua_isboolean(L,n)	(lua_type(L, (n)) == LUA_TBOOLEAN) + #define lua_isthread(L,n)	(lua_type(L, (n)) == LUA_TTHREAD) + #define lua_isnone(L,n)		(lua_type(L, (n)) == LUA_TNONE) +-#define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0) ++ ++#if LUA_TINT < 0 ++# define lua_isnoneornil(L, n)	( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) ) ++#else ++# define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0) ++#endif +  + #define lua_pushliteral(L, s)	\ + 	lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) +@@ -386,3 +416,4 @@ +  +  + #endif ++ +Binary files ../lua-5.1.3/src/lua.o and lua-5.1.3-patched/src/lua.o differ +Binary files ../lua-5.1.3/src/luac and lua-5.1.3-patched/src/luac differ +Binary files ../lua-5.1.3/src/luac.o and lua-5.1.3-patched/src/luac.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/luaconf.h lua-5.1.3-patched/src/luaconf.h +--- ../lua-5.1.3/src/luaconf.h	2008-01-18 19:07:48.000000000 +0200 ++++ lua-5.1.3-patched/src/luaconf.h	2008-03-24 20:28:57.000000000 +0200 +@@ -10,7 +10,9 @@ +  + #include <limits.h> + #include <stddef.h> +- ++#ifdef lua_assert ++# include <assert.h> ++#endif +  + /* + ** ================================================================== +@@ -136,14 +138,38 @@ +  +  + /* +-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +-** machines, ptrdiff_t gives a good choice between int or long.) ++@@ LUAI_BITSINT defines the number of bits in an int. ++** CHANGE here if Lua cannot automatically detect the number of bits of ++** your machine. Probably you do not need to change this. + */ +-#define LUA_INTEGER	ptrdiff_t ++/* avoid overflows in comparison */ ++#if INT_MAX-20 < 32760 ++#define LUAI_BITSINT	16 ++#elif INT_MAX > 2147483640L ++/* int has at least 32 bits */ ++#define LUAI_BITSINT	32 ++#else ++#error "you must define LUA_BITSINT with number of bits in an integer" ++#endif +  +  + /* ++@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode ++@@ LNUM_INT32 | LNUM_INT64: Integer type ++@@ LNUM_COMPLEX: Define for using 'a+bi' numbers ++@@ ++@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT ++@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with  ++@@ 32-bit scalar integer range optimized. ++** ++** These are kept in a separate configuration file mainly for ease of patching ++** (can be changed if integerated to Lua proper). ++*/ ++/*#define LNUM_DOUBLE*/ ++/*#define LNUM_INT32*/ ++#include "lnum_config.h" ++ ++/* + @@ LUA_API is a mark for all core API functions. + @@ LUALIB_API is a mark for all standard library functions. + ** CHANGE them if you need to define those functions in some special way. +@@ -383,22 +409,6 @@ +  +  + /* +-@@ LUAI_BITSINT defines the number of bits in an int. +-** CHANGE here if Lua cannot automatically detect the number of bits of +-** your machine. Probably you do not need to change this. +-*/ +-/* avoid overflows in comparison */ +-#if INT_MAX-20 < 32760 +-#define LUAI_BITSINT	16 +-#elif INT_MAX > 2147483640L +-/* int has at least 32 bits */ +-#define LUAI_BITSINT	32 +-#else +-#error "you must define LUA_BITSINT with number of bits in an integer" +-#endif +- +- +-/* + @@ LUAI_UINT32 is an unsigned integer with at least 32 bits. + @@ LUAI_INT32 is an signed integer with at least 32 bits. + @@ LUAI_UMEM is an unsigned integer big enough to count the total +@@ -425,6 +435,15 @@ + #define LUAI_MEM	long + #endif +  ++/* ++@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char' ++** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99) ++*/ ++#ifdef __cplusplus ++# define LUAI_BOOL bool ++#else ++# define LUAI_BOOL int ++#endif +  + /* + @@ LUAI_MAXCALLS limits the number of nested calls. +@@ -490,101 +509,6 @@ + /* }================================================================== */ +  +  +- +- +-/* +-** {================================================================== +-@@ LUA_NUMBER is the type of numbers in Lua. +-** CHANGE the following definitions only if you want to build Lua +-** with a number type different from double. You may also need to +-** change lua_number2int & lua_number2integer. +-** =================================================================== +-*/ +- +-#define LUA_NUMBER_DOUBLE +-#define LUA_NUMBER	double +- +-/* +-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +-@* over a number. +-*/ +-#define LUAI_UACNUMBER	double +- +- +-/* +-@@ LUA_NUMBER_SCAN is the format for reading numbers. +-@@ LUA_NUMBER_FMT is the format for writing numbers. +-@@ lua_number2str converts a number to a string. +-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +-@@ lua_str2number converts a string to a number. +-*/ +-#define LUA_NUMBER_SCAN		"%lf" +-#define LUA_NUMBER_FMT		"%.14g" +-#define lua_number2str(s,n)	sprintf((s), LUA_NUMBER_FMT, (n)) +-#define LUAI_MAXNUMBER2STR	32 /* 16 digits, sign, point, and \0 */ +-#define lua_str2number(s,p)	strtod((s), (p)) +- +- +-/* +-@@ The luai_num* macros define the primitive operations over numbers. +-*/ +-#if defined(LUA_CORE) +-#include <math.h> +-#define luai_numadd(a,b)	((a)+(b)) +-#define luai_numsub(a,b)	((a)-(b)) +-#define luai_nummul(a,b)	((a)*(b)) +-#define luai_numdiv(a,b)	((a)/(b)) +-#define luai_nummod(a,b)	((a) - floor((a)/(b))*(b)) +-#define luai_numpow(a,b)	(pow(a,b)) +-#define luai_numunm(a)		(-(a)) +-#define luai_numeq(a,b)		((a)==(b)) +-#define luai_numlt(a,b)		((a)<(b)) +-#define luai_numle(a,b)		((a)<=(b)) +-#define luai_numisnan(a)	(!luai_numeq((a), (a))) +-#endif +- +- +-/* +-@@ lua_number2int is a macro to convert lua_Number to int. +-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +-** CHANGE them if you know a faster way to convert a lua_Number to +-** int (with any rounding method and without throwing errors) in your +-** system. In Pentium machines, a naive typecast from double to int +-** in C is extremely slow, so any alternative is worth trying. +-*/ +- +-/* On a Pentium, resort to a trick */ +-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ +-    (defined(__i386) || defined (_M_IX86) || defined(__i386__)) +- +-/* On a Microsoft compiler, use assembler */ +-#if defined(_MSC_VER) +- +-#define lua_number2int(i,d)   __asm fld d   __asm fistp i +-#define lua_number2integer(i,n)		lua_number2int(i, n) +- +-/* the next trick should work on any Pentium, but sometimes clashes +-   with a DirectX idiosyncrasy */ +-#else +- +-union luai_Cast { double l_d; long l_l; }; +-#define lua_number2int(i,d) \ +-  { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +-#define lua_number2integer(i,n)		lua_number2int(i, n) +- +-#endif +- +- +-/* this option always works, but may be slow */ +-#else +-#define lua_number2int(i,d)	((i)=(int)(d)) +-#define lua_number2integer(i,d)	((i)=(lua_Integer)(d)) +- +-#endif +- +-/* }================================================================== */ +- +- + /* + @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. + ** CHANGE it if your system requires alignments larger than double. (For +@@ -728,28 +652,6 @@ + #define luai_userstateyield(L,n)	((void)L) +  +  +-/* +-@@ LUA_INTFRMLEN is the length modifier for integer conversions +-@* in 'string.format'. +-@@ LUA_INTFRM_T is the integer type correspoding to the previous length +-@* modifier. +-** CHANGE them if your system supports long long or does not support long. +-*/ +- +-#if defined(LUA_USELONGLONG) +- +-#define LUA_INTFRMLEN		"ll" +-#define LUA_INTFRM_T		long long +- +-#else +- +-#define LUA_INTFRMLEN		"l" +-#define LUA_INTFRM_T		long +- +-#endif +- +- +- + /* =================================================================== */ +  + /* +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lundump.c lua-5.1.3-patched/src/lundump.c +--- ../lua-5.1.3/src/lundump.c	2008-01-18 18:39:11.000000000 +0200 ++++ lua-5.1.3-patched/src/lundump.c	2008-03-26 04:33:51.000000000 +0200 +@@ -74,6 +74,13 @@ +  return x; + } +  ++static lua_Integer LoadInteger(LoadState* S) ++{ ++ lua_Integer x; ++ LoadVar(S,x); ++ return x; ++} ++ + static TString* LoadString(LoadState* S) + { +  size_t size; +@@ -120,6 +127,9 @@ +    case LUA_TNUMBER: + 	setnvalue(o,LoadNumber(S)); + 	break; ++   case LUA_TINT:   /* Integer type saved in bytecode (see lcode.c) */ ++	setivalue(o,LoadInteger(S)); ++	break; +    case LUA_TSTRING: + 	setsvalue2n(S->L,o,LoadString(S)); + 	break; +@@ -221,5 +231,22 @@ +  *h++=(char)sizeof(size_t); +  *h++=(char)sizeof(Instruction); +  *h++=(char)sizeof(lua_Number); +- *h++=(char)(((lua_Number)0.5)==0);		/* is lua_Number integral? */ ++ ++ /*  ++  * Last byte of header (0/1 in unpatched Lua 5.1.3): ++  * ++  * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only) ++  * 1: lua_Number is integer (nonpatched only) ++  * ++  * +2: LNUM_INT16: sizeof(lua_Integer) ++  * +4: LNUM_INT32: sizeof(lua_Integer) ++  * +8: LNUM_INT64: sizeof(lua_Integer) ++  * ++  * +0x80: LNUM_COMPLEX ++  */ ++ *h++ = (char)(sizeof(lua_Integer) ++#ifdef LNUM_COMPLEX ++    | 0x80 ++#endif ++    ); + } +Binary files ../lua-5.1.3/src/lundump.o and lua-5.1.3-patched/src/lundump.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lvm.c lua-5.1.3-patched/src/lvm.c +--- ../lua-5.1.3/src/lvm.c	2007-12-28 17:32:23.000000000 +0200 ++++ lua-5.1.3-patched/src/lvm.c	2008-03-14 11:13:17.000000000 +0200 +@@ -25,22 +25,35 @@ + #include "ltable.h" + #include "ltm.h" + #include "lvm.h" +- +- ++#include "llex.h" ++#include "lnum.h" +  + /* limit for table tag-method chains (to avoid loops) */ + #define MAXTAGLOOP	100 +  +  +-const TValue *luaV_tonumber (const TValue *obj, TValue *n) { +-  lua_Number num; ++/* ++ * If 'obj' is a string, it is tried to be interpreted as a number. ++ */ ++const TValue *luaV_tonumber ( const TValue *obj, TValue *n) { ++  lua_Number d; ++  lua_Integer i; ++   +   if (ttisnumber(obj)) return obj; +-  if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { +-    setnvalue(n, num); +-    return n; +-  } +-  else +-    return NULL; ++ ++  if (ttisstring(obj)) { ++    switch( luaO_str2d( svalue(obj), &d, &i ) ) { ++        case TK_INT: ++            setivalue(n,i); return n; ++        case TK_NUMBER:  ++            setnvalue(n,d); return n; ++#ifdef LNUM_COMPLEX ++        case TK_NUMBER2:    /* "N.NNNi", != 0 */ ++            setnvalue_complex_fast(n, d*I); return n; ++#endif ++        } ++    } ++  return NULL; + } +  +  +@@ -49,8 +62,7 @@ +     return 0; +   else { +     char s[LUAI_MAXNUMBER2STR]; +-    lua_Number n = nvalue(obj); +-    lua_number2str(s, n); ++    luaO_num2buf(s,obj); +     setsvalue2s(L, obj, luaS_new(L, s)); +     return 1; +   } +@@ -218,59 +230,127 @@ + } +  +  ++#ifdef LNUM_COMPLEX ++void error_complex( lua_State *L, const TValue *l, const TValue *r ) ++{ ++  char buf1[ LUAI_MAXNUMBER2STR ]; ++  char buf2[ LUAI_MAXNUMBER2STR ]; ++  luaO_num2buf( buf1, l ); ++  luaO_num2buf( buf2, r ); ++  luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 ); ++  /* no return */ ++} ++#endif ++ ++ + int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { +   int res; +-  if (ttype(l) != ttype(r)) ++  int tl,tr; ++  lua_Integer tmp; ++ ++  if (!ttype_ext_same(l,r)) +     return luaG_ordererror(L, l, r); +-  else if (ttisnumber(l)) +-    return luai_numlt(nvalue(l), nvalue(r)); +-  else if (ttisstring(l)) +-    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; +-  else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) ++#ifdef LNUM_COMPLEX ++  if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) ++    error_complex( L, l, r ); ++#endif ++  tl= ttype(l); tr= ttype(r); ++  if (tl==tr) {  /* clear arithmetics */ ++    switch(tl) { ++      case LUA_TINT:      return ivalue(l) < ivalue(r); ++      case LUA_TNUMBER:   return luai_numlt(nvalue_fast(l), nvalue_fast(r)); ++      case LUA_TSTRING:   return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; ++    } ++  } else if (tl==LUA_TINT) {  /* l:int, r:num */ ++    /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons ++     * in integer realm. Only otherwise cast 'l' to FP (which might change its ++     * value). ++     */ ++    if (tt_integer_valued(r,&tmp))  ++        return ivalue(l) < tmp; ++    else  ++        return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) ); ++ ++  } else if (tl==LUA_TNUMBER) {  /* l:num, r:int */ ++    if (tt_integer_valued(l,&tmp))  ++        return tmp < ivalue(r); ++    else ++        return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) ); ++ ++  } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) +     return res; ++ +   return luaG_ordererror(L, l, r); + } +  +  + static int lessequal (lua_State *L, const TValue *l, const TValue *r) { +   int res; +-  if (ttype(l) != ttype(r)) ++  int tl, tr; ++  lua_Integer tmp; ++ ++  if (!ttype_ext_same(l,r)) +     return luaG_ordererror(L, l, r); +-  else if (ttisnumber(l)) +-    return luai_numle(nvalue(l), nvalue(r)); +-  else if (ttisstring(l)) +-    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; +-  else if ((res = call_orderTM(L, l, r, TM_LE)) != -1)  /* first try `le' */ ++#ifdef LNUM_COMPLEX ++  if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) ++    error_complex( L, l, r ); ++#endif ++  tl= ttype(l); tr= ttype(r); ++  if (tl==tr) {  /* clear arithmetics */ ++    switch(tl) { ++      case LUA_TINT:      return ivalue(l) <= ivalue(r); ++      case LUA_TNUMBER:   return luai_numle(nvalue_fast(l), nvalue_fast(r)); ++      case LUA_TSTRING:   return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; ++    } ++  } ++  if (tl==LUA_TINT) {  /* l:int, r:num */ ++    if (tt_integer_valued(r,&tmp))  ++        return ivalue(l) <= tmp; ++    else ++        return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) ); ++ ++  } else if (tl==LUA_TNUMBER) {  /* l:num, r:int */ ++    if (tt_integer_valued(l,&tmp))  ++        return tmp <= ivalue(r); ++    else ++        return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) ); ++ ++  } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1)  /* first try `le' */ +     return res; +   else if ((res = call_orderTM(L, r, l, TM_LT)) != -1)  /* else try `lt' */ +     return !res; ++ +   return luaG_ordererror(L, l, r); + } +  +  +-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { ++/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping ++ *       implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled ++ *       simply by the 'default' case here. ++ */ ++int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) { +   const TValue *tm; +-  lua_assert(ttype(t1) == ttype(t2)); +-  switch (ttype(t1)) { ++  lua_assert(ttype_ext_same(l,r)); ++  switch (ttype(l)) { +     case LUA_TNIL: return 1; +-    case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); +-    case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */ +-    case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); ++    case LUA_TINT: ++    case LUA_TNUMBER: return luaO_rawequalObj(l,r); ++    case LUA_TBOOLEAN: return bvalue(l) == bvalue(r);  /* true must be 1 !! */ ++    case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r); +     case LUA_TUSERDATA: { +-      if (uvalue(t1) == uvalue(t2)) return 1; +-      tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, +-                         TM_EQ); ++      if (uvalue(l) == uvalue(r)) return 1; ++      tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ); +       break;  /* will try TM */ +     } +     case LUA_TTABLE: { +-      if (hvalue(t1) == hvalue(t2)) return 1; +-      tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); ++      if (hvalue(l) == hvalue(r)) return 1; ++      tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ); +       break;  /* will try TM */ +     } +-    default: return gcvalue(t1) == gcvalue(t2); ++    default: return gcvalue(l) == gcvalue(r); +   } +   if (tm == NULL) return 0;  /* no TM? */ +-  callTMres(L, L->top, tm, t1, t2);  /* call TM */ ++  callTMres(L, L->top, tm, l, r);  /* call TM */ +   return !l_isfalse(L->top); + } +  +@@ -310,30 +390,6 @@ + } +  +  +-static void Arith (lua_State *L, StkId ra, const TValue *rb, +-                   const TValue *rc, TMS op) { +-  TValue tempb, tempc; +-  const TValue *b, *c; +-  if ((b = luaV_tonumber(rb, &tempb)) != NULL && +-      (c = luaV_tonumber(rc, &tempc)) != NULL) { +-    lua_Number nb = nvalue(b), nc = nvalue(c); +-    switch (op) { +-      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; +-      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; +-      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; +-      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; +-      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; +-      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; +-      case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; +-      default: lua_assert(0); break; +-    } +-  } +-  else if (!call_binTM(L, rb, rc, ra, op)) +-    luaG_aritherror(L, rb, rc); +-} +- +- +- + /* + ** some macros for common tasks in `luaV_execute' + */ +@@ -357,17 +413,154 @@ + #define Protect(x)	{ L->savedpc = pc; {x;}; base = L->base; } +  +  +-#define arith_op(op,tm) { \ +-        TValue *rb = RKB(i); \ +-        TValue *rc = RKC(i); \ +-        if (ttisnumber(rb) && ttisnumber(rc)) { \ +-          lua_Number nb = nvalue(rb), nc = nvalue(rc); \ +-          setnvalue(ra, op(nb, nc)); \ +-        } \ +-        else \ +-          Protect(Arith(L, ra, rb, rc, tm)); \ ++/* Note: if called for unary operations, 'rc'=='rb'. ++ */ ++static void Arith (lua_State *L, StkId ra, const TValue *rb, ++                   const TValue *rc, TMS op) { ++  TValue tempb, tempc; ++  const TValue *b, *c; ++  lua_Number nb,nc; ++ ++  if ((b = luaV_tonumber(rb, &tempb)) != NULL && ++      (c = luaV_tonumber(rc, &tempc)) != NULL) { ++ ++    /* Keep integer arithmetics in the integer realm, if possible. ++     */ ++    if (ttisint(b) && ttisint(c)) { ++      lua_Integer ib = ivalue(b), ic = ivalue(c); ++      lua_Integer *ri = &ra->value.i; ++      ra->tt= LUA_TINT;  /* part of 'setivalue(ra)' */ ++      switch (op) { ++        case TM_ADD: if (try_addint( ri, ib, ic)) return; break; ++        case TM_SUB: if (try_subint( ri, ib, ic)) return; break; ++        case TM_MUL: if (try_mulint( ri, ib, ic)) return; break; ++        case TM_DIV: if (try_divint( ri, ib, ic)) return; break; ++        case TM_MOD: if (try_modint( ri, ib, ic)) return; break; ++        case TM_POW: if (try_powint( ri, ib, ic)) return; break; ++        case TM_UNM: if (try_unmint( ri, ib)) return; break; ++        default: lua_assert(0); ++      } ++    } ++    /* Fallback to floating point, when leaving range. */ ++ ++#ifdef LNUM_COMPLEX ++    if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) { ++      lua_Complex r; ++      if (op==TM_UNM) { ++        r= -nvalue_complex_fast(b);     /* never an integer (or scalar) */ ++        setnvalue_complex_fast( ra, r ); ++      } else { ++        lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c); ++        switch (op) { ++          case TM_ADD: r= bb + cc; break; ++          case TM_SUB: r= bb - cc; break; ++          case TM_MUL: r= bb * cc; break; ++          case TM_DIV: r= bb / cc; break; ++          case TM_MOD:  ++            luaG_runerror(L, "attempt to use %% on complex numbers");  /* no return */ ++          case TM_POW: r= luai_vectpow( bb, cc ); break; ++          default: lua_assert(0); r=0; ++        } ++        setnvalue_complex( ra, r ); +       } ++      return; ++    } ++#endif ++    nb = nvalue(b); nc = nvalue(c); ++    switch (op) { ++      case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return; ++      case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return; ++      case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return; ++      case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return; ++      case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return; ++      case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return; ++      case TM_UNM: setnvalue(ra, luai_numunm(nb)); return; ++      default: lua_assert(0); ++    } ++  } ++   ++  /* Either operand not a number */ ++  if (!call_binTM(L, rb, rc, ra, op)) ++    luaG_aritherror(L, rb, rc); ++} +  ++/* Helper macro to sort arithmetic operations into four categories: ++ *  TK_INT: integer - integer operands ++ *  TK_NUMBER: number - number (non complex, either may be integer) ++ *  TK_NUMBER2: complex numbers (at least the other) ++ *  0: non-numeric (at least the other) ++*/ ++#ifdef LNUM_COMPLEX ++static inline int arith_mode( const TValue *rb, const TValue *rc ) { ++  if (ttisint(rb) && ttisint(rc)) return TK_INT; ++  if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2; ++  if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER; ++  return 0; ++} ++#else ++# define arith_mode(rb,rc) \ ++    ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \ ++      (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 ) ++#endif ++ ++/* arith_op macro for two operators: ++ * automatically chooses, which function (number, integer, complex) to use ++ */ ++#define ARITH_OP2_START( op_num, op_int ) \ ++  int failed= 0; \ ++  switch( arith_mode(rb,rc) ) { \ ++    case TK_INT: \ ++      if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \ ++        { ra->tt= LUA_TINT; break; } /* else flow through */ \ ++    case TK_NUMBER: \ ++      setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break; ++ ++#define ARITH_OP2_END \ ++    default: \ ++      failed= 1; break; \ ++  } if (!failed) continue; ++ ++#define arith_op_continue_scalar( op_num, op_int ) \ ++    ARITH_OP2_START( op_num, op_int ) \ ++    ARITH_OP2_END ++ ++#ifdef LNUM_COMPLEX ++# define arith_op_continue( op_num, op_int, op_complex ) \ ++    ARITH_OP2_START( op_num, op_int ) \ ++      case TK_NUMBER2: \ ++        setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \ ++    ARITH_OP2_END ++#else ++# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int) ++#endif ++ ++/* arith_op macro for one operator: ++ */ ++#define ARITH_OP1_START( op_num, op_int ) \ ++  int failed= 0; \ ++  switch( arith_mode(rb,rb) ) { \ ++    case TK_INT: \ ++      if (op_int ( &(ra)->value.i, ivalue(rb) )) \ ++        { ra->tt= LUA_TINT; break; } /* else flow through */ \ ++      case TK_NUMBER: \ ++        setnvalue(ra, op_num (nvalue(rb))); break; \ ++ ++#define ARITH_OP1_END \ ++      default: \ ++        failed= 1; break; \ ++  } if (!failed) continue; ++ ++#ifdef LNUM_COMPLEX ++# define arith_op1_continue( op_num, op_int, op_complex ) \ ++    ARITH_OP1_START( op_num, op_int ) \ ++      case TK_NUMBER2: \ ++        setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \ ++    ARITH_OP1_END ++#else ++# define arith_op1_continue( op_num, op_int, _ ) \ ++    ARITH_OP1_START( op_num, op_int ) \ ++    ARITH_OP1_END ++#endif +  +  + void luaV_execute (lua_State *L, int nexeccalls) { +@@ -468,38 +661,45 @@ +         continue; +       } +       case OP_ADD: { +-        arith_op(luai_numadd, TM_ADD); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue( luai_numadd, try_addint, luai_vectadd ); ++        Protect(Arith(L, ra, rb, rc, TM_ADD)); \ +         continue; +       } +       case OP_SUB: { +-        arith_op(luai_numsub, TM_SUB); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue( luai_numsub, try_subint, luai_vectsub ); ++        Protect(Arith(L, ra, rb, rc, TM_SUB)); +         continue; +       } +       case OP_MUL: { +-        arith_op(luai_nummul, TM_MUL); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue(luai_nummul, try_mulint, luai_vectmul); ++        Protect(Arith(L, ra, rb, rc, TM_MUL)); +         continue; +       } +       case OP_DIV: { +-        arith_op(luai_numdiv, TM_DIV); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue(luai_numdiv, try_divint, luai_vectdiv); ++        Protect(Arith(L, ra, rb, rc, TM_DIV)); +         continue; +       } +       case OP_MOD: { +-        arith_op(luai_nummod, TM_MOD); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue_scalar(luai_nummod, try_modint);  /* scalars only */ ++        Protect(Arith(L, ra, rb, rc, TM_MOD)); +         continue; +       } +       case OP_POW: { +-        arith_op(luai_numpow, TM_POW); ++        TValue *rb = RKB(i), *rc= RKC(i); ++        arith_op_continue(luai_numpow, try_powint, luai_vectpow); ++        Protect(Arith(L, ra, rb, rc, TM_POW)); +         continue; +       } +       case OP_UNM: { +         TValue *rb = RB(i); +-        if (ttisnumber(rb)) { +-          lua_Number nb = nvalue(rb); +-          setnvalue(ra, luai_numunm(nb)); +-        } +-        else { +-          Protect(Arith(L, ra, rb, rb, TM_UNM)); +-        } ++        arith_op1_continue(luai_numunm, try_unmint, luai_vectunm); ++        Protect(Arith(L, ra, rb, rb, TM_UNM)); +         continue; +       } +       case OP_NOT: { +@@ -511,11 +711,11 @@ +         const TValue *rb = RB(i); +         switch (ttype(rb)) { +           case LUA_TTABLE: { +-            setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); ++            setivalue(ra, luaH_getn(hvalue(rb))); +             break; +           } +           case LUA_TSTRING: { +-            setnvalue(ra, cast_num(tsvalue(rb)->len)); ++            setivalue(ra, tsvalue(rb)->len); +             break; +           } +           default: {  /* try metamethod */ +@@ -648,14 +848,30 @@ +         } +       } +       case OP_FORLOOP: { +-        lua_Number step = nvalue(ra+2); +-        lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ +-        lua_Number limit = nvalue(ra+1); +-        if (luai_numlt(0, step) ? luai_numle(idx, limit) +-                                : luai_numle(limit, idx)) { +-          dojump(L, pc, GETARG_sBx(i));  /* jump back */ +-          setnvalue(ra, idx);  /* update internal index... */ +-          setnvalue(ra+3, idx);  /* ...and external index */ ++        /* If start,step and limit are all integers, we don't need to check ++         * against overflow in the looping. ++         */ ++        if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) { ++          lua_Integer step = ivalue(ra+2); ++          lua_Integer idx = ivalue(ra) + step; /* increment index */ ++          lua_Integer limit = ivalue(ra+1); ++          if (step > 0 ? (idx <= limit) : (limit <= idx)) { ++            dojump(L, pc, GETARG_sBx(i));  /* jump back */ ++            setivalue(ra, idx);  /* update internal index... */ ++            setivalue(ra+3, idx);  /* ...and external index */ ++          } ++        } else { ++          /* non-integer looping (don't use 'nvalue_fast', some may be integer!)  ++          */ ++          lua_Number step = nvalue(ra+2); ++          lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ ++          lua_Number limit = nvalue(ra+1); ++          if (luai_numlt(0, step) ? luai_numle(idx, limit) ++                                  : luai_numle(limit, idx)) { ++            dojump(L, pc, GETARG_sBx(i));  /* jump back */ ++            setnvalue(ra, idx);  /* update internal index... */ ++            setnvalue(ra+3, idx);  /* ...and external index */ ++          } +         } +         continue; +       } +@@ -664,13 +880,21 @@ +         const TValue *plimit = ra+1; +         const TValue *pstep = ra+2; +         L->savedpc = pc;  /* next steps may throw errors */ ++        /* Using same location for tonumber's both arguments, effectively does ++         * in-place modification (string->number). */ +         if (!tonumber(init, ra)) +           luaG_runerror(L, LUA_QL("for") " initial value must be a number"); +         else if (!tonumber(plimit, ra+1)) +           luaG_runerror(L, LUA_QL("for") " limit must be a number"); +         else if (!tonumber(pstep, ra+2)) +           luaG_runerror(L, LUA_QL("for") " step must be a number"); +-        setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); ++        /* Step back one value (keep within integers if we can) ++         */ ++        if (!( ttisint(ra) && ttisint(pstep) && ++               try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) { ++            /* don't use 'nvalue_fast()', values may be integer */ ++            setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); ++        } +         dojump(L, pc, GETARG_sBx(i)); +         continue; +       } +@@ -707,7 +931,7 @@ +           luaH_resizearray(L, h, last);  /* pre-alloc it at once */ +         for (; n > 0; n--) { +           TValue *val = ra+n; +-          setobj2t(L, luaH_setnum(L, h, last--), val); ++          setobj2t(L, luaH_setint(L, h, last--), val); +           luaC_barriert(L, h, val); +         } +         continue; +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/lvm.h lua-5.1.3-patched/src/lvm.h +--- ../lua-5.1.3/src/lvm.h	2007-12-27 15:02:25.000000000 +0200 ++++ lua-5.1.3-patched/src/lvm.h	2008-03-19 10:49:34.000000000 +0200 +@@ -15,11 +15,9 @@ +  + #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) +  +-#define tonumber(o,n)	(ttype(o) == LUA_TNUMBER || \ +-                         (((o) = luaV_tonumber(o,n)) != NULL)) ++#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) +  +-#define equalobj(L,o1,o2) \ +-	(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) ++#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2)) +  +  + LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +Binary files ../lua-5.1.3/src/lvm.o and lua-5.1.3-patched/src/lvm.o differ +Binary files ../lua-5.1.3/src/lzio.o and lua-5.1.3-patched/src/lzio.o differ +diff -urN --exclude=.svn --exclude=.DS_Store ../lua-5.1.3/src/print.c lua-5.1.3-patched/src/print.c +--- ../lua-5.1.3/src/print.c	2007-03-26 03:17:38.000000000 +0300 ++++ lua-5.1.3-patched/src/print.c	2008-03-19 11:04:51.000000000 +0200 +@@ -14,6 +14,7 @@ + #include "lobject.h" + #include "lopcodes.h" + #include "lundump.h" ++#include "lnum.h" +  + #define PrintFunction	luaU_print +  +@@ -59,8 +60,16 @@ +   case LUA_TBOOLEAN: + 	printf(bvalue(o) ? "true" : "false"); + 	break; ++  case LUA_TINT: ++	printf(LUA_INTEGER_FMT,ivalue(o)); ++	break; +   case LUA_TNUMBER: +-	printf(LUA_NUMBER_FMT,nvalue(o)); ++#ifdef LNUM_COMPLEX ++    // TBD: Do we get complex values here? ++    { lua_Number b= nvalue_img_fast(o); ++	  printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); } ++#endif ++	printf(LUA_NUMBER_FMT,nvalue_fast(o)); + 	break; +   case LUA_TSTRING: + 	PrintString(rawtsvalue(o)); +Binary files ../lua-5.1.3/src/print.o and lua-5.1.3-patched/src/print.o differ diff --git a/tools/lua/patches/020-shared_liblua.patch b/tools/lua/patches/020-shared_liblua.patch new file mode 100644 index 000000000..402b8a5fc --- /dev/null +++ b/tools/lua/patches/020-shared_liblua.patch @@ -0,0 +1,154 @@ +Index: lua-5.1.3/Makefile +=================================================================== +--- lua-5.1.3.orig/Makefile	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/Makefile	2008-05-23 09:05:51.000000000 +0200 +@@ -37,8 +37,8 @@ +  + # What to install. + TO_BIN= lua luac +-TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp +-TO_LIB= liblua.a ++TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp lnum_config.h ++TO_LIB= liblua.a liblua.so.$R + TO_MAN= lua.1 luac.1 +  + # Lua version and release. +@@ -58,6 +58,7 @@ + 	cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) + 	cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) + 	cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) ++	ln -s liblua.so.$R $(INSTALL_LIB)/liblua.so + 	cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) +  + local: +Index: lua-5.1.3/src/ldo.h +=================================================================== +--- lua-5.1.3.orig/src/ldo.h	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/src/ldo.h	2008-05-23 09:03:32.000000000 +0200 +@@ -46,7 +46,7 @@ + LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); + LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); + LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +-LUAI_FUNC void luaD_growstack (lua_State *L, int n); ++LUA_API void luaD_growstack (lua_State *L, int n); +  + LUAI_FUNC void luaD_throw (lua_State *L, int errcode); + LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); +Index: lua-5.1.3/src/lfunc.h +=================================================================== +--- lua-5.1.3.orig/src/lfunc.h	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/src/lfunc.h	2008-05-23 09:03:32.000000000 +0200 +@@ -18,7 +18,7 @@ +                          cast(int, sizeof(TValue *)*((n)-1))) +  +  +-LUAI_FUNC Proto *luaF_newproto (lua_State *L); ++LUA_API Proto *luaF_newproto (lua_State *L); + LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); + LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); + LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +Index: lua-5.1.3/src/lmem.h +=================================================================== +--- lua-5.1.3.orig/src/lmem.h	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/src/lmem.h	2008-05-23 09:03:32.000000000 +0200 +@@ -38,9 +38,9 @@ +    ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) +  +  +-LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, ++LUA_API void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, +                                                           size_t size); +-LUAI_FUNC void *luaM_toobig (lua_State *L); ++LUA_API void *luaM_toobig (lua_State *L); + LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, +                                size_t size_elem, int limit, +                                const char *errormsg); +Index: lua-5.1.3/src/lstring.h +=================================================================== +--- lua-5.1.3.orig/src/lstring.h	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/src/lstring.h	2008-05-23 09:03:32.000000000 +0200 +@@ -25,7 +25,7 @@ +  + LUAI_FUNC void luaS_resize (lua_State *L, int newsize); + LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +-LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); ++LUA_API TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +  +  + #endif +Index: lua-5.1.3/src/lundump.h +=================================================================== +--- lua-5.1.3.orig/src/lundump.h	2008-05-23 09:03:23.000000000 +0200 ++++ lua-5.1.3/src/lundump.h	2008-05-23 09:03:32.000000000 +0200 +@@ -17,7 +17,7 @@ + LUAI_FUNC void luaU_header (char* h); +  + /* dump one chunk; from ldump.c */ +-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); ++LUA_API int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); +  + #ifdef luac_c + /* print one chunk; from print.c */ +Index: lua-5.1.3/src/Makefile +=================================================================== +--- lua-5.1.3.orig/src/Makefile	2008-05-23 09:03:32.000000000 +0200 ++++ lua-5.1.3/src/Makefile	2008-05-23 09:03:36.000000000 +0200 +@@ -23,6 +23,7 @@ + PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris +  + LUA_A=	liblua.a ++LUA_SO= liblua.so + CORE_O=	lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + 	lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o  \ + 	lundump.o lvm.o lzio.o lnum.o +@@ -33,11 +34,12 @@ + LUA_O=	lua.o +  + LUAC_T=	luac +-LUAC_O=	luac.o print.o ++LUAC_O=	luac.o print.o lopcodes.o +  + ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) ++ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T) + ALL_A= $(LUA_A) ++ALL_SO= $(LUA_SO) +  + default: $(PLAT) +  +@@ -47,14 +49,23 @@ +  + a:	$(ALL_A) +  ++so:	$(ALL_SO) ++ + $(LUA_A): $(CORE_O) $(LIB_O) + 	$(AR) $@ $? + 	$(RANLIB) $@ +  +-$(LUA_T): $(LUA_O) $(LUA_A) +-	$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) ++$(LUA_SO): $(CORE_O) $(LIB_O) ++	$(CC) -o $@.$(PKG_VERSION) -shared -soname="$@.$(PKG_VERSION)" $? -nostdlib -lgcc ++	ln -fs $@.$(PKG_VERSION) $@ ++ ++$(LUA_T): $(LUA_O) $(LUA_SO) ++	$(CC) -o $@ -L. -llua $(MYLDFLAGS) $(LUA_O) $(LIBS) ++ ++$(LUAC_T): $(LUAC_O) $(LUA_SO) ++	$(CC) -o $@ -L. -llua $(MYLDFLAGS) $(LUAC_O) $(LIBS) +  +-$(LUAC_T): $(LUAC_O) $(LUA_A) ++$(LUAC_T)-host: $(LUAC_O) $(LUA_A) + 	$(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) +  + clean: +@@ -96,7 +107,7 @@ + 	$(MAKE) all MYCFLAGS= +  + linux: +-	$(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" ++	$(MAKE) all MYCFLAGS+=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" +  + macosx: + 	$(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" diff --git a/tools/lua/patches/030-archindependent-bytecode.patch b/tools/lua/patches/030-archindependent-bytecode.patch new file mode 100644 index 000000000..4ba58ebfb --- /dev/null +++ b/tools/lua/patches/030-archindependent-bytecode.patch @@ -0,0 +1,113 @@ +diff -ur lua-5.1.3-pt2/src/ldump.c lua-5.1.3-pt3/src/ldump.c +--- lua-5.1.3-pt2/src/ldump.c	2008-04-05 14:25:13.000000000 +0200 ++++ lua-5.1.3-pt3/src/ldump.c	2008-04-05 14:28:27.000000000 +0200 +@@ -67,12 +67,12 @@ + { +  if (s==NULL || getstr(s)==NULL) +  { +-  size_t size=0; ++  unsigned int size=0; +   DumpVar(size,D); +  } +  else +  { +-  size_t size=s->tsv.len+1;		/* include trailing '\0' */ ++  unsigned int size=s->tsv.len+1;		/* include trailing '\0' */ +   DumpVar(size,D); +   DumpBlock(getstr(s),size,D); +  } +diff -ur lua-5.1.3-pt2/src/lundump.c lua-5.1.3-pt3/src/lundump.c +--- lua-5.1.3-pt2/src/lundump.c	2008-04-05 14:25:13.000000000 +0200 ++++ lua-5.1.3-pt3/src/lundump.c	2008-04-05 14:28:27.000000000 +0200 +@@ -25,6 +25,7 @@ +  ZIO* Z; +  Mbuffer* b; +  const char* name; ++ int swap; + } LoadState; +  + #ifdef LUAC_TRUST_BINARIES +@@ -40,7 +41,6 @@ + } + #endif +  +-#define LoadMem(S,b,n,size)	LoadBlock(S,b,(n)*(size)) + #define	LoadByte(S)		(lu_byte)LoadChar(S) + #define LoadVar(S,x)		LoadMem(S,&x,1,sizeof(x)) + #define LoadVector(S,b,n,size)	LoadMem(S,b,n,size) +@@ -52,6 +52,49 @@ +  IF (r!=0, "unexpected end"); + } +  ++static void LoadMem (LoadState* S, void* b, int n, size_t size) ++{ ++ LoadBlock(S,b,n*size); ++ if (S->swap) ++ { ++  char* p=(char*) b; ++  char c; ++  switch (size) ++  { ++   case 1: ++  	break; ++   case 2: ++	while (n--) ++	{ ++	 c=p[0]; p[0]=p[1]; p[1]=c; ++	 p+=2; ++	} ++  	break; ++   case 4: ++	while (n--) ++	{ ++	 c=p[0]; p[0]=p[3]; p[3]=c; ++	 c=p[1]; p[1]=p[2]; p[2]=c; ++	 p+=4; ++	} ++  	break; ++   case 8: ++	while (n--) ++	{ ++	 c=p[0]; p[0]=p[7]; p[7]=c; ++	 c=p[1]; p[1]=p[6]; p[6]=c; ++	 c=p[2]; p[2]=p[5]; p[5]=c; ++	 c=p[3]; p[3]=p[4]; p[4]=c; ++	 p+=8; ++	} ++  	break; ++   default: ++   	IF(1, "bad size"); ++  	break; ++  } ++ } ++} ++ + static int LoadChar(LoadState* S) + { +  char x; +@@ -83,7 +126,7 @@ +  + static TString* LoadString(LoadState* S) + { +- size_t size; ++ unsigned int size; +  LoadVar(S,size); +  if (size==0) +   return NULL; +@@ -194,6 +237,7 @@ +  char s[LUAC_HEADERSIZE]; +  luaU_header(h); +  LoadBlock(S,s,LUAC_HEADERSIZE); ++ S->swap=(s[6]!=h[6]); s[6]=h[6]; +  IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); + } +  +@@ -228,7 +272,7 @@ +  *h++=(char)LUAC_FORMAT; +  *h++=(char)*(char*)&x;				/* endianness */ +  *h++=(char)sizeof(int); +- *h++=(char)sizeof(size_t); ++ *h++=(char)sizeof(unsigned int); +  *h++=(char)sizeof(Instruction); +  *h++=(char)sizeof(lua_Number); +  diff --git a/tools/lua/patches/100-no_readline.patch b/tools/lua/patches/100-no_readline.patch new file mode 100644 index 000000000..7368187d8 --- /dev/null +++ b/tools/lua/patches/100-no_readline.patch @@ -0,0 +1,53 @@ +diff -ur lua-luci-5.1.3/src/luaconf.h lua-luci-5.1.3-new/src/luaconf.h +--- lua-luci-5.1.3/src/luaconf.h	2008-04-14 13:19:54.000000000 +0200 ++++ lua-luci-5.1.3-new/src/luaconf.h	2008-04-14 13:19:17.000000000 +0200 +@@ -38,7 +38,6 @@ + #if defined(LUA_USE_LINUX) + #define LUA_USE_POSIX + #define LUA_USE_DLOPEN		/* needs an extra library: -ldl */ +-#define LUA_USE_READLINE	/* needs some extra libraries */ + #endif +  + #if defined(LUA_USE_MACOSX) +Nur in lua-luci-5.1.3-new/src: luaconf.h.orig. +diff -ur lua-luci-5.1.3/src/Makefile lua-luci-5.1.3-new/src/Makefile +--- lua-luci-5.1.3/src/Makefile	2008-04-14 13:19:57.000000000 +0200 ++++ lua-luci-5.1.3-new/src/Makefile	2008-04-14 13:19:17.000000000 +0200 +@@ -17,6 +17,7 @@ + MYCFLAGS= + MYLDFLAGS= + MYLIBS= ++# USE_READLINE=1 +  + # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= +  +@@ -86,7 +87,7 @@ + 	@echo "MYLIBS = $(MYLIBS)" +  + # convenience targets for popular platforms +- ++RFLAG=$(if $(USE_READLINE),-DLUA_USE_READLINE) + none: + 	@echo "Please choose a platform:" + 	@echo "   $(PLATS)" +@@ -101,16 +102,16 @@ + 	$(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" +  + freebsd: +-	$(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" ++	$(MAKE) all MYCFLAGS="-DLUA_USE_LINUX $(RFLAG)" MYLIBS="-Wl,-E$(if $(USE_READLINE), -lreadline)" +  + generic: + 	$(MAKE) all MYCFLAGS= +  + linux: +-	$(MAKE) all MYCFLAGS+=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" ++	$(MAKE) all MYCFLAGS+="-DLUA_USE_LINUX $(RFLAG)" MYLIBS="-Wl,-E -ldl $(if $(USE_READLINE), -lreadline -lhistory -lncurses)" +  + macosx: +-	$(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" ++	$(MAKE) all MYCFLAGS=-DLUA_USE_LINUX $(if $(USE_READLINE), MYLIBS="-lreadline") + # use this on Mac OS X 10.3- + #	$(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX +  +Nur in lua-luci-5.1.3-new/src: Makefile.orig. diff --git a/tools/lua/patches/200-lua-path.patch b/tools/lua/patches/200-lua-path.patch new file mode 100644 index 000000000..62dd00e39 --- /dev/null +++ b/tools/lua/patches/200-lua-path.patch @@ -0,0 +1,15 @@ +--- b/src/luaconf.h	2008-05-06 20:10:46.000000000 +0200 ++++ a/src/luaconf.h	2008-05-06 20:10:27.000000000 +0200 +@@ -95,9 +95,9 @@ + 	".\\?.dll;"  LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" +  + #else +-#define LUA_ROOT	"/usr/local/" +-#define LUA_LDIR	LUA_ROOT "share/lua/5.1/" +-#define LUA_CDIR	LUA_ROOT "lib/lua/5.1/" ++#define LUA_ROOT	"/usr/" ++#define LUA_LDIR	LUA_ROOT "share/lua/" ++#define LUA_CDIR	LUA_ROOT "lib/lua/" + #define LUA_PATH_DEFAULT  \ + 		"./?.lua;"  LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \ + 		            LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua"  | 
