aboutsummaryrefslogtreecommitdiff
path: root/src/lib_bit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_bit.c')
-rw-r--r--src/lib_bit.c98
1 files changed, 92 insertions, 6 deletions
diff --git a/src/lib_bit.c b/src/lib_bit.c
index 93fead92..85821b81 100644
--- a/src/lib_bit.c
+++ b/src/lib_bit.c
@@ -13,25 +13,82 @@
13#include "lj_obj.h" 13#include "lj_obj.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_str.h" 15#include "lj_str.h"
16#if LJ_HASFFI
17#include "lj_ctype.h"
18#include "lj_cdata.h"
19#include "lj_cconv.h"
20#include "lj_carith.h"
21#endif
22#include "lj_ff.h"
16#include "lj_lib.h" 23#include "lj_lib.h"
17 24
18/* ------------------------------------------------------------------------ */ 25/* ------------------------------------------------------------------------ */
19 26
20#define LJLIB_MODULE_bit 27#define LJLIB_MODULE_bit
21 28
22LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT) 29#if LJ_HASFFI
30static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
23{ 31{
32 GCcdata *cd = lj_cdata_new_(L, id, 8);
33 *(uint64_t *)cdataptr(cd) = x;
34 setcdataV(L, L->base-1, cd);
35 return FFH_RES(1);
36}
37#endif
38
39LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit)
40{
41#if LJ_HASFFI
42 CTypeID id = 0;
43 setintV(L->base-1, (int32_t)lj_carith_check64(L, 1, &id));
44 return FFH_RES(1);
45#else
46 lj_lib_checknumber(L, 1);
47 return FFH_RETRY;
48#endif
49}
50
51LJLIB_ASM(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
52{
53#if LJ_HASFFI
54 CTypeID id = 0;
55 uint64_t x = lj_carith_check64(L, 1, &id);
56 return id ? bit_result64(L, id, ~x) : FFH_RETRY;
57#else
58 lj_lib_checknumber(L, 1);
59 return FFH_RETRY;
60#endif
61}
62
63LJLIB_ASM(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
64{
65#if LJ_HASFFI
66 CTypeID id = 0;
67 uint64_t x = lj_carith_check64(L, 1, &id);
68 return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
69#else
24 lj_lib_checknumber(L, 1); 70 lj_lib_checknumber(L, 1);
25 return FFH_RETRY; 71 return FFH_RETRY;
72#endif
26} 73}
27LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
28LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
29 74
30LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL) 75LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
31{ 76{
77#if LJ_HASFFI
78 CTypeID id = 0, id2 = 0;
79 uint64_t x = lj_carith_check64(L, 1, &id);
80 int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
81 if (id) {
82 x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
83 return bit_result64(L, id, x);
84 }
85 if (id2) setintV(L->base+1, sh);
86 return FFH_RETRY;
87#else
32 lj_lib_checknumber(L, 1); 88 lj_lib_checknumber(L, 1);
33 lj_lib_checkbit(L, 2); 89 lj_lib_checkbit(L, 2);
34 return FFH_RETRY; 90 return FFH_RETRY;
91#endif
35} 92}
36LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR) 93LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
37LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR) 94LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
@@ -40,9 +97,29 @@ LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
40 97
41LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND) 98LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
42{ 99{
100#if LJ_HASFFI
101 CTypeID id = 0;
102 TValue *o = L->base, *top = L->top;
103 int i = 0;
104 do { lj_carith_check64(L, ++i, &id); } while (++o < top);
105 if (id) {
106 CTState *cts = ctype_cts(L);
107 CType *ct = ctype_get(cts, id);
108 int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
109 uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
110 o = L->base;
111 do {
112 lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
113 if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
114 } while (++o < top);
115 return bit_result64(L, id, y);
116 }
117 return FFH_RETRY;
118#else
43 int i = 0; 119 int i = 0;
44 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top); 120 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
45 return FFH_RETRY; 121 return FFH_RETRY;
122#endif
46} 123}
47LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR) 124LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
48LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR) 125LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
@@ -51,12 +128,21 @@ LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
51 128
52LJLIB_CF(bit_tohex) 129LJLIB_CF(bit_tohex)
53{ 130{
131#if LJ_HASFFI
132 CTypeID id = 0, id2 = 0;
133 uint64_t b = lj_carith_check64(L, 1, &id);
134 int32_t i, dig = id ? 16 : 8;
135 int32_t n = L->base+1>=L->top ? dig : (int32_t)lj_carith_check64(L, 2, &id2);
136 char buf[16];
137#else
54 uint32_t b = (uint32_t)lj_lib_checkbit(L, 1); 138 uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
55 int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2); 139 int32_t i, dig = 8;
56 const char *hexdigits = "0123456789abcdef"; 140 int32_t n = L->base+1>=L->top ? dig : lj_lib_checkbit(L, 2);
57 char buf[8]; 141 char buf[8];
142#endif
143 const char *hexdigits = "0123456789abcdef";
58 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 144 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
59 if (n > 8) n = 8; 145 if (n > dig) n = dig;
60 for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } 146 for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
61 lua_pushlstring(L, buf, (size_t)n); 147 lua_pushlstring(L, buf, (size_t)n);
62 return 1; 148 return 1;