LCOV - code coverage report
Current view: top level - src - lbitlib.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 100.0 % 94 94
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1