1 /* 2 ** Lua BitOp -- a bit operations library for Lua 5.1/5.2. 3 ** http://bitop.luajit.org/ 4 ** 5 ** Copyright (C) 2008-2012 Mike Pall. All rights reserved. 6 ** 7 ** SPDX-License-Identifier: MIT 8 ** 9 */ 10 11 #define LUA_BITOP_VERSION "1.0.2" 12 13 #define LUA_LIB 14 #include <lua.h> 15 #include <lauxlib.h> 16 17 #include "lua_bitop.h" 18 #include "ws_diag_control.h" 19 20 #include <stdint.h> 21 22 typedef int32_t SBits; 23 typedef uint32_t UBits; phaserize(PyObject * self,PyObject * args)24 25 typedef union { 26 lua_Number n; 27 #ifdef LUA_NUMBER_DOUBLE 28 uint64_t b; 29 #else 30 UBits b; 31 #endif 32 } BitNum; 33 34 /* Convert argument to bit type. */ 35 static UBits barg(lua_State *L, int idx) 36 { 37 BitNum bn; 38 UBits b; 39 #if LUA_VERSION_NUM < 502 40 bn.n = lua_tonumber(L, idx); 41 #else 42 bn.n = luaL_checknumber(L, idx); 43 #endif 44 #if defined(LUA_NUMBER_DOUBLE) 45 bn.n += 6755399441055744.0; /* 2^52+2^51 */ 46 #ifdef SWAPPED_DOUBLE 47 b = (UBits)(bn.b >> 32); 48 #else PyInit_tachyon(void)49 b = (UBits)bn.b; 50 #endif 51 #elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ 52 defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ 53 defined(LUA_NUMBER_LLONG) 54 if (sizeof(UBits) == sizeof(lua_Number)) 55 b = bn.b; 56 else 57 b = (UBits)(SBits)bn.n; 58 #elif defined(LUA_NUMBER_FLOAT) 59 #error "A 'float' lua_Number type is incompatible with this library" 60 #else 61 #error "Unknown number type, check LUA_NUMBER_* in luaconf.h" 62 #endif 63 #if LUA_VERSION_NUM < 502 64 if (b == 0 && !lua_isnumber(L, idx)) { 65 luaL_typerror(L, idx, "number"); 66 } 67 #endif 68 return b; 69 } 70 71 /* Return bit type. */ 72 #define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; 73 74 static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } 75 static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } 76 77 #define BIT_OP(func, opr) \ 78 static int func(lua_State *L) { int i; UBits b = barg(L, 1); \ 79 for (i = lua_gettop(L); i > 1; i--) { b opr barg(L, i); } BRET(b) } 80 BIT_OP(bit_band, &=) 81 BIT_OP(bit_bor, |=) 82 BIT_OP(bit_bxor, ^=) 83 84 #define bshl(b, n) (b << n) 85 #define bshr(b, n) (b >> n) 86 #define bsar(b, n) ((SBits)b >> n) 87 #define brol(b, n) ((b << n) | (b >> (32-n))) 88 #define bror(b, n) ((b << (32-n)) | (b >> n)) 89 #define BIT_SH(func, fn) \ 90 static int func(lua_State *L) { \ 91 UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } 92 BIT_SH(bit_lshift, bshl) 93 BIT_SH(bit_rshift, bshr) 94 BIT_SH(bit_arshift, bsar) 95 BIT_SH(bit_rol, brol) 96 BIT_SH(bit_ror, bror) 97 98 static int bit_bswap(lua_State *L) 99 { 100 UBits b = barg(L, 1); 101 b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); 102 BRET(b) 103 } 104 105 static int bit_tohex(lua_State *L) 106 { 107 UBits b = barg(L, 1); 108 SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); 109 const char *hexdigits = "0123456789abcdef"; 110 char buf[8]; 111 int i; 112 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 113 if (n > 8) n = 8; 114 for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } 115 lua_pushlstring(L, buf, (size_t)n); 116 return 1; 117 } 118 119 static const struct luaL_Reg bit_funcs[] = { 120 { "tobit", bit_tobit }, 121 { "bnot", bit_bnot }, 122 { "band", bit_band }, 123 { "bor", bit_bor }, 124 { "bxor", bit_bxor }, 125 { "lshift", bit_lshift }, 126 { "rshift", bit_rshift }, 127 { "arshift", bit_arshift }, 128 { "rol", bit_rol }, 129 { "ror", bit_ror }, 130 { "bswap", bit_bswap }, 131 { "tohex", bit_tohex }, 132 { NULL, NULL } 133 }; 134 135 /* Signed right-shifts are implementation-defined per C89/C99. 136 ** But the de facto standard are arithmetic right-shifts on two's 137 ** complement CPUs. This behaviour is required here, so test for it. 138 */ 139 #define BAD_SAR (bsar(-8, 2) != (SBits)-2) 140 141 LUALIB_API int luaopen_bit(lua_State *L) 142 { 143 UBits b; 144 lua_pushnumber(L, (lua_Number)1437217655L); 145 b = barg(L, -1); 146 if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */ 147 const char *msg = "compiled with incompatible luaconf.h"; 148 #ifdef LUA_NUMBER_DOUBLE 149 #ifdef _WIN32 150 if (b == (UBits)1610612736L) 151 msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; 152 #endif 153 if (b == (UBits)1127743488L) 154 msg = "not compiled with SWAPPED_DOUBLE"; 155 #endif 156 DIAG_OFF(unreachable-code) 157 if (BAD_SAR) 158 msg = "arithmetic right-shift broken"; 159 DIAG_ON(unreachable-code) 160 luaL_error(L, "bit library self-test failed (%s)", msg); 161 } 162 #if LUA_VERSION_NUM < 502 163 luaL_register(L, "bit", bit_funcs); 164 return 1; 165 #else 166 luaL_newlib(L, bit_funcs); 167 lua_setglobal(L, "bit"); /* added for wireshark */ 168 return 0; /* changed from 1 to 0 for wireshark, since lua_setglobal now pops the table */ 169 #endif 170 } 171 172