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