mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'bigint-embed' of https://github.com/dearblue/mruby into bigint-embed
This commit is contained in:
+476
-335
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,8 @@ typedef int64_t mp_dbl_limb_signed;
|
||||
#define MPZ_DIG_SIZE 32
|
||||
#endif
|
||||
|
||||
#define RBIGINT_EMBED_SIZE_MAX ((sizeof(void*) * 3) / sizeof(mp_limb))
|
||||
|
||||
typedef struct _mpz_t {
|
||||
mp_limb *p;
|
||||
short sn;
|
||||
@@ -54,10 +56,82 @@ typedef struct _mpz_t {
|
||||
|
||||
struct RBigint {
|
||||
MRB_OBJECT_HEADER;
|
||||
mpz_t mp;
|
||||
union {
|
||||
mpz_t heap;
|
||||
mp_limb ary[RBIGINT_EMBED_SIZE_MAX];
|
||||
} as;
|
||||
};
|
||||
#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v))
|
||||
|
||||
/*
|
||||
* flags of struct RBigint
|
||||
*
|
||||
* 6..: UNUSED
|
||||
* 4..5: sign flags
|
||||
* 00: negative (<--> -1)
|
||||
* 01: zero (<--> 0)
|
||||
* 10: positive (<--> +1)
|
||||
* 11: UNUSED
|
||||
* 0..3: size of embedded array; 15 means used with heap
|
||||
*/
|
||||
|
||||
#define RBIGINT_EMBED_SIZE_MASK 0x0f
|
||||
#define RBIGINT_EMBED_SIZE_OVER RBIGINT_EMBED_SIZE_MASK
|
||||
#define RBIGINT_EMBED_SIZE_SHIFT 0
|
||||
#define RBIGINT_EMBED_SIGN_MASK 0x03
|
||||
#define RBIGINT_EMBED_SIGN_SHIFT 4
|
||||
|
||||
#define RBIGINT_ARY(m) (RBIGINT_EMBED_P(m) ? RBIGINT_EMBED_ARY(m) : RBIGINT_HEAP_ARY(m))
|
||||
#define RBIGINT_SIGN(m) (RBIGINT_EMBED_P(m) ? RBIGINT_EMBED_SIGN(m) : RBIGINT_HEAP_SIGN(m))
|
||||
#define RBIGINT_SIZE(m) (RBIGINT_EMBED_P(m) ? RBIGINT_EMBED_SIZE(m) : RBIGINT_HEAP_SIZE(m))
|
||||
#define RBIGINT_SET_SIGN(m, s) do { \
|
||||
if (RBIGINT_EMBED_P(m)) { \
|
||||
RBIGINT_SET_EMBED_SIGN(m, s); \
|
||||
} \
|
||||
else { \
|
||||
RBIGINT_SET_HEAP_SIGN(m, s); \
|
||||
} \
|
||||
} while (0)
|
||||
#define RBIGINT_SET_SIZE(m, s) do { \
|
||||
if (RBIGINT_EMBED_P(m)) { \
|
||||
RBIGINT_SET_EMBED_SIZE(m, s); \
|
||||
} \
|
||||
else { \
|
||||
RBIGINT_SET_HEAP_SIZE(m, s); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RBIGINT_HEAP_ARY(m) ((m)->as.heap.p)
|
||||
#define RBIGINT_HEAP_SIGN(m) ((m)->as.heap.sn)
|
||||
#define RBIGINT_HEAP_SIZE(m) ((m)->as.heap.sz)
|
||||
#define RBIGINT_SET_HEAP(m) do { \
|
||||
(m)->flags |= RBIGINT_EMBED_SIZE_OVER << RBIGINT_EMBED_SIZE_SHIFT; \
|
||||
} while (0)
|
||||
#define RBIGINT_SET_HEAP_SIGN(m, s) do { \
|
||||
(m)->as.heap.sn = (s); \
|
||||
} while (0)
|
||||
#define RBIGINT_SET_HEAP_SIZE(m, s) do { \
|
||||
(m)->as.heap.sz = (s); \
|
||||
} while (0)
|
||||
|
||||
#define RBIGINT_EMBED_P(m) ((((m)->flags >> RBIGINT_EMBED_SIZE_SHIFT) & RBIGINT_EMBED_SIZE_MASK) < RBIGINT_EMBED_SIZE_OVER)
|
||||
#define RBIGINT_EMBED_ARY(m) ((m)->as.ary)
|
||||
#define RBIGINT_EMBED_SIGN(m) ((short)(((m)->flags >> RBIGINT_EMBED_SIGN_SHIFT) & RBIGINT_EMBED_SIGN_MASK) - 1)
|
||||
#define RBIGINT_EMBED_SIZE(m) (size_t)(((m)->flags >> RBIGINT_EMBED_SIZE_SHIFT) & RBIGINT_EMBED_SIZE_MASK)
|
||||
#define RBIGINT_SET_EMBED_ZERO(m) do { \
|
||||
(m)->flags &= ~(RBIGINT_EMBED_SIZE_MASK << RBIGINT_EMBED_SIZE_SHIFT); \
|
||||
} while (0)
|
||||
#define RBIGINT_SET_EMBED_SIGN(m, s) do { \
|
||||
(m)->flags = ((((s) + 1) & RBIGINT_EMBED_SIGN_MASK) << RBIGINT_EMBED_SIGN_SHIFT) | \
|
||||
((m)->flags & ~(RBIGINT_EMBED_SIGN_MASK << RBIGINT_EMBED_SIGN_SHIFT)); \
|
||||
} while (0)
|
||||
#define RBIGINT_SET_EMBED_SIZE(m, s) do { \
|
||||
size_t s_tmp = (s); \
|
||||
mrb_assert((s_tmp) <= RBIGINT_EMBED_SIZE_MAX); \
|
||||
RBIGINT_SET_EMBED_ZERO(m); \
|
||||
(m)->flags |= (s_tmp) << RBIGINT_EMBED_SIZE_SHIFT; \
|
||||
} while (0)
|
||||
|
||||
mrb_static_assert_object_size(struct RBigint);
|
||||
|
||||
#endif /* MRUBY_BIGINT_H */
|
||||
|
||||
Reference in New Issue
Block a user