e576bb | 2002-10-11 | Martin Nilsson | | |
c84bd1 | 2003-01-13 | Henrik Grubbström (Grubba) | | || $Id: bignum.c,v 1.29 2003/01/13 14:42:06 grubba Exp $
|
e576bb | 2002-10-11 | Martin Nilsson | | */
|
1b10db | 2002-10-08 | Martin Nilsson | |
|
fda0de | 1999-10-08 | Fredrik Noring | | #include "global.h"
#ifdef AUTO_BIGNUM
#include "interpret.h"
#include "program.h"
#include "object.h"
#include "svalue.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
fda0de | 1999-10-08 | Fredrik Noring | |
|
6ad237 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
c84bd1 | 2003-01-13 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct svalue auto_bignum_program = {
|
2fbeae | 2001-07-01 | Martin Stjernholm | | T_INT, 0,
#ifdef HAVE_UNION_INIT
{0},
#endif
};
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct program *get_auto_bignum_program(void)
|
8852cb | 1999-10-25 | Fredrik Hübinette (Hubbe) | | {
return program_from_function(&auto_bignum_program);
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct program *get_auto_bignum_program_or_zero(void)
|
8852cb | 1999-10-25 | Fredrik Hübinette (Hubbe) | | {
|
91487e | 2003-01-11 | Martin Stjernholm | | if (auto_bignum_program.type == T_INT)
return 0;
|
8852cb | 1999-10-25 | Fredrik Hübinette (Hubbe) | | return program_from_function(&auto_bignum_program);
}
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | void exit_auto_bignum(void)
{
free_svalue(&auto_bignum_program);
auto_bignum_program.type=T_INT;
|
fda0de | 1999-10-08 | Fredrik Noring | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void convert_stack_top_to_bignum(void)
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | {
apply_svalue(&auto_bignum_program, 1);
|
fda0de | 1999-10-08 | Fredrik Noring | |
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != T_OBJECT)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Gmp.mpz conversion failed.\n");
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | }
|
fda0de | 1999-10-08 | Fredrik Noring | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void convert_stack_top_with_base_to_bignum(void)
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
apply_svalue(&auto_bignum_program, 2);
if(sp[-1].type != T_OBJECT)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Gmp.mpz conversion failed.\n");
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
|
39ac73 | 1999-10-20 | Fredrik Noring | | int is_bignum_object(struct object *o)
{
|
e28b47 | 1999-10-25 | Fredrik Hübinette (Hubbe) | |
|
91487e | 2003-01-11 | Martin Stjernholm | | if (auto_bignum_program.type == T_INT)
|
3905cf | 1999-11-11 | Fredrik Hübinette (Hubbe) | | return 0;
|
e28b47 | 1999-10-25 | Fredrik Hübinette (Hubbe) | |
|
1c1c5e | 2001-04-08 | Fredrik Hübinette (Hubbe) | | return o->prog == program_from_svalue(&auto_bignum_program);
|
39ac73 | 1999-10-20 | Fredrik Noring | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int is_bignum_object_in_svalue(struct svalue *sv)
|
39ac73 | 1999-10-20 | Fredrik Noring | | {
return sv->type == T_OBJECT && is_bignum_object(sv->u.object);
}
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct object *make_bignum_object(void)
|
fda0de | 1999-10-08 | Fredrik Noring | | {
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | convert_stack_top_to_bignum();
|
39ac73 | 1999-10-20 | Fredrik Noring | | return (--sp)->u.object;
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct object *bignum_from_svalue(struct svalue *s)
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | {
push_svalue(s);
convert_stack_top_to_bignum();
|
39ac73 | 1999-10-20 | Fredrik Noring | | return (--sp)->u.object;
|
fda0de | 1999-10-08 | Fredrik Noring | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *string_from_bignum(struct object *o, int base)
|
ff0d46 | 1999-10-15 | Fredrik Noring | | {
push_int(base);
safe_apply(o, "digits", 1);
if(sp[-1].type != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Gmp.mpz string conversion failed.\n");
|
ff0d46 | 1999-10-15 | Fredrik Noring | |
return (--sp)->u.string;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s)
|
fda0de | 1999-10-08 | Fredrik Noring | | {
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | push_svalue(s);
convert_stack_top_to_bignum();
free_svalue(s);
*s=sp[-1];
|
fda0de | 1999-10-08 | Fredrik Noring | | sp--;
|
e801bb | 1999-10-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(sp);
|
fda0de | 1999-10-08 | Fredrik Noring | | }
|
bd35ec | 1999-10-30 | Fredrik Noring | | #ifdef INT64
|
2fe565 | 1999-10-29 | Fredrik Noring | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void push_int64(INT64 i)
|
2fe565 | 1999-10-29 | Fredrik Noring | | {
|
0a5d06 | 2000-08-08 | Henrik Grubbström (Grubba) | | if(i == DO_NOT_WARN((INT_TYPE)i))
|
2fe565 | 1999-10-29 | Fredrik Noring | | {
|
0a5d06 | 2000-08-08 | Henrik Grubbström (Grubba) | | push_int(DO_NOT_WARN((INT_TYPE)i));
|
2fe565 | 1999-10-29 | Fredrik Noring | | }
else
{
|
173c45 | 2001-02-02 | Per Hedbor | | unsigned int neg = 0;
if( i < 0 )
|
2fe565 | 1999-10-29 | Fredrik Noring | | {
|
173c45 | 2001-02-02 | Per Hedbor | | i = -i;
neg = 1;
|
2fe565 | 1999-10-29 | Fredrik Noring | | }
|
cffe80 | 2002-02-12 | Henrik Grubbström (Grubba) | |
|
173c45 | 2001-02-02 | Per Hedbor | | #if PIKE_BYTEORDER == 1234
{
char digits[8];
char *ledigits = (char *)&i;
digits[7] = ledigits[ 0 ]; digits[6] = ledigits[ 1 ];
digits[5] = ledigits[ 2 ]; digits[4] = ledigits[ 3 ];
digits[3] = ledigits[ 4 ]; digits[2] = ledigits[ 5 ];
digits[1] = ledigits[ 6 ]; digits[0] = ledigits[ 7 ];
push_string( make_shared_binary_string( digits, 8 ) );
}
#else
push_string( make_shared_binary_string( (char *)&i, 8 ) );
#endif
push_int( 256 );
apply_svalue(&auto_bignum_program, 2);
|
2fe565 | 1999-10-29 | Fredrik Noring | | if(neg)
apply_low(sp[-1].u.object,FIND_LFUN(sp[-1].u.object->prog,LFUN_COMPL),0);
}
}
|
173c45 | 2001-02-02 | Per Hedbor | |
#define BIGNUM_INT64_MASK 0xffffff
#define BIGNUM_INT64_SHIFT 24
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int int64_from_bignum(INT64 *i, struct object *bignum)
|
2fe565 | 1999-10-29 | Fredrik Noring | | {
int neg, pos, rshfun, andfun;
*i = 0;
push_int(0);
apply_low(bignum, FIND_LFUN(bignum->prog, LFUN_LT), 1);
if(sp[-1].type != T_INT)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Result from Gmp.bignum->`< not an integer.\n");
|
2fe565 | 1999-10-29 | Fredrik Noring | | neg = (--sp)->u.integer;
if(neg)
apply_low(bignum, FIND_LFUN(bignum->prog, LFUN_COMPL), 0);
rshfun = FIND_LFUN(bignum->prog, LFUN_RSH);
andfun = FIND_LFUN(bignum->prog, LFUN_AND);
ref_push_object(bignum);
for(pos = 0; sp[-1].type != T_INT; )
{
push_int(BIGNUM_INT64_MASK);
apply_low(sp[-2].u.object, andfun, 1);
if(sp[-1].type != T_INT)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Result from Gmp.bignum->`& not an integer.\n");
|
2fe565 | 1999-10-29 | Fredrik Noring | | *i |= (INT64)(--sp)->u.integer << (INT64)pos;
pos += BIGNUM_INT64_SHIFT;
push_int(BIGNUM_INT64_SHIFT);
apply_low(sp[-2].u.object, rshfun, 1);
stack_swap();
pop_stack();
}
*i |= (INT64)(--sp)->u.integer << (INT64)pos;
if(neg)
*i = ~*i;
|
bd35ec | 1999-10-30 | Fredrik Noring | |
|
2fe565 | 1999-10-29 | Fredrik Noring | | return 1;
}
|
856cff | 1999-10-29 | Fredrik Noring | | #endif /* INT64 */
|
2fe565 | 1999-10-29 | Fredrik Noring | |
|
fda0de | 1999-10-08 | Fredrik Noring | | #endif /* AUTO_BIGNUM */
|