1 /*
2  * This is the bit32 library from lua 5.2.0, backported to
3  * lua 5.1.4.
4  *
5  * http://smbolton.com/lua/lbitlib-5.2.0-backport4.c
6  * version 5.2.0-backport4
7  *
8  * This backport was assembled by Sean Bolton (sean at smbolton
9  * dot com) almost entirely from the above mentioned Lua distributions,
10  * which are:
11  *
12  * Copyright (C) 1994-2011 Lua.org, PUC-Rio.  All rights reserved.
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining
15  * a copy of this software and associated documentation files (the
16  * "Software"), to deal in the Software without restriction, including
17  * without limitation the rights to use, copy, modify, merge, publish,
18  * distribute, sublicense, and/or sell copies of the Software, and to
19  * permit persons to whom the Software is furnished to do so, subject to
20  * the following conditions:
21  *
22  * The above copyright notice and this permission notice shall be
23  * included in all copies or substantial portions of the Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
29  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
30  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32  */
33 
34 #define LUA_LIB
35 
36 #include "lua.h"
37 #include "lauxlib.h"
38 #include "lualib.h"  /* for #define LUA_BITLIBNAME in Lua 5.2 and LuaJIT */
39 
40 /* We install into "bit32" which doesn't conflict with LuaJIT's "bit" */
41 #if (LUA_VERSION_NUM < 502)
42 
43 #define LUA_BITLIBNAME	"bit32"
44 
45 /* ----- adapted from lua-5.2.0 luaconf.h: ----- */
46 
47 /*
48 @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
49 ** It must have at least 32 bits.
50 */
51 #if !defined(LUAI_INT32)
52 #if INT_MAX <= 32767
53 #define LUAI_INT32 long
54 #else
55 #define LUAI_INT32 int
56 #endif
57 #endif
58 
59 #define LUA_UNSIGNED    unsigned LUAI_INT32
60 
61 #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI)    /* { */
62 
63 /* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
64    with a DirectX idiosyncrasy */
65 #if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86)	/* { */
66 
67 #define MS_ASMTRICK
68 
69 #else                           /* }{ */
70 /* the next definition uses a trick that should work on any machine
71    using IEEE754 with a 32-bit integer type */
72 
73 #define LUA_IEEE754TRICK
74 
75 /*
76 @@ LUA_IEEEENDIAN is the endianness of doubles in your machine
77 ** (0 for little endian, 1 for big endian); if not defined, Lua will
78 ** check it dynamically.
79 */
80 /* check for known architectures */
81 #if defined(__i386__) || defined(__i386) || defined(__X86__) || \
82     defined (__x86_64)
83 #define LUA_IEEEENDIAN  0
84 #elif defined(__POWERPC__) || defined(__ppc__)
85 #define LUA_IEEEENDIAN  1
86 #endif
87 
88 #endif                          /* } */
89 
90 #endif                  /* } */
91 
92 /* ----- from lua-5.2.0 lua.h: ----- */
93 
94 /* unsigned integer type */
95 typedef LUA_UNSIGNED lua_Unsigned;
96 
97 /* ----- adapted from lua-5.2.0 llimits.h: ----- */
98 
99 /* lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
100 ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
101 */
102 
103 #if defined(MS_ASMTRICK)        /* { */
104 /* trick with Microsoft assembler for X86 */
105 
106 #define lua_number2unsigned(i,n)  \
107   {__int64 l; __asm {__asm fld n   __asm fistp l} i = (unsigned int)l;}
108 
109 #elif defined(LUA_IEEE754TRICK)         /* }{ */
110 /* the next trick should work on any machine using IEEE754 with
111    a 32-bit integer type */
112 
113 union luai_Cast2 { double l_d; LUAI_INT32 l_p[2]; };
114 
115 #if !defined(LUA_IEEEENDIAN)    /* { */
116 #define LUAI_EXTRAIEEE  \
117   static const union luai_Cast2 ieeeendian = {-(33.0 + 6755399441055744.0)};
118 #define LUA_IEEEENDIAN          (ieeeendian.l_p[1] == 33)
119 #else
120 #define LUAI_EXTRAIEEE          /* empty */
121 #endif                          /* } */
122 
123 #define lua_number2int32(i,n,t) \
124   { LUAI_EXTRAIEEE \
125     volatile union luai_Cast2 u; u.l_d = (n) + 6755399441055744.0; \
126     (i) = (t)u.l_p[LUA_IEEEENDIAN]; }
127 
128 #define lua_number2unsigned(i,n)        lua_number2int32(i, n, lua_Unsigned)
129 
130 #endif                          /* } */
131 
132 #if !defined(lua_number2unsigned)       /* { */
133 /* the following definition assures proper modulo behavior */
134 #if defined(LUA_NUMBER_DOUBLE)
135 #include <math.h>
136 #define SUPUNSIGNED     ((lua_Number)(~(lua_Unsigned)0) + 1)
137 #define lua_number2unsigned(i,n)  \
138         ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
139 #else
140 #define lua_number2unsigned(i,n)        ((i)=(lua_Unsigned)(n))
141 #endif
142 #endif                          /* } */
143 
144 /* on several machines, coercion from unsigned to double is slow,
145    so it may be worth to avoid */
146 #define lua_unsigned2number(u)  \
147     (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
148 
149 /* ----- adapted from lua-5.2.0 lapi.c: ----- */
150 
lua_pushunsigned(lua_State * L,lua_Unsigned u)151 static void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
152   lua_Number n;
153   n = lua_unsigned2number(u);
154   lua_pushnumber(L, n);
155 }
156 
157 /* ----- adapted from lua-5.2.0-work3 lbitlib.c getuintarg(): ----- */
158 
luaL_checkunsigned(lua_State * L,int arg)159 static lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) {
160   lua_Unsigned r;
161   lua_Number x = lua_tonumber(L, arg);
162   if (x == 0) luaL_checktype(L, arg, LUA_TNUMBER);
163   lua_number2unsigned(r, x);
164   return r;
165 }
166 
167 /* ----- Lua 5.2 luaL_newlib() compatibility: ----- */
168 
169 #define LUAMOD_API  LUALIB_API
170 /* #define LUA_BITLIBNAME "bit32" */
171 /* #define luaL_newlib(x, y) luaL_register(x, LUA_BITLIBNAME, y) */
172 
173 /* ----- avoid a 'symbol redefined' warning below ----- */
174 
175 #undef LUA_LIB
176 
177 /* ----- here follows the unmodified lbitlib.c from Lua 5.2.0 ----- */
178 
179 /*
180 ** $Id: lbitlib.c,v 1.16 2011/06/20 16:35:23 roberto Exp $
181 ** Standard library for bitwise operations
182 ** See Copyright Notice in lua.h
183 */
184 
185 #define lbitlib_c
186 #define LUA_LIB
187 
188 #include "lua.h"
189 
190 #include "lauxlib.h"
191 #include "lualib.h"
192 
193 
194 /* number of bits to consider in a number */
195 #if !defined(LUA_NBITS)
196 #define LUA_NBITS	32
197 #endif
198 
199 
200 #define ALLONES		(~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
201 
202 /* macro to trim extra bits */
203 #define trim(x)		((x) & ALLONES)
204 
205 
206 /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
207 #define mask(n)		(~((ALLONES << 1) << ((n) - 1)))
208 
209 
210 typedef lua_Unsigned b_uint;
211 
212 
213 
andaux(lua_State * L)214 static b_uint andaux (lua_State *L) {
215   int i, n = lua_gettop(L);
216   b_uint r = ~(b_uint)0;
217   for (i = 1; i <= n; i++)
218     r &= luaL_checkunsigned(L, i);
219   return trim(r);
220 }
221 
222 
b_and(lua_State * L)223 static int b_and (lua_State *L) {
224   b_uint r = andaux(L);
225   lua_pushunsigned(L, r);
226   return 1;
227 }
228 
229 
b_test(lua_State * L)230 static int b_test (lua_State *L) {
231   b_uint r = andaux(L);
232   lua_pushboolean(L, r != 0);
233   return 1;
234 }
235 
236 
b_or(lua_State * L)237 static int b_or (lua_State *L) {
238   int i, n = lua_gettop(L);
239   b_uint r = 0;
240   for (i = 1; i <= n; i++)
241     r |= luaL_checkunsigned(L, i);
242   lua_pushunsigned(L, trim(r));
243   return 1;
244 }
245 
246 
b_xor(lua_State * L)247 static int b_xor (lua_State *L) {
248   int i, n = lua_gettop(L);
249   b_uint r = 0;
250   for (i = 1; i <= n; i++)
251     r ^= luaL_checkunsigned(L, i);
252   lua_pushunsigned(L, trim(r));
253   return 1;
254 }
255 
256 
b_not(lua_State * L)257 static int b_not (lua_State *L) {
258   b_uint r = ~luaL_checkunsigned(L, 1);
259   lua_pushunsigned(L, trim(r));
260   return 1;
261 }
262 
263 
b_shift(lua_State * L,b_uint r,int i)264 static int b_shift (lua_State *L, b_uint r, int i) {
265   if (i < 0) {  /* shift right? */
266     i = -i;
267     r = trim(r);
268     if (i >= LUA_NBITS) r = 0;
269     else r >>= i;
270   }
271   else {  /* shift left */
272     if (i >= LUA_NBITS) r = 0;
273     else r <<= i;
274     r = trim(r);
275   }
276   lua_pushunsigned(L, r);
277   return 1;
278 }
279 
280 
b_lshift(lua_State * L)281 static int b_lshift (lua_State *L) {
282   return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
283 }
284 
285 
b_rshift(lua_State * L)286 static int b_rshift (lua_State *L) {
287   return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
288 }
289 
290 
b_arshift(lua_State * L)291 static int b_arshift (lua_State *L) {
292   b_uint r = luaL_checkunsigned(L, 1);
293   int i = luaL_checkint(L, 2);
294   if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
295     return b_shift(L, r, -i);
296   else {  /* arithmetic shift for 'negative' number */
297     if (i >= LUA_NBITS) r = ALLONES;
298     else
299       r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
300     lua_pushunsigned(L, r);
301     return 1;
302   }
303 }
304 
305 
b_rot(lua_State * L,int i)306 static int b_rot (lua_State *L, int i) {
307   b_uint r = luaL_checkunsigned(L, 1);
308   i &= (LUA_NBITS - 1);  /* i = i % NBITS */
309   r = trim(r);
310   r = (r << i) | (r >> (LUA_NBITS - i));
311   lua_pushunsigned(L, trim(r));
312   return 1;
313 }
314 
315 
b_lrot(lua_State * L)316 static int b_lrot (lua_State *L) {
317   return b_rot(L, luaL_checkint(L, 2));
318 }
319 
320 
b_rrot(lua_State * L)321 static int b_rrot (lua_State *L) {
322   return b_rot(L, -luaL_checkint(L, 2));
323 }
324 
325 
326 /*
327 ** get field and width arguments for field-manipulation functions,
328 ** checking whether they are valid
329 */
fieldargs(lua_State * L,int farg,int * width)330 static int fieldargs (lua_State *L, int farg, int *width) {
331   int f = luaL_checkint(L, farg);
332   int w = luaL_optint(L, farg + 1, 1);
333   luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
334   luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
335   if (f + w > LUA_NBITS)
336     luaL_error(L, "trying to access non-existent bits");
337   *width = w;
338   return f;
339 }
340 
341 
b_extract(lua_State * L)342 static int b_extract (lua_State *L) {
343   int w;
344   b_uint r = luaL_checkunsigned(L, 1);
345   int f = fieldargs(L, 2, &w);
346   r = (r >> f) & mask(w);
347   lua_pushunsigned(L, r);
348   return 1;
349 }
350 
351 
b_replace(lua_State * L)352 static int b_replace (lua_State *L) {
353   int w;
354   b_uint r = luaL_checkunsigned(L, 1);
355   b_uint v = luaL_checkunsigned(L, 2);
356   int f = fieldargs(L, 3, &w);
357   int m = mask(w);
358   v &= m;  /* erase bits outside given width */
359   r = (r & ~(m << f)) | (v << f);
360   lua_pushunsigned(L, r);
361   return 1;
362 }
363 
364 
365 static const luaL_Reg bitlib[] = {
366   {"arshift", b_arshift},
367   {"band", b_and},
368   {"bnot", b_not},
369   {"bor", b_or},
370   {"bxor", b_xor},
371   {"btest", b_test},
372   {"extract", b_extract},
373   {"lrotate", b_lrot},
374   {"lshift", b_lshift},
375   {"replace", b_replace},
376   {"rrotate", b_rrot},
377   {"rshift", b_rshift},
378   {NULL, NULL}
379 };
380 
381 
382 
luaopen_bit32(lua_State * L)383 LUAMOD_API int luaopen_bit32 (lua_State *L) {
384   /* luaL_newlib(L, bitlib); */
385   luaL_register(L, LUA_BITLIBNAME, bitlib);
386   return 1;
387 }
388 
389 #endif // (LUA_VERSION_NUM < 502)
390