root/lib_bit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bit_result64
  2. bit_checkbit
  3. LJLIB_ASM
  4. LJLIB_ASM
  5. LJLIB_ASM
  6. LJLIB_ASM
  7. LJLIB_ASM_
  8. LJLIB_ASM_
  9. luaopen_bit

   1 /*
   2 ** Bit manipulation library.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #define lib_bit_c
   7 #define LUA_LIB
   8 
   9 #include "lua.h"
  10 #include "lauxlib.h"
  11 #include "lualib.h"
  12 
  13 #include "lj_obj.h"
  14 #include "lj_err.h"
  15 #include "lj_buf.h"
  16 #include "lj_strscan.h"
  17 #include "lj_strfmt.h"
  18 #if LJ_HASFFI
  19 #include "lj_ctype.h"
  20 #include "lj_cdata.h"
  21 #include "lj_cconv.h"
  22 #include "lj_carith.h"
  23 #endif
  24 #include "lj_ff.h"
  25 #include "lj_lib.h"
  26 
  27 /* ------------------------------------------------------------------------ */
  28 
  29 #define LJLIB_MODULE_bit
  30 
  31 #if LJ_HASFFI
  32 static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
  33 {
  34   GCcdata *cd = lj_cdata_new_(L, id, 8);
  35   *(uint64_t *)cdataptr(cd) = x;
  36   setcdataV(L, L->base-1-LJ_FR2, cd);
  37   return FFH_RES(1);
  38 }
  39 #else
  40 static int32_t bit_checkbit(lua_State *L, int narg)
  41 {
  42   TValue *o = L->base + narg-1;
  43   if (!(o < L->top && lj_strscan_numberobj(o)))
  44     lj_err_argt(L, narg, LUA_TNUMBER);
  45   if (LJ_LIKELY(tvisint(o))) {
  46     return intV(o);
  47   } else {
  48     int32_t i = lj_num2bit(numV(o));
  49     if (LJ_DUALNUM) setintV(o, i);
  50     return i;
  51   }
  52 }
  53 #endif
  54 
  55 LJLIB_ASM(bit_tobit)            LJLIB_REC(bit_tobit)
  56 {
  57 #if LJ_HASFFI
  58   CTypeID id = 0;
  59   setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id));
  60   return FFH_RES(1);
  61 #else
  62   lj_lib_checknumber(L, 1);
  63   return FFH_RETRY;
  64 #endif
  65 }
  66 
  67 LJLIB_ASM(bit_bnot)             LJLIB_REC(bit_unary IR_BNOT)
  68 {
  69 #if LJ_HASFFI
  70   CTypeID id = 0;
  71   uint64_t x = lj_carith_check64(L, 1, &id);
  72   return id ? bit_result64(L, id, ~x) : FFH_RETRY;
  73 #else
  74   lj_lib_checknumber(L, 1);
  75   return FFH_RETRY;
  76 #endif
  77 }
  78 
  79 LJLIB_ASM(bit_bswap)            LJLIB_REC(bit_unary IR_BSWAP)
  80 {
  81 #if LJ_HASFFI
  82   CTypeID id = 0;
  83   uint64_t x = lj_carith_check64(L, 1, &id);
  84   return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
  85 #else
  86   lj_lib_checknumber(L, 1);
  87   return FFH_RETRY;
  88 #endif
  89 }
  90 
  91 LJLIB_ASM(bit_lshift)           LJLIB_REC(bit_shift IR_BSHL)
  92 {
  93 #if LJ_HASFFI
  94   CTypeID id = 0, id2 = 0;
  95   uint64_t x = lj_carith_check64(L, 1, &id);
  96   int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
  97   if (id) {
  98     x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
  99     return bit_result64(L, id, x);
 100   }
 101   if (id2) setintV(L->base+1, sh);
 102   return FFH_RETRY;
 103 #else
 104   lj_lib_checknumber(L, 1);
 105   bit_checkbit(L, 2);
 106   return FFH_RETRY;
 107 #endif
 108 }
 109 LJLIB_ASM_(bit_rshift)          LJLIB_REC(bit_shift IR_BSHR)
 110 LJLIB_ASM_(bit_arshift)         LJLIB_REC(bit_shift IR_BSAR)
 111 LJLIB_ASM_(bit_rol)             LJLIB_REC(bit_shift IR_BROL)
 112 LJLIB_ASM_(bit_ror)             LJLIB_REC(bit_shift IR_BROR)
 113 
 114 LJLIB_ASM(bit_band)             LJLIB_REC(bit_nary IR_BAND)
 115 {
 116 #if LJ_HASFFI
 117   CTypeID id = 0;
 118   TValue *o = L->base, *top = L->top;
 119   int i = 0;
 120   do { lj_carith_check64(L, ++i, &id); } while (++o < top);
 121   if (id) {
 122     CTState *cts = ctype_cts(L);
 123     CType *ct = ctype_get(cts, id);
 124     int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
 125     uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
 126     o = L->base;
 127     do {
 128       lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
 129       if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
 130     } while (++o < top);
 131     return bit_result64(L, id, y);
 132   }
 133   return FFH_RETRY;
 134 #else
 135   int i = 0;
 136   do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
 137   return FFH_RETRY;
 138 #endif
 139 }
 140 LJLIB_ASM_(bit_bor)             LJLIB_REC(bit_nary IR_BOR)
 141 LJLIB_ASM_(bit_bxor)            LJLIB_REC(bit_nary IR_BXOR)
 142 
 143 /* ------------------------------------------------------------------------ */
 144 
 145 LJLIB_CF(bit_tohex)             LJLIB_REC(.)
 146 {
 147 #if LJ_HASFFI
 148   CTypeID id = 0, id2 = 0;
 149   uint64_t b = lj_carith_check64(L, 1, &id);
 150   int32_t n = L->base+1>=L->top ? (id ? 16 : 8) :
 151                                   (int32_t)lj_carith_check64(L, 2, &id2);
 152 #else
 153   uint32_t b = (uint32_t)bit_checkbit(L, 1);
 154   int32_t n = L->base+1>=L->top ? 8 : bit_checkbit(L, 2);
 155 #endif
 156   SBuf *sb = lj_buf_tmp_(L);
 157   SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
 158   if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
 159   sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
 160 #if LJ_HASFFI
 161   if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
 162 #else
 163   if (n < 8) b &= (1u << 4*n)-1;
 164 #endif
 165   sb = lj_strfmt_putfxint(sb, sf, b);
 166   setstrV(L, L->top-1, lj_buf_str(L, sb));
 167   lj_gc_check(L);
 168   return 1;
 169 }
 170 
 171 /* ------------------------------------------------------------------------ */
 172 
 173 #include "lj_libdef.h"
 174 
 175 LUALIB_API int luaopen_bit(lua_State *L)
 176 {
 177   LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
 178   return 1;
 179 }
 180 

/* [<][>][^][v][top][bottom][index][help] */