Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • 9.0
  • 8.0
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • nt-tools
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
  • v8.0.1982
  • v8.0.1980
  • v8.0.1978
  • v8.0.1976
  • v8.0.1974
  • v8.0.1972
  • v8.0.1970
  • v8.0.1968
  • v8.0.1966
  • v8.0.1964
  • v8.0.1962
40 results

bignum.c

Blame
  • bignum.c 3.73 KiB
    /*
    || 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.
    */
    
    #include "global.h"
    
    #include "interpret.h"
    #include "program.h"
    #include "object.h"
    #include "svalue.h"
    #include "pike_error.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_function(&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_function(&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);
    }
    
    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);
    }
    
    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;
    }
    
    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;
    }
    
    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);
    }
    
    #ifdef INT64
    static void bootstrap_push_int64 (INT64 i)
    {
      if(i == DO_NOT_WARN((INT_TYPE)i))
      {
        push_int(DO_NOT_WARN((INT_TYPE)i));
      }
      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 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 *))
    {
      /* 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;
    }