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