diff -urN lua-5.1.1/Makefile lua-5.1.1.patched/Makefile
--- lua-5.1.1/Makefile 2006-06-02 12:53:38.000000000 +0200
+++ lua-5.1.1.patched/Makefile 2006-08-22 14:54:24.000000000 +0200
@@ -11,7 +11,7 @@
# if INSTALL_TOP is not an absolute path. (Man pages are installed from the
# doc directory.)
#
-INSTALL_TOP= /usr/local
+INSTALL_TOP= /home/tgrellie
INSTALL_BIN= $(INSTALL_TOP)/bin
INSTALL_INC= $(INSTALL_TOP)/include
INSTALL_LIB= $(INSTALL_TOP)/lib
diff -urN lua-5.1.1/src/lcode.c lua-5.1.1.patched/src/lcode.c
--- lua-5.1.1/src/lcode.c 2006-03-21 20:28:49.000000000 +0100
+++ lua-5.1.1.patched/src/lcode.c 2006-10-10 14:16:06.000000000 +0200
@@ -645,6 +645,17 @@
case OP_POW: r = luai_numpow(v1, v2); break;
case OP_UNM: r = luai_numunm(v1); break;
case OP_LEN: return 0; /* no constant folding for 'len' */
+#if defined(LUA_BITWISE_OPERATORS)
+ case OP_BOR: luai_logor(r, v1, v2); break;
+ case OP_BAND: luai_logand(r, v1, v2); break;
+ case OP_BXOR: luai_logxor(r, v1, v2); break;
+ case OP_BRSHFT: luai_logrshft(r, v1, v2); break;
+ case OP_BLSHFT: luai_loglshft(r, v1, v2); break;
+ case OP_BNOT: luai_lognot(r, v1); break;
+ case OP_INTDIV:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
+ r = luai_numintdiv(v1, v2); break;
+#endif
default: lua_assert(0); r = 0; break;
}
if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
@@ -658,7 +669,11 @@
return;
else {
int o1 = luaK_exp2RK(fs, e1);
+#if defined(LUA_BITWISE_OPERATORS)
+ int o2 = (op != OP_UNM && op != OP_LEN && op != OP_BNOT) ? luaK_exp2RK(fs, e2) : 0;
+#else
int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
+#endif
freeexp(fs, e2);
freeexp(fs, e1);
e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
@@ -687,6 +702,14 @@
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
switch (op) {
+#if defined(LUA_BITWISE_OPERATORS)
+ case OPR_BNOT: {
+ if (e->k == VK)
+ luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
+ codearith(fs, OP_BNOT, e, &e2);
+ break;
+ }
+#endif
case OPR_MINUS: {
if (e->k == VK)
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
@@ -762,6 +785,14 @@
case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
+#if defined(LUA_BITWISE_OPERATORS)
+ case OPR_BOR: codearith(fs, OP_BOR, e1, e2); break;
+ case OPR_BAND: codearith(fs, OP_BAND, e1, e2); break;
+ case OPR_BXOR: codearith(fs, OP_BXOR, e1, e2); break;
+ case OPR_BLSHFT: codearith(fs, OP_BLSHFT, e1, e2); break;
+ case OPR_BRSHFT: codearith(fs, OP_BRSHFT, e1, e2); break;
+ case OPR_INTDIV: codearith(fs, OP_INTDIV, e1, e2); break;
+#endif
case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
diff -urN lua-5.1.1/src/lcode.h lua-5.1.1.patched/src/lcode.h
--- lua-5.1.1/src/lcode.h 2006-03-21 20:28:03.000000000 +0100
+++ lua-5.1.1.patched/src/lcode.h 2006-10-10 14:16:32.000000000 +0200
@@ -25,6 +25,9 @@
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
+#if defined(LUA_BITWISE_OPERATORS)
+ OPR_BOR, OPR_BAND, OPR_BXOR, OPR_BLSHFT, OPR_BRSHFT, OPR_INTDIV,
+#endif
OPR_CONCAT,
OPR_NE, OPR_EQ,
OPR_LT, OPR_LE, OPR_GT, OPR_GE,
@@ -33,8 +36,11 @@
} BinOpr;
+#if defined(LUA_BITWISE_OPERATORS)
+typedef enum UnOpr { OPR_BNOT, OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
+#else
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
-
+#endif
#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
diff -urN lua-5.1.1/src/ldebug.c lua-5.1.1.patched/src/ldebug.c
--- lua-5.1.1/src/ldebug.c 2005-12-22 17:19:56.000000000 +0100
+++ lua-5.1.1.patched/src/ldebug.c 2006-06-20 17:47:52.000000000 +0200
@@ -574,6 +574,16 @@
luaG_typeerror(L, p2, "perform arithmetic on");
}
+#if defined (LUA_BITWISE_OPERATORS)
+void luaG_logicerror (lua_State *L, const TValue *p1, const TValue *p2) {
+ TValue temp;
+ if (luaV_tonumber(p1, &temp) == NULL)
+ p2 = p1; /* first operand is wrong */
+ luaG_typeerror(L, p2, "perform bitwise operation on");
+}
+#endif
+
+
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
diff -urN lua-5.1.1/src/ldebug.h lua-5.1.1.patched/src/ldebug.h
--- lua-5.1.1/src/ldebug.h 2005-04-25 21:24:10.000000000 +0200
+++ lua-5.1.1.patched/src/ldebug.h 2006-06-20 17:48:29.000000000 +0200
@@ -30,4 +30,9 @@
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);
+#if defined (LUA_BITWISE_OPERATORS)
+LUAI_FUNC void luaG_logicerror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+#endif
+
#endif
diff -urN lua-5.1.1/src/llex.c lua-5.1.1.patched/src/llex.c
--- lua-5.1.1/src/llex.c 2006-03-09 19:14:31.000000000 +0100
+++ lua-5.1.1.patched/src/llex.c 2006-10-10 14:07:52.000000000 +0200
@@ -39,7 +39,11 @@
"end", "false", "for", "function", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
+#if defined(LUA_BITWISE_OPERATORS)
+ "..", "...", "==", ">=", ">>", "<=", "<<", "^^", "~=", "!="
+#else
"..", "...", "==", ">=", "<=", "~=",
+#endif
"<number>", "<name>", "<string>", "<eof>",
NULL
};
@@ -371,6 +375,30 @@
if (ls->current != '=') return '=';
else { next(ls); return TK_EQ; }
}
+#if defined(LUA_BITWISE_OPERATORS)
+ case '<': {
+ next(ls);
+ if (ls->current == '=') { next(ls); return TK_LE; }
+ else if (ls->current == '<') { next(ls); return TK_LSHFT; }
+ else return '<';
+ }
+ case '>': {
+ next(ls);
+ if (ls->current == '=') { next(ls); return TK_GE; }
+ else if (ls->current == '>') { next(ls); return TK_RSHFT; }
+ else return '>';
+ }
+ case '^': {
+ next(ls);
+ if (ls->current != '^') return '^';
+ else { next(ls); return TK_XOR; }
+ }
+ case '!': {
+ next(ls);
+ if (ls->current != '=') return '!';
+ else { next(ls); return TK_NE; }
+ }
+#else
case '<': {
next(ls);
if (ls->current != '=') return '<';
@@ -379,8 +407,9 @@
case '>': {
next(ls);
if (ls->current != '=') return '>';
- else { next(ls); return TK_GE; }
+ else { next(ls); return TK_GE; }
}
+#endif
case '~': {
next(ls);
if (ls->current != '=') return '~';
diff -urN lua-5.1.1/src/llex.h lua-5.1.1.patched/src/llex.h
--- lua-5.1.1/src/llex.h 2006-03-23 19:23:32.000000000 +0100
+++ lua-5.1.1.patched/src/llex.h 2006-10-10 14:06:40.000000000 +0200
@@ -28,7 +28,11 @@
TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
+#if defined(LUA_BITWISE_OPERATORS)
+ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LSHFT, TK_LE, TK_RSHFT, TK_XOR, TK_NE, TK_CNE, TK_NUMBER,
+#else
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
+#endif
TK_NAME, TK_STRING, TK_EOS
};
diff -urN lua-5.1.1/src/lopcodes.c lua-5.1.1.patched/src/lopcodes.c
--- lua-5.1.1/src/lopcodes.c 2005-11-08 20:45:36.000000000 +0100
+++ lua-5.1.1.patched/src/lopcodes.c 2006-10-10 14:11:28.000000000 +0200
@@ -32,6 +32,15 @@
"DIV",
"MOD",
"POW",
+#if defined(LUA_BITWISE_OPERATORS)
+ "BOR",
+ "BAND",
+ "OP_BXOR"
+ "BLSHFT",
+ "BRSHFT",
+ "BNOT",
+ "INTDIV",
+#endif
"UNM",
"NOT",
"LEN",
@@ -78,6 +87,15 @@
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
+#if defined(LUA_BITWISE_OPERATORS)
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BLSHFT */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_RLSHFT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_INTDIV */
+#endif
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
diff -urN lua-5.1.1/src/lopcodes.h lua-5.1.1.patched/src/lopcodes.h
--- lua-5.1.1/src/lopcodes.h 2006-03-14 20:04:44.000000000 +0100
+++ lua-5.1.1.patched/src/lopcodes.h 2006-10-10 14:09:47.000000000 +0200
@@ -174,10 +174,20 @@
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
+#if defined(LUA_BITWISE_OPERATORS)
+OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
+OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
+OP_BXOR,/* A B C R(A) := RK(B) ^| RK(C) */
+OP_BLSHFT,/* A B C R(A) := RK(B) << RK(C) */
+OP_BRSHFT,/* A B C R(A) := RK(B) >> RK(C) */
+OP_BNOT,/* A B R(A) := ~ R(B) */
+OP_INTDIV,/* A B C R(A) := RK(B) \ RK(C) */
+#endif
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
+
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP,/* sBx pc+=sBx */
@@ -186,8 +196,8 @@
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
-OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
-OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@@ -197,8 +207,8 @@
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
-OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
+OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
+ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
diff -urN lua-5.1.1/src/lparser.c lua-5.1.1.patched/src/lparser.c
--- lua-5.1.1/src/lparser.c 2006-06-05 17:57:59.000000000 +0200
+++ lua-5.1.1.patched/src/lparser.c 2006-10-10 14:29:03.000000000 +0200
@@ -780,6 +780,9 @@
case TK_NOT: return OPR_NOT;
case '-': return OPR_MINUS;
case '#': return OPR_LEN;
+#if defined(LUA_BITWISE_OPERATORS)
+ case '~': return OPR_BNOT;
+#endif
default: return OPR_NOUNOPR;
}
}
@@ -793,6 +796,14 @@
case '/': return OPR_DIV;
case '%': return OPR_MOD;
case '^': return OPR_POW;
+#if defined(LUA_BITWISE_OPERATORS)
+ case '|': return OPR_BOR;
+ case '&': return OPR_BAND;
+ case TK_XOR: return OPR_BXOR;
+ case TK_LSHFT: return OPR_BLSHFT;
+ case TK_RSHFT: return OPR_BRSHFT;
+ case '\\': return OPR_INTDIV;
+#endif
case TK_CONCAT: return OPR_CONCAT;
case TK_NE: return OPR_NE;
case TK_EQ: return OPR_EQ;
@@ -812,6 +823,9 @@
lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
+#if defined(LUA_BITWISE_OPERATORS)
+ {6, 6}, {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `|' `&' `!' `<<' `>>' `\' */
+#endif
{10, 9}, {5, 4}, /* power and concat (right associative) */
{3, 3}, {3, 3}, /* equality and inequality */
{3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
diff -urN lua-5.1.1/src/ltm.c lua-5.1.1.patched/src/ltm.c
--- lua-5.1.1/src/ltm.c 2006-01-10 13:50:00.000000000 +0100
+++ lua-5.1.1.patched/src/ltm.c 2006-10-10 14:42:15.000000000 +0200
@@ -34,6 +34,9 @@
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call"
+#if defined(LUA_BITWISE_OPERATORS)
+ ,"__or", "__and", "__xor", "__shl", "__shr", "__not", "__intdiv"
+#endif
};
int i;
for (i=0; i<TM_N; i++) {
diff -urN lua-5.1.1/src/ltm.h lua-5.1.1.patched/src/ltm.h
--- lua-5.1.1/src/ltm.h 2005-06-06 15:30:25.000000000 +0200
+++ lua-5.1.1.patched/src/ltm.h 2006-10-10 14:19:51.000000000 +0200
@@ -33,6 +33,15 @@
TM_LE,
TM_CONCAT,
TM_CALL,
+#if defined(LUA_BITWISE_OPERATORS)
+ TM_BOR,
+ TM_BAND,
+ TM_BXOR,
+ TM_BRSHFT,
+ TM_BLSHFT,
+ TM_BNOT,
+ TM_INTDIV,
+#endif
TM_N /* number of elements in the enum */
} TMS;
diff -urN lua-5.1.1/src/lua.h lua-5.1.1.patched/src/lua.h
--- lua-5.1.1/src/lua.h 2006-06-02 17:34:00.000000000 +0200
+++ lua-5.1.1.patched/src/lua.h 2006-10-10 14:52:14.000000000 +0200
@@ -17,7 +17,7 @@
#define LUA_VERSION "Lua 5.1"
-#define LUA_RELEASE "Lua 5.1.1"
+#define LUA_RELEASE "Lua 5.1.1 patched (added | & ^^ << >> ~ \\ !=)"
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT "Copyright (C) 1994-2006 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
diff -urN lua-5.1.1/src/luaconf.h lua-5.1.1.patched/src/luaconf.h
--- lua-5.1.1/src/luaconf.h 2006-04-10 20:27:23.000000000 +0200
+++ lua-5.1.1.patched/src/luaconf.h 2006-10-10 16:17:35.000000000 +0200
@@ -2,6 +2,7 @@
** $Id: luaconf.h,v 1.82 2006/04/10 18:27:23 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
+** Added logic operators : & | ^^ (xor) << >> ~, arithmetic operator \ (integer division) and != as an alternative to ~=
*/
@@ -209,6 +210,12 @@
*/
#define LUA_IDSIZE 60
+/*
+@@ LUA_BITWISE_OPERATORS enable logical operators | & ^| >> << ~ on lua_Number
+@* but also arithmetic operator \ (integer division) and != as an alernative to ~=
+*/
+#define LUA_BITWISE_OPERATORS
+
/*
** {==================================================================
@@ -216,6 +223,7 @@
** ===================================================================
*/
+
#if defined(lua_c) || defined(luaall_c)
/*
@@ -525,25 +533,6 @@
/*
-@@ 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
@@ -581,6 +570,38 @@
#endif
+
+/*
+@@ 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))
+#ifdef LUA_BITWISE_OPERATORS
+#define luai_numintdiv(a,b) (floor((a)/(b)))
+#endif
+#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)))
+
+#if defined(LUA_BITWISE_OPERATORS)
+#define luai_logor(r, a, b) { lua_Integer ai,bi; lua_number2int(ai,a); lua_number2int(bi,b); r = ai|bi; }
+#define luai_logand(r, a,b) { lua_Integer ai,bi; lua_number2int(ai,a); lua_number2int(bi,b); r = ai&bi; }
+#define luai_logxor(r, a,b) { lua_Integer ai,bi; lua_number2int(ai,a); lua_number2int(bi,b); r = ai^bi; }
+#define luai_lognot(r,a) { lua_Integer ai; lua_number2int(ai,a); r = ~ai; }
+#define luai_logrshft(r, a,b) { lua_Integer ai,bi; lua_number2int(ai,a); lua_number2int(bi,b); r = ai>>bi; }
+#define luai_loglshft(r, a,b) { lua_Integer ai,bi; lua_number2int(ai,a); lua_number2int(bi,b); r = ai<<bi; }
+#endif
+
+#endif
+
/* }================================================================== */
diff -urN lua-5.1.1/src/lvm.c lua-5.1.1.patched/src/lvm.c
--- lua-5.1.1/src/lvm.c 2006-10-10 16:33:05.000000000 +0200
+++ lua-5.1.1.patched/src/lvm.c 2006-10-10 16:35:41.000000000 +0200
@@ -325,6 +325,9 @@
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;
+#if defined(LUA_BITWISE_OPERATORS)
+ case TM_INTDIV: setnvalue(ra, luai_numintdiv(nb, nc)); break;
+#endif
default: lua_assert(0); break;
}
}
@@ -332,7 +335,30 @@
luaG_aritherror(L, rb, rc);
}
-
+#if defined(LUA_BITWISE_OPERATORS)
+static void Logic (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);
+ lua_Integer r;
+ switch (op) {
+ case TM_BLSHFT: luai_loglshft(r, nb, nc); break;
+ case TM_BRSHFT: luai_logrshft(r, nb, nc); break;
+ case TM_BOR: luai_logor(r, nb, nc); break;
+ case TM_BAND: luai_logand(r, nb, nc); break;
+ case TM_BXOR: luai_logxor(r, nb, nc); break;
+ case TM_BNOT: luai_lognot(r, nb); break;
+ default: lua_assert(0); r = 0; break;
+ }
+ setnvalue(ra, r);
+ }
+ else if (!call_binTM(L, rb, rc, ra, op))
+ luaG_logicerror(L, rb, rc);
+}
+#endif
/*
** some macros for common tasks in `luaV_execute'
@@ -369,6 +395,21 @@
}
+#if defined(LUA_BITWISE_OPERATORS)
+#define logic_op(op,tm) { \
+ TValue *rb = RKB(i); \
+ TValue *rc = RKC(i); \
+ if (ttisnumber(rb) && ttisnumber(rc)) { \
+ lua_Integer r; \
+ op(r, nvalue(rb), nvalue(rc)); \
+ setnvalue(ra, r); \
+ } \
+ else \
+ Protect(Logic(L, ra, rb, rc, tm)); \
+ }
+#endif
+
+
void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
@@ -503,6 +544,44 @@
}
continue;
}
+#if defined(LUA_BITWISE_OPERATORS)
+ case OP_BOR: {
+ logic_op(luai_logor, TM_BOR);
+ continue;
+ }
+ case OP_BAND: {
+ logic_op(luai_logand, TM_BAND);
+ continue;
+ }
+ case OP_BXOR: {
+ logic_op(luai_logxor, TM_BXOR);
+ continue;
+ }
+ case OP_BLSHFT: {
+ logic_op(luai_loglshft, TM_BRSHFT);
+ continue;
+ }
+ case OP_BRSHFT: {
+ logic_op(luai_logrshft, TM_BRSHFT);
+ continue;
+ }
+ case OP_BNOT: {
+ TValue *rb = RB(i);
+ if (ttisnumber(rb)) {
+ lua_Integer r;
+ luai_lognot(r, nvalue(rb));
+ setnvalue(ra, r);
+ }
+ else {
+ Protect(Logic(L, ra, rb, rb, TM_BNOT));
+ }
+ continue;
+ }
+ case OP_INTDIV: {
+ arith_op(luai_numintdiv, TM_DIV);
+ continue;
+ }
+#endif
case OP_NOT: {
int res = l_isfalse(RB(i)); /* next assignment may change this value */
setbvalue(ra, res);
diff -urN lua-5.1.1/test/bitwisepatchtest.lua lua-5.1.1.patched/test/bitwisepatchtest.lua
--- lua-5.1.1/test/bitwisepatchtest.lua 1970-01-01 01:00:00.000000000 +0100
+++ lua-5.1.1.patched/test/bitwisepatchtest.lua 2006-06-20 16:30:41.000000000 +0200
@@ -0,0 +1,24 @@
+hex=function (i) return "0x"..string.format("%X", i) end
+print(hex(0x54|0x55))
+print(hex(0x54&0x66))
+print(hex(0x54^|0x66))
+print(hex(~0x54))
+print(hex(0xF<< 4))
+print(hex(0xF0>> 4))
+a,b=0x54,0x55
+print(hex(a),"|",hex(b), "=",hex(a|b))
+print(hex(a),"|","0x55", "=",hex(a|0x55))
+print(hex(a),"|","0x5|0x50 (", hex(0x5|0x50), ") =",hex(a|(0x5|0x50)))
+a,b=0x54,0x66
+print(hex(a),"&",hex(b), "=",hex(a&b))
+print(hex(a),"&","0x66", "=",hex(a&0x66))
+print(hex(a),"^|",hex(b), "=",hex(a^|b))
+print(hex(a),"^|","0x66", "=",hex(a^|0x66))
+print("~"..hex(a),"=",hex(~a))
+a,b=0xF,0xF0
+print(hex(a).."<<4","=",hex(a<<4))
+print(hex(b)..">>4","=",hex(b>>4))
+a,b=0xF,4
+print(hex(a).."<<"..b,"=",hex(a<<b))
+a,b=0xF0,4
+print(hex(a)..">>"..b,"=",hex(a>>b))