e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
fda0de1999-10-08Fredrik Noring #ifndef BIGNUM_H #define BIGNUM_H
4278902014-10-29Per Hedbor #ifdef __cplusplus extern "C++" { #endif
2c4f4c2014-10-22Per Hedbor #include <gmp.h>
4278902014-10-29Per Hedbor #ifdef __cplusplus }; #endif
6df8332013-06-13Martin Nilsson #include "global.h"
ff0d461999-10-15Fredrik Noring /* Note: These functions assume some properties of the CPU. */
fda0de1999-10-08Fredrik Noring 
ff0d461999-10-15Fredrik Noring #define INT_TYPE_SIGN(x) ((x) < 0)
fda0de1999-10-08Fredrik Noring 
0d80be2012-12-31Arne Goedeke /*
0dfcb62015-01-20Martin Nilsson  * Arithmetic operations which try to be standard compliant when * checking for overflow. The first set of functions uses a second * larger integer type to perform computations. The second uses manual * multiplication for unsigned multiply or checks for overflow as * recommended in
0d80be2012-12-31Arne Goedeke  * https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
0dfcb62015-01-20Martin Nilsson  * * When using clang with builtin support for checking arithmetic * overflow, those builtins will be used. These functions will also * detect and try to avoid undefined behavior, e.g. shifts of
fe62692014-01-11Arne Goedeke  * negative integers.
80e6772014-03-08Arne Goedeke  *
0dfcb62015-01-20Martin Nilsson  * The family of DO_*_OVERFLOW functions sets the result only if no * overflow occured.
0d80be2012-12-31Arne Goedeke  */
fe62692014-01-11Arne Goedeke #define GENERIC_OVERFLOW_CHECKS(type) \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_## type ## _NEG_OVERFLOW(type a, type * res) { \
fe62692014-01-11Arne Goedeke  if (a == MIN_ ## type) return 1; \ *res = -a; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _NEG_OVERFLOW(type a) { \
fe62692014-01-11Arne Goedeke  return a == MIN_ ## type; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _DIV_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  return a == MIN_ ## type && b == -1; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _DIV_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if (a == MIN_ ## type && b == -1) return 1; \ *res = a/b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE U ## type ## _MUL_OVERFLOW(unsigned type a, unsigned type b) { \
fe62692014-01-11Arne Goedeke  unsigned type res; \ return DO_U ## type ## _MUL_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE U ## type ## _ADD_OVERFLOW(unsigned type a, unsigned type b) { \
fe62692014-01-11Arne Goedeke  unsigned type res; \ return DO_U ## type ## _ADD_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE U ## type ## _SUB_OVERFLOW(unsigned type a, unsigned type b) { \
fe62692014-01-11Arne Goedeke  unsigned type res; \ return DO_U ## type ## _SUB_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _MUL_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  type res; \ return DO_ ## type ## _MUL_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _ADD_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  type res; \ return DO_ ## type ## _ADD_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _SUB_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  type res; \ return DO_ ## type ## _SUB_OVERFLOW(a, b, &res); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _MOD_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  return type ## _DIV_OVERFLOW(a, b); \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _MOD_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if (type ## _MOD_OVERFLOW(a, b)) { \ return 1; \ } \ *res = a % b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE type ## _LSH_OVERFLOW(type a, type b) { \
fe62692014-01-11Arne Goedeke  type size = (type)sizeof(type)*CHAR_BIT; \
0653372014-08-31Per Hedbor  return (b < 0 || b >= size || ((a<<b)>>b)!=a); \
fe62692014-01-11Arne Goedeke } \
01b9212016-01-12Per Hedbor  static inline int PIKE_UNUSED_ATTRIBUTE type ## _RSH_OVERFLOW(type UNUSED(a), type b) { \
0bc5672014-08-17Per Hedbor  return b>=(type)sizeof(type)*CHAR_BIT; \
fe62692014-01-11Arne Goedeke } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _LSH_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if (type ## _LSH_OVERFLOW(a, b)) return 1; \ *res = a << b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _RSH_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if (type ## _RSH_OVERFLOW(a, b)) return 1; \ *res = a >> b; \ return 0; \
0d80be2012-12-31Arne Goedeke }
fda0de1999-10-08Fredrik Noring 
fe62692014-01-11Arne Goedeke #define _GEN_OF2(type, type2, utype2, size) \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _ADD_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  type2 tmp; \ tmp = (type2)a + (type2)b; \ if (tmp < MIN_ ## type || tmp > MAX_ ## type) \ return 1; \ *res = (type)tmp; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _SUB_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  type2 tmp; \ tmp = (type2)a - (type2)b; \ if (tmp < MIN_ ## type || tmp > MAX_ ## type) \ return 1; \ *res = (type)tmp; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _MUL_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  type2 tmp; \ tmp = (type2)a * (type2)b; \ if (tmp < MIN_ ## type || tmp > MAX_ ## type) \ return 1; \ *res = (type)tmp; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_U ## type ## _ADD_OVERFLOW(unsigned type a, unsigned type b, \
fe62692014-01-11Arne Goedeke  unsigned type * res) { \ utype2 tmp; \ tmp = (utype2)a + (utype2)b; \ if (tmp >> size) return 1; \ *res = (unsigned type)tmp; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_U ## type ## _MUL_OVERFLOW(unsigned type a, unsigned type b, \
fe62692014-01-11Arne Goedeke  unsigned type * res) { \ utype2 tmp; \ tmp = (utype2)a * (utype2)b; \ if (tmp >> size) return 1; \ *res = (unsigned type)tmp; \ return 0; \
67d4a62012-12-30Jonas Walldén }
fe62692014-01-11Arne Goedeke #define _GEN_OF1(type, size) \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _ADD_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if ((b > 0 && a > MAX_ ## type - b) || \ (b < 0 && a < MIN_ ## type - b)) \ return 1; \ *res = a + b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## type ## _SUB_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if ((b > 0 && a < MIN_ ## type + b) || \ (b < 0 && a > MAX_ ## type + b)) \ return 1; \ *res = a - b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_## type ## _MUL_OVERFLOW(type a, type b, type * res) { \
fe62692014-01-11Arne Goedeke  if (a > 0) { \ if (b > 0) { \ if (a > (MAX_ ## type / b)) { \ return 1; \ } \ } else { \ if (b < (MIN_ ## type / a)) { \ return 1; \ } \ } \ } else { \ if (b > 0) { \ if (a < (MAX_ ## type / b)) { \ return 1; \ } \ } else { \ if ( (a != 0) && (b < (MAX_ ## type / a))) { \ return 1; \ } \ } \ } \ *res = a * b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_U ## type ## _ADD_OVERFLOW(unsigned type a, unsigned type b, \
fe62692014-01-11Arne Goedeke  unsigned type * res) { \ if (a > MAX_U ## type - b) \ return 1; \ *res = a + b; \ return 0; \ } \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_U ## type ## _MUL_OVERFLOW(unsigned type a, unsigned type b, \
fe62692014-01-11Arne Goedeke  unsigned type * res) { \ unsigned type tmp = 0; \ unsigned type bits = size/2; \ unsigned type low_mask = ((1 << bits)-1); \ unsigned type a1 = a >> bits; \ unsigned type b1 = b >> bits; \ unsigned type a0 = a & low_mask; \ unsigned type b0 = b & low_mask; \ tmp = a1 * b1; \ a1 *= b0; \ b1 *= a0; \ if (tmp || (a1|b1) & ~low_mask) return 1; \ tmp = a1<<bits; \ if (DO_U ## type ## _ADD_OVERFLOW(tmp, b1<<bits, &tmp) \ || DO_U ## type ## _ADD_OVERFLOW(tmp, a0*b0, &tmp)) return 1; \ *res = tmp; \ return 0; \ } \
67d4a62012-12-30Jonas Walldén 
e8b5f32014-01-14Tobias S. Josefowitz #define GEN_USUB_OF(type) \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE DO_U ## type ## _SUB_OVERFLOW(unsigned type a, unsigned type b, \
e8b5f32014-01-14Tobias S. Josefowitz  unsigned type * res) { \ if (b > a) \ return 1; \ *res = a - b; \ return 0; \ } \
ed4c9b2013-01-01Jonas Walldén #define GEN_OF1(size) \
e8b5f32014-01-14Tobias S. Josefowitz  GEN_USUB_OF(INT ## size) \
ed4c9b2013-01-01Jonas Walldén  _GEN_OF1(INT ## size, size) \
fe62692014-01-11Arne Goedeke  GENERIC_OVERFLOW_CHECKS(INT ## size)
bafc382014-05-02Arne Goedeke #define GEN_OF2(s1, s2, utype2) \
e8b5f32014-01-14Tobias S. Josefowitz  GEN_USUB_OF(INT ## s1) \
bafc382014-05-02Arne Goedeke  _GEN_OF2(INT ## s1, INT ## s2, utype2, s1) \
fe62692014-01-11Arne Goedeke  GENERIC_OVERFLOW_CHECKS(INT ## s1)
0d80be2012-12-31Arne Goedeke 
66fb9b2015-12-15Arne Goedeke #if PIKE_CLANG_BUILTIN(__builtin_uadd_overflow) || __GNUC__ >= 5
bafc382014-05-02Arne Goedeke #define DO_CLANG_OF(name, type, builtin) \
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE name(type a, type b, type * res) { \
bafc382014-05-02Arne Goedeke  type tmp; \ if (builtin(a, b, &tmp)) return 1; \ *res = tmp; \ return 0; \ } DO_CLANG_OF(DO_INT32_ADD_OVERFLOW, INT32, __builtin_sadd_overflow) DO_CLANG_OF(DO_INT32_SUB_OVERFLOW, INT32, __builtin_ssub_overflow) DO_CLANG_OF(DO_INT32_MUL_OVERFLOW, INT32, __builtin_smul_overflow) DO_CLANG_OF(DO_UINT32_ADD_OVERFLOW, unsigned INT32, __builtin_uadd_overflow) DO_CLANG_OF(DO_UINT32_SUB_OVERFLOW, unsigned INT32, __builtin_usub_overflow) DO_CLANG_OF(DO_UINT32_MUL_OVERFLOW, unsigned INT32, __builtin_umul_overflow) GENERIC_OVERFLOW_CHECKS(INT32) # if SIZEOF_LONG == 8 DO_CLANG_OF(DO_INT64_ADD_OVERFLOW, INT64, __builtin_saddl_overflow) DO_CLANG_OF(DO_INT64_SUB_OVERFLOW, INT64, __builtin_ssubl_overflow) DO_CLANG_OF(DO_INT64_MUL_OVERFLOW, INT64, __builtin_smull_overflow) DO_CLANG_OF(DO_UINT64_ADD_OVERFLOW, UINT64, __builtin_uaddl_overflow) DO_CLANG_OF(DO_UINT64_SUB_OVERFLOW, UINT64, __builtin_usubl_overflow) DO_CLANG_OF(DO_UINT64_MUL_OVERFLOW, UINT64, __builtin_umull_overflow) # elif SIZEOF_LONG_LONG == 8 DO_CLANG_OF(DO_INT64_ADD_OVERFLOW, INT64, __builtin_saddll_overflow) DO_CLANG_OF(DO_INT64_SUB_OVERFLOW, INT64, __builtin_ssubll_overflow) DO_CLANG_OF(DO_INT64_MUL_OVERFLOW, INT64, __builtin_smulll_overflow) DO_CLANG_OF(DO_UINT64_ADD_OVERFLOW, UINT64, __builtin_uaddll_overflow) DO_CLANG_OF(DO_UINT64_SUB_OVERFLOW, UINT64, __builtin_usubll_overflow) DO_CLANG_OF(DO_UINT64_MUL_OVERFLOW, UINT64, __builtin_umulll_overflow) #endif GENERIC_OVERFLOW_CHECKS(INT64) #else /* PIKE_CLANG_BUILTIN(__builtin_uadd_overflow) */
ed4c9b2013-01-01Jonas Walldén #if defined(INT128) && defined(UINT128)
bafc382014-05-02Arne Goedeke GEN_OF2(64, 128, UINT128) GEN_OF2(32, 64, UINT64)
34bdd42016-02-12Henrik Grubbström (Grubba) #else
0d80be2012-12-31Arne Goedeke GEN_OF1(64)
bafc382014-05-02Arne Goedeke GEN_OF2(32, 64, UINT64)
0d80be2012-12-31Arne Goedeke #endif
fda0de1999-10-08Fredrik Noring 
bafc382014-05-02Arne Goedeke #endif /* PIKE_CLANG_BUILTIN(__builtin_uadd_overflow) */ GEN_OF2(16, 32, unsigned INT32)
302a322014-08-22Per Hedbor /*GEN_OF2(8, 32, unsigned INT32) */
fe62692014-01-11Arne Goedeke 
0819ee2014-03-13Henrik Grubbström (Grubba) /* NB: GCC 4.1.2 doesn't alias pointers to INT_TYPE and to INT32/INT64, * so the DO_INT_TYPE_*_OVERFLOW variants can't just be cpp-renames * to the corresponding INT32/INT64 variant, as the stores to the * target variable may get lost. We fix this by having variables * of the correct type as temporaries, and then copying the result. */
6809cd2014-03-20Henrik Grubbström (Grubba) #define _GEN_UNOP(OP, type1, TYPE1, type2, name) \
01b9212016-01-12Per Hedbor  static inline int PIKE_UNUSED_ATTRIBUTE name ## _ ## OP ## _OVERFLOW(type2 a) { \
1600422014-03-15Arne Goedeke  type1 tmp; \
6809cd2014-03-20Henrik Grubbström (Grubba)  return (DO_## TYPE1 ## _ ## OP ## _OVERFLOW(a, &tmp)); \
0819ee2014-03-13Henrik Grubbström (Grubba)  } \
01b9212016-01-12Per Hedbor  static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## name ## _ ## OP ## _OVERFLOW(type2 a, \
1600422014-03-15Arne Goedeke  type2 *res) { \ type1 tmp; \
6809cd2014-03-20Henrik Grubbström (Grubba)  if (DO_ ## TYPE1 ## _ ## OP ## _OVERFLOW(a, &tmp)) return 1; \
0819ee2014-03-13Henrik Grubbström (Grubba)  *res = tmp; \ return 0; \ }
6809cd2014-03-20Henrik Grubbström (Grubba) #define _GEN_BINOP(OP, type1, TYPE1, type2, name) \
01b9212016-01-12Per Hedbor  static inline int PIKE_UNUSED_ATTRIBUTE name ## _ ## OP ## _OVERFLOW(type2 a, type2 b) { \
1600422014-03-15Arne Goedeke  type1 tmp; \
6809cd2014-03-20Henrik Grubbström (Grubba)  return (DO_ ## TYPE1 ## _ ## OP ## _OVERFLOW(a, b, &tmp)); \
0819ee2014-03-13Henrik Grubbström (Grubba)  } \
01b9212016-01-12Per Hedbor  static inline int PIKE_UNUSED_ATTRIBUTE DO_ ## name ## _ ## OP ## _OVERFLOW(type2 a, \
1600422014-03-15Arne Goedeke  type2 b, \ type2 *res) { \ type1 tmp; \
6809cd2014-03-20Henrik Grubbström (Grubba)  if (DO_ ## TYPE1 ## _ ## OP ## _OVERFLOW(a, b, &tmp)) return 1; \
0819ee2014-03-13Henrik Grubbström (Grubba)  *res = tmp; \ return 0; \ }
1600422014-03-15Arne Goedeke 
6809cd2014-03-20Henrik Grubbström (Grubba) #define GEN_INT_TYPE(size) \ _GEN_UNOP(NEG, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(MUL, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(ADD, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(SUB, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(DIV, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(MOD, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(LSH, INT ## size, INT ## size, INT_TYPE, INT_TYPE) \ _GEN_BINOP(RSH, INT ## size, INT ## size, INT_TYPE, INT_TYPE)
1600422014-03-15Arne Goedeke 
0d80be2012-12-31Arne Goedeke #if SIZEOF_INT_TYPE == 8
0819ee2014-03-13Henrik Grubbström (Grubba) GEN_INT_TYPE(64)
0d80be2012-12-31Arne Goedeke #elif SIZEOF_INT_TYPE == 4
0819ee2014-03-13Henrik Grubbström (Grubba) GEN_INT_TYPE(32)
0d80be2012-12-31Arne Goedeke #endif
fda0de1999-10-08Fredrik Noring 
1600422014-03-15Arne Goedeke /* let's assume that sizeof(char*) == sizeof(size_t) */ #if SIZEOF_CHAR_P == 8
6809cd2014-03-20Henrik Grubbström (Grubba) _GEN_BINOP(ADD, UINT64, UINT64, size_t, SIZE_T) _GEN_BINOP(SUB, UINT64, UINT64, size_t, SIZE_T)
ce36de2014-03-20Henrik Grubbström (Grubba) _GEN_BINOP(MUL, UINT64, UINT64, size_t, SIZE_T)
1600422014-03-15Arne Goedeke #elif SIZEOF_CHAR_P == 4
6809cd2014-03-20Henrik Grubbström (Grubba) _GEN_BINOP(ADD, unsigned INT32, UINT32, size_t, SIZE_T) _GEN_BINOP(SUB, unsigned INT32, UINT32, size_t, SIZE_T) _GEN_BINOP(MUL, unsigned INT32, UINT32, size_t, SIZE_T)
1600422014-03-15Arne Goedeke #endif
e37a3e1999-10-09Fredrik Hübinette (Hubbe) /* Prototypes begin here */
07bb4a2014-10-29Martin Nilsson PMOD_EXPORT extern struct program *bignum_program;
9b8caa2006-05-29Martin Stjernholm PMOD_EXPORT void convert_stack_top_to_bignum(void); PMOD_EXPORT void convert_stack_top_with_base_to_bignum(void);
8852cb1999-10-25Fredrik Hübinette (Hubbe) int is_bignum_object(struct object *o);
9b8caa2006-05-29Martin Stjernholm PMOD_EXPORT int is_bignum_object_in_svalue(struct svalue *sv); PMOD_EXPORT struct object *make_bignum_object(void); PMOD_EXPORT struct object *bignum_from_svalue(struct svalue *s);
51f3702015-08-06Per Hedbor PMOD_EXPORT struct object *create_double_bignum(INT_TYPE low, INT_TYPE high);
9b8caa2006-05-29Martin Stjernholm PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s);
15a8282017-05-08Henrik Grubbström (Grubba) PMOD_EXPORT int low_compare_bignums(MP_INT *a, MP_INT *b); PMOD_EXPORT int compare_bignums(struct object *a, struct object *b);
856cff1999-10-29Fredrik Noring 
2355e32014-10-29Martin Nilsson PMOD_EXPORT void push_int64(INT64 i);
0a3c552016-05-09Martin Nilsson PMOD_EXPORT void push_ulongest(UINT64 i);
bf3f1e2018-03-21Tobias S. Josefowitz PMOD_EXPORT void ulongest_to_svalue_no_free(struct svalue *sv, UINT64 i);
56ff1a2008-05-01Martin Stjernholm 
f43e352016-06-11Henrik Grubbström (Grubba) /* Returns low 64 bits and nonzero if bignum. */ PMOD_EXPORT int low_int64_from_bignum(INT64 *i, struct object *bignum);
56ff1a2008-05-01Martin Stjernholm /* Returns nonzero iff conversion is successful. */
2355e32014-10-29Martin Nilsson PMOD_EXPORT int int64_from_bignum(INT64 *i, struct object *bignum);
56ff1a2008-05-01Martin Stjernholm 
2355e32014-10-29Martin Nilsson PMOD_EXPORT void reduce_stack_top_bignum(void);
dccaa22008-05-01Martin Stjernholm 
65068f2014-10-29Martin Nilsson #define is_bignum_object(O) ((O)->prog == bignum_program)
2355e32014-10-29Martin Nilsson PMOD_EXPORT int mpz_from_svalue(MP_INT *, struct svalue *); PMOD_EXPORT void push_bignum(MP_INT *);
fda0de1999-10-08Fredrik Noring 
082ad22014-10-29Martin Nilsson /* Deprecated */
95d4b22014-10-29Martin Nilsson #define get_auto_bignum_program_or_zero() bignum_program #define get_auto_bignum_program() bignum_program
7960be2014-10-30Martin Nilsson #define AUTO_BIGNUM 1
082ad22014-10-29Martin Nilsson 
e37a3e1999-10-09Fredrik Hübinette (Hubbe) #endif /* BIGNUM_H */