aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-10-28 13:17:29 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-10-28 13:17:29 -0200
commitf39034889d010f6f81257dde9517a9ad4d021d1c (patch)
tree766b5429e95c6ae6a0753ce7c3f67c66095c6bfa
parent6b053a63cb10395d310a043b91bd421656446e78 (diff)
downloadlua-f39034889d010f6f81257dde9517a9ad4d021d1c.tar.gz
lua-f39034889d010f6f81257dde9517a9ad4d021d1c.tar.bz2
lua-f39034889d010f6f81257dde9517a9ad4d021d1c.zip
stricter control over number of bits in each operation
-rw-r--r--lbitlib.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/lbitlib.c b/lbitlib.c
index db8a1d5f..0656ce28 100644
--- a/lbitlib.c
+++ b/lbitlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbitlib.c,v 1.8 2010/10/25 20:31:11 roberto Exp roberto $ 2** $Id: lbitlib.c,v 1.9 2010/10/27 16:50:32 roberto Exp roberto $
3** Standard library for bitwise operations 3** Standard library for bitwise operations
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,12 +13,16 @@
13#include "lualib.h" 13#include "lualib.h"
14 14
15 15
16/* number of bits considered when shifting/rotating (must be a power of 2) */ 16/* number of bits to consider in a number */
17#define NBITS 32 17#define NBITS 32
18 18
19#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1))
19 20
20typedef LUA_INT32 b_int; 21/* mask to trim extra bits */
21typedef unsigned LUA_INT32 b_uint; 22#define trim(x) ((x) & ALLONES)
23
24
25typedef lua_Unsigned b_uint;
22 26
23 27
24#define getuintarg(L,arg) luaL_checkunsigned(L,arg) 28#define getuintarg(L,arg) luaL_checkunsigned(L,arg)
@@ -29,7 +33,7 @@ static b_uint andaux (lua_State *L) {
29 b_uint r = ~(b_uint)0; 33 b_uint r = ~(b_uint)0;
30 for (i = 1; i <= n; i++) 34 for (i = 1; i <= n; i++)
31 r &= getuintarg(L, i); 35 r &= getuintarg(L, i);
32 return r; 36 return trim(r);
33} 37}
34 38
35 39
@@ -52,7 +56,7 @@ static int b_or (lua_State *L) {
52 b_uint r = 0; 56 b_uint r = 0;
53 for (i = 1; i <= n; i++) 57 for (i = 1; i <= n; i++)
54 r |= getuintarg(L, i); 58 r |= getuintarg(L, i);
55 lua_pushunsigned(L, r); 59 lua_pushunsigned(L, trim(r));
56 return 1; 60 return 1;
57} 61}
58 62
@@ -62,14 +66,14 @@ static int b_xor (lua_State *L) {
62 b_uint r = 0; 66 b_uint r = 0;
63 for (i = 1; i <= n; i++) 67 for (i = 1; i <= n; i++)
64 r ^= getuintarg(L, i); 68 r ^= getuintarg(L, i);
65 lua_pushunsigned(L, r); 69 lua_pushunsigned(L, trim(r));
66 return 1; 70 return 1;
67} 71}
68 72
69 73
70static int b_not (lua_State *L) { 74static int b_not (lua_State *L) {
71 b_uint r = ~getuintarg(L, 1); 75 b_uint r = ~getuintarg(L, 1);
72 lua_pushunsigned(L, r); 76 lua_pushunsigned(L, trim(r));
73 return 1; 77 return 1;
74} 78}
75 79
@@ -77,12 +81,14 @@ static int b_not (lua_State *L) {
77static int b_shift (lua_State *L, b_uint r, int i) { 81static int b_shift (lua_State *L, b_uint r, int i) {
78 if (i < 0) { /* shift right? */ 82 if (i < 0) { /* shift right? */
79 i = -i; 83 i = -i;
84 r = trim(r);
80 if (i >= NBITS) r = 0; 85 if (i >= NBITS) r = 0;
81 else r >>= i; 86 else r >>= i;
82 } 87 }
83 else { /* shift left */ 88 else { /* shift left */
84 if (i >= NBITS) r = 0; 89 if (i >= NBITS) r = 0;
85 else r <<= i; 90 else r <<= i;
91 r = trim(r);
86 } 92 }
87 lua_pushunsigned(L, r); 93 lua_pushunsigned(L, r);
88 return 1; 94 return 1;
@@ -102,12 +108,12 @@ static int b_rshift (lua_State *L) {
102static int b_arshift (lua_State *L) { 108static int b_arshift (lua_State *L) {
103 b_uint r = getuintarg(L, 1); 109 b_uint r = getuintarg(L, 1);
104 int i = luaL_checkint(L, 2); 110 int i = luaL_checkint(L, 2);
105 if (i < 0 || !(r & 0x80000000)) 111 if (i < 0 || !(r & (1 << (NBITS - 1))))
106 return b_shift(L, r, -i); 112 return b_shift(L, r, -i);
107 else { /* arithmetic shift for 'negative' number */ 113 else { /* arithmetic shift for 'negative' number */
108 if (i >= NBITS) r = 0xffffffff; 114 if (i >= NBITS) r = ALLONES;
109 else 115 else
110 r = (r >> i) | ~(~(b_uint)0 >> i); /* add signal bit */ 116 r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
111 lua_pushunsigned(L, r); 117 lua_pushunsigned(L, r);
112 return 1; 118 return 1;
113 } 119 }
@@ -117,8 +123,9 @@ static int b_arshift (lua_State *L) {
117static int b_rot (lua_State *L, int i) { 123static int b_rot (lua_State *L, int i) {
118 b_uint r = getuintarg(L, 1); 124 b_uint r = getuintarg(L, 1);
119 i &= (NBITS - 1); /* i = i % NBITS */ 125 i &= (NBITS - 1); /* i = i % NBITS */
126 r = trim(r);
120 r = (r << i) | (r >> (NBITS - i)); 127 r = (r << i) | (r >> (NBITS - i));
121 lua_pushunsigned(L, r); 128 lua_pushunsigned(L, trim(r));
122 return 1; 129 return 1;
123} 130}
124 131
@@ -153,3 +160,4 @@ LUAMOD_API int luaopen_bit32 (lua_State *L) {
153 luaL_newlib(L, bitlib); 160 luaL_newlib(L, bitlib);
154 return 1; 161 return 1;
155} 162}
163