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 #include "global.h" #ifdef AUTO_BIGNUM #include "interpret.h" #include "program.h" #include "object.h" #include "svalue.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
fda0de1999-10-08Fredrik Noring 
6ad2372002-05-11Martin Nilsson #define sp Pike_sp
8133372008-05-30Martin Stjernholm PMOD_EXPORT struct svalue auto_bignum_program = SVALUE_INIT_FREE;
e37a3e1999-10-09Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct program *get_auto_bignum_program(void)
8852cb1999-10-25Fredrik Hübinette (Hubbe) { return program_from_function(&auto_bignum_program); }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct program *get_auto_bignum_program_or_zero(void)
8852cb1999-10-25Fredrik Hübinette (Hubbe) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(auto_bignum_program) == PIKE_T_FREE)
91487e2003-01-11Martin Stjernholm  return 0;
8852cb1999-10-25Fredrik Hübinette (Hubbe)  return program_from_function(&auto_bignum_program); }
e37a3e1999-10-09Fredrik Hübinette (Hubbe) void exit_auto_bignum(void) { free_svalue(&auto_bignum_program);
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&auto_bignum_program);
fda0de1999-10-08Fredrik Noring }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void convert_stack_top_to_bignum(void)
e37a3e1999-10-09Fredrik Hübinette (Hubbe) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(auto_bignum_program) != T_PROGRAM)
8837942008-07-28Martin Stjernholm  Pike_error("Gmp.mpz conversion failed (Gmp.bignum not loaded).\n");
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  apply_svalue(&auto_bignum_program, 1); }
fda0de1999-10-08Fredrik Noring 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void convert_stack_top_with_base_to_bignum(void)
31ea271999-10-22Fredrik Noring {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(auto_bignum_program) != T_PROGRAM)
8837942008-07-28Martin Stjernholm  Pike_error("Gmp.mpz conversion failed (Gmp.bignum not loaded).\n");
31ea271999-10-22Fredrik Noring  apply_svalue(&auto_bignum_program, 2); }
39ac731999-10-20Fredrik Noring int is_bignum_object(struct object *o) {
e28b471999-10-25Fredrik Hübinette (Hubbe)  /* Note: * This function should *NOT* try to resolv Gmp.mpz unless * it is already loaded into memory. * /Hubbe */
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(auto_bignum_program) == T_INT)
3905cf1999-11-11Fredrik Hübinette (Hubbe)  return 0; /* not possible */
e28b471999-10-25Fredrik Hübinette (Hubbe) 
1c1c5e2001-04-08Fredrik Hübinette (Hubbe)  return o->prog == program_from_svalue(&auto_bignum_program);
39ac731999-10-20Fredrik Noring }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int is_bignum_object_in_svalue(struct svalue *sv)
39ac731999-10-20Fredrik Noring {
6b304c2004-12-30Henrik Grubbström (Grubba)  /* FIXME: object subtype? */
017b572011-10-28Henrik Grubbström (Grubba)  return TYPEOF(*sv) == T_OBJECT && is_bignum_object(sv->u.object);
39ac731999-10-20Fredrik Noring }
e37a3e1999-10-09Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct object *make_bignum_object(void)
fda0de1999-10-08Fredrik Noring {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  convert_stack_top_to_bignum();
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp-1);
39ac731999-10-20Fredrik Noring  return (--sp)->u.object;
e37a3e1999-10-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct object *bignum_from_svalue(struct svalue *s)
e37a3e1999-10-09Fredrik Hübinette (Hubbe) { push_svalue(s); convert_stack_top_to_bignum();
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp-1);
39ac731999-10-20Fredrik Noring  return (--sp)->u.object;
fda0de1999-10-08Fredrik Noring }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct pike_string *string_from_bignum(struct object *o, int base)
ff0d461999-10-15Fredrik Noring { push_int(base); safe_apply(o, "digits", 1);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(sp[-1]) != T_STRING)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Gmp.mpz string conversion failed.\n");
ff0d461999-10-15Fredrik Noring 
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp-1);
ff0d461999-10-15Fredrik Noring  return (--sp)->u.string; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s)
fda0de1999-10-08Fredrik Noring {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  push_svalue(s); convert_stack_top_to_bignum(); free_svalue(s); *s=sp[-1];
fda0de1999-10-08Fredrik Noring  sp--;
e801bb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
fda0de1999-10-08Fredrik Noring }
bd35ec1999-10-30Fredrik Noring #ifdef INT64
0b926d2003-04-02Martin Stjernholm static void bootstrap_push_int64 (INT64 i)
2fe5651999-10-29Fredrik Noring {
0a5d062000-08-08Henrik Grubbström (Grubba)  if(i == DO_NOT_WARN((INT_TYPE)i))
2fe5651999-10-29Fredrik Noring  {
0a5d062000-08-08Henrik Grubbström (Grubba)  push_int(DO_NOT_WARN((INT_TYPE)i));
2fe5651999-10-29Fredrik Noring  } else
f6a5c62003-04-02Martin Stjernholm  Pike_fatal ("Failed to convert large integer (Gmp.bignum not loaded).\n");
2fe5651999-10-29Fredrik Noring }
956e5e2003-03-28Martin Stjernholm PMOD_EXPORT void (*push_int64) (INT64) = bootstrap_push_int64; PMOD_EXPORT int (*int64_from_bignum) (INT64 *, struct object *) = NULL;
00cf022003-11-15Martin Stjernholm PMOD_EXPORT void (*reduce_stack_top_bignum) (void) = NULL;
dccaa22008-05-01Martin Stjernholm #endif PMOD_EXPORT void (*push_ulongest) (unsigned LONGEST) = NULL; PMOD_EXPORT int (*ulongest_from_bignum) (unsigned LONGEST *, struct object *) = NULL;
f6a5c62003-04-02Martin Stjernholm 
dccaa22008-05-01Martin Stjernholm PMOD_EXPORT void hook_in_gmp_funcs ( #ifdef INT64
f6a5c62003-04-02Martin Stjernholm  void (*push_int64_val)(INT64),
00cf022003-11-15Martin Stjernholm  int (*int64_from_bignum_val) (INT64 *, struct object *),
dccaa22008-05-01Martin Stjernholm  void (*reduce_stack_top_bignum_val) (void), #endif void (*push_ulongest_val) (unsigned LONGEST), int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *))
f6a5c62003-04-02Martin Stjernholm { /* Assigning the pointers above directly from the Gmp module doesn't * work in some cases, e.g. NT. */
dccaa22008-05-01Martin Stjernholm #ifdef INT64
f6a5c62003-04-02Martin Stjernholm  push_int64 = push_int64_val ? push_int64_val : bootstrap_push_int64; int64_from_bignum = int64_from_bignum_val;
00cf022003-11-15Martin Stjernholm  reduce_stack_top_bignum = reduce_stack_top_bignum_val;
956e5e2003-03-28Martin Stjernholm #endif
dccaa22008-05-01Martin Stjernholm  push_ulongest = push_ulongest_val; ulongest_from_bignum = ulongest_from_bignum_val; }
2fe5651999-10-29Fredrik Noring 
fda0de1999-10-08Fredrik Noring #endif /* AUTO_BIGNUM */