Coverage Report

Created: 2025-12-28 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tarantool/third_party/luajit/src/lib_bit.c
Line
Count
Source
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
114k
{
34
114k
  GCcdata *cd = lj_cdata_new_(L, id, 8);
35
114k
  *(uint64_t *)cdataptr(cd) = x;
36
114k
  setcdataV(L, L->base-1-LJ_FR2, cd);
37
114k
  return FFH_RES(1);
38
114k
}
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
261
{
57
261
#if LJ_HASFFI
58
261
  CTypeID id = 0;
59
261
  setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id));
60
261
  return FFH_RES(1);
61
#else
62
  lj_lib_checknumber(L, 1);
63
  return FFH_RETRY;
64
#endif
65
261
}
66
67
LJLIB_ASM(bit_bnot)   LJLIB_REC(bit_unary IR_BNOT)
68
339
{
69
339
#if LJ_HASFFI
70
339
  CTypeID id = 0;
71
339
  uint64_t x = lj_carith_check64(L, 1, &id);
72
339
  return id ? bit_result64(L, id, ~x) : FFH_RETRY;
73
#else
74
  lj_lib_checknumber(L, 1);
75
  return FFH_RETRY;
76
#endif
77
339
}
78
79
LJLIB_ASM(bit_bswap)    LJLIB_REC(bit_unary IR_BSWAP)
80
313
{
81
313
#if LJ_HASFFI
82
313
  CTypeID id = 0;
83
313
  uint64_t x = lj_carith_check64(L, 1, &id);
84
313
  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
313
}
90
91
LJLIB_ASM(bit_lshift)   LJLIB_REC(bit_shift IR_BSHL)
92
158
{
93
158
#if LJ_HASFFI
94
158
  CTypeID id = 0, id2 = 0;
95
158
  uint64_t x = lj_carith_check64(L, 1, &id);
96
158
  int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
97
158
  if (id) {
98
0
    x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
99
0
    return bit_result64(L, id, x);
100
0
  }
101
158
  setintV(L->base+1, sh);
102
158
  return FFH_RETRY;
103
#else
104
  lj_lib_checknumber(L, 1);
105
  bit_checkbit(L, 2);
106
  return FFH_RETRY;
107
#endif
108
158
}
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
131k
{
116
131k
#if LJ_HASFFI
117
131k
  CTypeID id = 0;
118
131k
  TValue *o = L->base, *top = L->top;
119
131k
  int i = 0;
120
359k
  do { lj_carith_check64(L, ++i, &id); } while (++o < top);
121
131k
  if (id) {
122
114k
    CTState *cts = ctype_cts(L);
123
114k
    CType *ct = ctype_get(cts, id);
124
114k
    int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
125
114k
    uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
126
114k
    o = L->base;
127
342k
    do {
128
342k
      lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
129
342k
      if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
130
342k
    } while (++o < top);
131
114k
    return bit_result64(L, id, y);
132
114k
  }
133
16.7k
  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
131k
}
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
0
{
147
0
#if LJ_HASFFI
148
0
  CTypeID id = 0, id2 = 0;
149
0
  uint64_t b = lj_carith_check64(L, 1, &id);
150
0
  int32_t n = L->base+1>=L->top ? (id ? 16 : 8) :
151
0
          (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
0
  SBuf *sb = lj_buf_tmp_(L);
157
0
  SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
158
0
  if (n < 0) { n = (int32_t)(~(uint32_t)n+1u); sf |= STRFMT_F_UPPER; }
159
0
  if ((uint32_t)n > 254) n = 254;
160
0
  sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
161
0
#if LJ_HASFFI
162
0
  if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
163
#else
164
  if (n < 8) b &= (1u << 4*n)-1;
165
#endif
166
0
  sb = lj_strfmt_putfxint(sb, sf, b);
167
0
  setstrV(L, L->top-1, lj_buf_str(L, sb));
168
0
  lj_gc_check(L);
169
0
  return 1;
170
0
}
171
172
/* ------------------------------------------------------------------------ */
173
174
#include "lj_libdef.h"
175
176
LUALIB_API int luaopen_bit(lua_State *L)
177
28.4k
{
178
28.4k
  LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
179
28.4k
  return 1;
180
28.4k
}
181