/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 | | |