Index: lua-5.1.4/src/Makefile =================================================================== --- lua-5.1.4.orig/src/Makefile 2008-09-25 13:08:31.000000000 +0200 +++ lua-5.1.4/src/Makefile 2008-09-25 13:08:43.000000000 +0200 @@ -29,7 +29,7 @@ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.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 lposix.o + lstrlib.o loadlib.o linit.o lposix.o lbitlib.o LUA_T= lua LUA_O= lua.o Index: lua-5.1.4/src/bit_limits.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ lua-5.1.4/src/bit_limits.h 2008-09-25 13:09:16.000000000 +0200 @@ -0,0 +1,4 @@ +#define BITLIB_FLOAT_BITS 53 +#define BITLIB_FLOAT_MAX 0xfffffffffffffL +#define BITLIB_FLOAT_MIN (-0x10000000000000L) +#define BITLIB_FLOAT_UMAX 0x1fffffffffffffUL Index: lua-5.1.4/src/lbitlib.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ lua-5.1.4/src/lbitlib.c 2008-09-25 13:05:15.000000000 +0200 @@ -0,0 +1,133 @@ +/* Bitwise operations library */ +/* (c) Reuben Thomas 2000-2008 */ +/* See README for license */ + +#include "lua.h" +#include "lauxlib.h" +#include "limits.h" + +#include "bit_limits.h" + + +/* FIXME: Assume lua_Integer is int */ +#define LUA_INTEGER_MAX INT_MAX +#define LUA_INTEGER_MIN INT_MIN + +/* FIXME: Assume uint is an unsigned lua_Integer */ +typedef unsigned int lua_UInteger; +#define LUA_UINTEGER_MAX UINT_MAX + + +/* Bit type size and limits */ + +#define BIT_BITS \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? \ + BITLIB_FLOAT_BITS : (CHAR_BIT * sizeof(lua_Integer))) + +/* This code may give warnings if BITLIB_FLOAT_* are too big to fit in + long, but that doesn't matter since in that case they won't be + used. */ +#define BIT_MAX \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_MAX : LUA_INTEGER_MAX) + +#define BIT_MIN \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_MIN : LUA_INTEGER_MIN) + +#define BIT_UMAX \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_UMAX : LUA_UINTEGER_MAX) + + +/* Define TOBIT to get a bit value */ +#ifdef BUILTIN_CAST +#define +#define TOBIT(L, n, res) \ + ((void)(res), luaL_checkinteger((L), (n))) +#else +#include +#include + +/* FIXME: Assume lua_Number fits in a double (use of fmod). */ +#define TOBIT(L, n, res) \ + ((lua_Integer)(((res) = fmod(luaL_checknumber(L, (n)), (double)BIT_UMAX + 1.0)), \ + (res) > BIT_MAX ? ((res) -= (double)BIT_UMAX, (res) -= 1) : \ + ((res) < BIT_MIN ? ((res) += (double)BIT_UMAX, (res) += 1) : (res)))) +#endif + + +#define BIT_TRUNCATE(i) \ + ((i) & BIT_UMAX) + + +/* Operations + + The macros MONADIC and VARIADIC only deal with bitwise operations. + + LOGICAL_SHIFT truncates its left-hand operand before shifting so + that any extra bits at the most-significant end are not shifted + into the result. + + ARITHMETIC_SHIFT does not truncate its left-hand operand, so that + the sign bits are not removed and right shift work properly. + */ + +#define MONADIC(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE(op TOBIT(L, 1, f))); \ + return 1; \ + } + +#define VARIADIC(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + int n = lua_gettop(L), i; \ + lua_Integer w = TOBIT(L, 1, f); \ + for (i = 2; i <= n; i++) \ + w op TOBIT(L, i, f); \ + lua_pushinteger(L, BIT_TRUNCATE(w)); \ + return 1; \ + } + +#define LOGICAL_SHIFT(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE(BIT_TRUNCATE((lua_UInteger)TOBIT(L, 1, f)) op \ + (unsigned)luaL_checknumber(L, 2))); \ + return 1; \ + } + +#define ARITHMETIC_SHIFT(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE((lua_Integer)TOBIT(L, 1, f) op \ + (unsigned)luaL_checknumber(L, 2))); \ + return 1; \ + } + +MONADIC(cast, +) +MONADIC(bnot, ~) +VARIADIC(band, &=) +VARIADIC(bor, |=) +VARIADIC(bxor, ^=) +ARITHMETIC_SHIFT(lshift, <<) +LOGICAL_SHIFT(rshift, >>) +ARITHMETIC_SHIFT(arshift, >>) + +static const struct luaL_reg bitlib[] = { + {"cast", bit_cast}, + {"bnot", bit_bnot}, + {"band", bit_band}, + {"bor", bit_bor}, + {"bxor", bit_bxor}, + {"lshift", bit_lshift}, + {"rshift", bit_rshift}, + {"arshift", bit_arshift}, + {NULL, NULL} +}; + +LUALIB_API int luaopen_bit (lua_State *L) { + luaL_register(L, "bit", bitlib); + lua_pushnumber(L, BIT_BITS); + lua_setfield(L, -2, "bits"); + return 1; +} Index: lua-5.1.4/src/linit.c =================================================================== --- lua-5.1.4.orig/src/linit.c 2008-09-25 13:08:11.000000000 +0200 +++ lua-5.1.4/src/linit.c 2008-09-25 13:08:27.000000000 +0200 @@ -24,6 +24,7 @@ {LUA_MATHLIBNAME, luaopen_math}, {LUA_DBLIBNAME, luaopen_debug}, {LUA_POSIXLIBNAME, luaopen_posix}, + {LUA_BITLIBNAME, luaopen_bit}, {NULL, NULL} }; Index: lua-5.1.4/src/lualib.h =================================================================== --- lua-5.1.4.orig/src/lualib.h 2008-09-25 13:07:29.000000000 +0200 +++ lua-5.1.4/src/lualib.h 2008-09-25 13:08:06.000000000 +0200 @@ -42,6 +42,9 @@ #define LUA_POSIXLIBNAME "posix" LUALIB_API int (luaopen_posix) (lua_State *L); +#define LUA_BITLIBNAME "bit" +LUALIB_API int (luaopen_bit) (lua_State *L); + /* open all previous libraries */ LUALIB_API void (luaL_openlibs) (lua_State *L);