pike.git / src / bignum.c

version» Context lines:

pike.git/src/bignum.c:7:   #include "global.h"      #include "interpret.h"   #include "program.h"   #include "object.h"   #include "svalue.h"   #include "pike_error.h"      #include "bignum.h"    - #define sp Pike_sp -  - PMOD_EXPORT struct svalue auto_bignum_program = SVALUE_INIT_FREE; -  - PMOD_EXPORT struct program *get_auto_bignum_program(void) - { -  return program_from_svalue(&auto_bignum_program); - } -  - PMOD_EXPORT struct program *get_auto_bignum_program_or_zero(void) - { -  if (TYPEOF(auto_bignum_program) == PIKE_T_FREE) -  return 0; -  return program_from_svalue(&auto_bignum_program); - } -  - void exit_auto_bignum(void) - { -  free_svalue(&auto_bignum_program); -  mark_free_svalue (&auto_bignum_program); - } -  +    PMOD_EXPORT void convert_stack_top_to_bignum(void)   { -  if (TYPEOF(auto_bignum_program) != T_PROGRAM) -  Pike_error("Gmp.mpz conversion failed (Gmp.bignum not loaded).\n"); -  apply_svalue(&auto_bignum_program, 1); +  push_object(clone_object(bignum_program, 1));   }      PMOD_EXPORT void convert_stack_top_with_base_to_bignum(void)   { -  if (TYPEOF(auto_bignum_program) != T_PROGRAM) -  Pike_error("Gmp.mpz conversion failed (Gmp.bignum not loaded).\n"); -  apply_svalue(&auto_bignum_program, 2); +  push_object(clone_object(bignum_program, 2));   }    - int is_bignum_object(struct object *o) - { -  /* Note: -  * This function should *NOT* try to resolv Gmp.mpz unless -  * it is already loaded into memory. -  * /Hubbe -  */ -  -  if (TYPEOF(auto_bignum_program) == T_INT) -  return 0; /* not possible */ -  -  return o->prog == program_from_svalue(&auto_bignum_program); - } -  +    PMOD_EXPORT int is_bignum_object_in_svalue(struct svalue *sv)   {    /* FIXME: object subtype? */    return TYPEOF(*sv) == T_OBJECT && is_bignum_object(sv->u.object);   }      PMOD_EXPORT struct object *make_bignum_object(void)   { -  convert_stack_top_to_bignum(); -  dmalloc_touch_svalue(sp-1); -  return (--sp)->u.object; +  return clone_object(bignum_program, 1);   }      PMOD_EXPORT struct object *bignum_from_svalue(struct svalue *s)   {    push_svalue(s); -  convert_stack_top_to_bignum(); -  dmalloc_touch_svalue(sp-1); -  return (--sp)->u.object; +  return make_bignum_object();   }    - PMOD_EXPORT struct pike_string *string_from_bignum(struct object *o, int base) - { -  push_int(base); -  safe_apply(o, "digits", 1); -  -  if(TYPEOF(sp[-1]) != T_STRING) -  Pike_error("Gmp.mpz string conversion failed.\n"); -  -  dmalloc_touch_svalue(sp-1); -  return (--sp)->u.string; - } -  +    PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s)   {    push_svalue(s);    convert_stack_top_to_bignum();    free_svalue(s); -  *s=sp[-1]; -  sp--; -  dmalloc_touch_svalue(sp); +  *s=Pike_sp[-1]; +  Pike_sp--; +  dmalloc_touch_svalue(Pike_sp);   }    - #ifdef INT64 - static void bootstrap_push_int64 (INT64 i) + PMOD_EXPORT int low_compare_bignums(MP_INT *a, MP_INT *b)   { -  if(i == DO_NOT_WARN((INT_TYPE)i)) -  { -  push_int(DO_NOT_WARN((INT_TYPE)i)); +  return mpz_cmp(a, b);   } -  else -  Pike_fatal ("Failed to convert large integer (Gmp.bignum not loaded).\n"); - } +     - PMOD_EXPORT void (*push_int64) (INT64) = bootstrap_push_int64; - PMOD_EXPORT int (*int64_from_bignum) (INT64 *, struct object *) = NULL; - PMOD_EXPORT void (*reduce_stack_top_bignum) (void) = NULL; - #endif -  - PMOD_EXPORT void (*push_ulongest) (unsigned LONGEST) = NULL; - PMOD_EXPORT int (*ulongest_from_bignum) (unsigned LONGEST *, -  struct object *) = NULL; -  - PMOD_EXPORT int (*mpz_from_svalue)(MP_INT *, struct svalue *) = NULL; - PMOD_EXPORT void (*push_bignum)(MP_INT *) = NULL; -  - PMOD_EXPORT void hook_in_gmp_funcs ( - #ifdef INT64 -  void (*push_int64_val)(INT64), -  int (*int64_from_bignum_val) (INT64 *, struct object *), -  void (*reduce_stack_top_bignum_val) (void), - #endif -  void (*push_ulongest_val) (unsigned LONGEST), -  int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *), -  int (*mpz_from_svalue_val)(MP_INT *, struct svalue *), -  void (*push_bignum_val)(MP_INT *)) + PMOD_EXPORT int compare_bignums(struct object *a, struct object *b)   { -  /* Assigning the pointers above directly from the Gmp module doesn't -  * work in some cases, e.g. NT. */ - #ifdef INT64 -  push_int64 = push_int64_val ? push_int64_val : bootstrap_push_int64; -  int64_from_bignum = int64_from_bignum_val; -  reduce_stack_top_bignum = reduce_stack_top_bignum_val; - #endif -  push_ulongest = push_ulongest_val; -  ulongest_from_bignum = ulongest_from_bignum_val; -  mpz_from_svalue = mpz_from_svalue_val; -  push_bignum = push_bignum_val; +  if (!is_bignum_object(a)) Pike_error("First object is not a bignum.\n"); +  if (!is_bignum_object(b)) Pike_error("Second object is not a bignum.\n"); +  return low_compare_bignums((MP_INT *)a->storage, (MP_INT *)b->storage);   }