lbitlib.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. ** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $
  3. ** Standard library for bitwise operations
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define lbitlib_c
  7. #define LUA_LIB
  8. #include "lprefix.h"
  9. #include "lua.h"
  10. #include "lauxlib.h"
  11. #include "lualib.h"
  12. #if defined(LUA_COMPAT_BITLIB) /* { */
  13. #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
  14. #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i))
  15. /* number of bits to consider in a number */
  16. #if !defined(LUA_NBITS)
  17. #define LUA_NBITS 32
  18. #endif
  19. /*
  20. ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
  21. ** be made in two parts to avoid problems when LUA_NBITS is equal to the
  22. ** number of bits in a lua_Unsigned.)
  23. */
  24. #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
  25. /* macro to trim extra bits */
  26. #define trim(x) ((x) & ALLONES)
  27. /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
  28. #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
  29. static lua_Unsigned andaux(lua_State *L)
  30. {
  31. int i, n = lua_gettop(L);
  32. lua_Unsigned r = ~(lua_Unsigned)0;
  33. for (i = 1; i <= n; i++)
  34. r &= checkunsigned(L, i);
  35. return trim(r);
  36. }
  37. static int b_and(lua_State *L)
  38. {
  39. lua_Unsigned r = andaux(L);
  40. pushunsigned(L, r);
  41. return 1;
  42. }
  43. static int b_test(lua_State *L)
  44. {
  45. lua_Unsigned r = andaux(L);
  46. lua_pushboolean(L, r != 0);
  47. return 1;
  48. }
  49. static int b_or(lua_State *L)
  50. {
  51. int i, n = lua_gettop(L);
  52. lua_Unsigned r = 0;
  53. for (i = 1; i <= n; i++)
  54. r |= checkunsigned(L, i);
  55. pushunsigned(L, trim(r));
  56. return 1;
  57. }
  58. static int b_xor(lua_State *L)
  59. {
  60. int i, n = lua_gettop(L);
  61. lua_Unsigned r = 0;
  62. for (i = 1; i <= n; i++)
  63. r ^= checkunsigned(L, i);
  64. pushunsigned(L, trim(r));
  65. return 1;
  66. }
  67. static int b_not(lua_State *L)
  68. {
  69. lua_Unsigned r = ~checkunsigned(L, 1);
  70. pushunsigned(L, trim(r));
  71. return 1;
  72. }
  73. static int b_shift(lua_State *L, lua_Unsigned r, lua_Integer i)
  74. {
  75. if (i < 0) /* shift right? */
  76. {
  77. i = -i;
  78. r = trim(r);
  79. if (i >= LUA_NBITS) r = 0;
  80. else r >>= i;
  81. }
  82. else /* shift left */
  83. {
  84. if (i >= LUA_NBITS) r = 0;
  85. else r <<= i;
  86. r = trim(r);
  87. }
  88. pushunsigned(L, r);
  89. return 1;
  90. }
  91. static int b_lshift(lua_State *L)
  92. {
  93. return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
  94. }
  95. static int b_rshift(lua_State *L)
  96. {
  97. return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
  98. }
  99. static int b_arshift(lua_State *L)
  100. {
  101. lua_Unsigned r = checkunsigned(L, 1);
  102. lua_Integer i = luaL_checkinteger(L, 2);
  103. if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
  104. return b_shift(L, r, -i);
  105. else /* arithmetic shift for 'negative' number */
  106. {
  107. if (i >= LUA_NBITS) r = ALLONES;
  108. else
  109. r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
  110. pushunsigned(L, r);
  111. return 1;
  112. }
  113. }
  114. static int b_rot(lua_State *L, lua_Integer d)
  115. {
  116. lua_Unsigned r = checkunsigned(L, 1);
  117. int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
  118. r = trim(r);
  119. if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
  120. r = (r << i) | (r >> (LUA_NBITS - i));
  121. pushunsigned(L, trim(r));
  122. return 1;
  123. }
  124. static int b_lrot(lua_State *L)
  125. {
  126. return b_rot(L, luaL_checkinteger(L, 2));
  127. }
  128. static int b_rrot(lua_State *L)
  129. {
  130. return b_rot(L, -luaL_checkinteger(L, 2));
  131. }
  132. /*
  133. ** get field and width arguments for field-manipulation functions,
  134. ** checking whether they are valid.
  135. ** ('luaL_error' called without 'return' to avoid later warnings about
  136. ** 'width' being used uninitialized.)
  137. */
  138. static int fieldargs(lua_State *L, int farg, int *width)
  139. {
  140. lua_Integer f = luaL_checkinteger(L, farg);
  141. lua_Integer w = luaL_optinteger(L, farg + 1, 1);
  142. luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
  143. luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
  144. if (f + w > LUA_NBITS)
  145. luaL_error(L, "trying to access non-existent bits");
  146. *width = (int)w;
  147. return (int)f;
  148. }
  149. static int b_extract(lua_State *L)
  150. {
  151. int w;
  152. lua_Unsigned r = trim(checkunsigned(L, 1));
  153. int f = fieldargs(L, 2, &w);
  154. r = (r >> f) & mask(w);
  155. pushunsigned(L, r);
  156. return 1;
  157. }
  158. static int b_replace(lua_State *L)
  159. {
  160. int w;
  161. lua_Unsigned r = trim(checkunsigned(L, 1));
  162. lua_Unsigned v = trim(checkunsigned(L, 2));
  163. int f = fieldargs(L, 3, &w);
  164. lua_Unsigned m = mask(w);
  165. r = (r & ~(m << f)) | ((v & m) << f);
  166. pushunsigned(L, r);
  167. return 1;
  168. }
  169. static const luaL_Reg bitlib[] =
  170. {
  171. {"arshift", b_arshift},
  172. {"band", b_and},
  173. {"bnot", b_not},
  174. {"bor", b_or},
  175. {"bxor", b_xor},
  176. {"btest", b_test},
  177. {"extract", b_extract},
  178. {"lrotate", b_lrot},
  179. {"lshift", b_lshift},
  180. {"replace", b_replace},
  181. {"rrotate", b_rrot},
  182. {"rshift", b_rshift},
  183. {NULL, NULL}
  184. };
  185. LUAMOD_API int luaopen_bit32(lua_State *L)
  186. {
  187. luaL_newlib(L, bitlib);
  188. return 1;
  189. }
  190. #else /* }{ */
  191. LUAMOD_API int luaopen_bit32(lua_State *L)
  192. {
  193. return luaL_error(L, "library 'bit32' has been deprecated");
  194. }
  195. #endif /* } */