From 79042c5037c7e14bdaf3445c95c9a1bb5c9c85f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se> Date: Tue, 11 Mar 1997 04:21:39 +0100 Subject: [PATCH] Addressed memory leaks. powm test for divide by zero. Added method mpz->pow(int) and functions gmp.pow(int, int) and Gmp.fac(int) Rev: src/modules/Gmp/mpz_glue.c:1.4 --- src/modules/Gmp/mpz_glue.c | 120 ++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 34 deletions(-) diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c index ea0e567848..ef1ec9f859 100644 --- a/src/modules/Gmp/mpz_glue.c +++ b/src/modules/Gmp/mpz_glue.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: mpz_glue.c,v 1.3 1997/03/10 10:42:28 nisse Exp $"); +RCSID("$Id: mpz_glue.c,v 1.4 1997/03/11 03:21:39 nisse Exp $"); #include "gmp_machine.h" #include "types.h" @@ -270,7 +270,6 @@ static void mpzmod_cast(INT32 args) if(!strcmp(sp[-args].u.string->str, "object")) { pop_n_elems(args); - this_object()->refs++; push_object(this_object()); } break; @@ -279,7 +278,6 @@ static void mpzmod_cast(INT32 args) if(!strcmp(sp[-args].u.string->str, "mixed")) { pop_n_elems(args); - this_object()->refs++; push_object(this_object()); } break; @@ -347,10 +345,14 @@ static void return_temporary(INT32 args) static void name(INT32 args) \ { \ INT32 e; \ - struct object *res = clone(mpzmod_program, 0); \ + struct object *res; \ + for(e=0; e<args; e++) \ + get_mpz(sp+e-args); \ + res = clone(mpzmod_program, 0); \ mpz_set(OBTOMPZ(res), THIS); \ for(e=0;e<args;e++) \ - fun(OBTOMPZ(res), OBTOMPZ(res), get_mpz(sp+e-args));\ + fun(OBTOMPZ(res), OBTOMPZ(res), \ + OBTOMPZ(sp[e-args].u.object)); \ pop_n_elems(args); \ push_object(res); \ } @@ -362,13 +364,19 @@ BINFUN(mpzmod_gcd,mpz_gcd) static void mpzmod_sub(INT32 args) { INT32 e; - struct object *res = clone(mpzmod_program, 0); + struct object *res; + + if (args) + for (e = 0; e<args; e++) + get_mpz(sp + e - args); + + res = clone(mpzmod_program, 0); mpz_set(OBTOMPZ(res), THIS); if(args) { for(e=0;e<args;e++) - mpz_sub(OBTOMPZ(res), OBTOMPZ(res), get_mpz(sp+e-args)); + mpz_sub(OBTOMPZ(res), OBTOMPZ(res), OBTOMPZ(sp[e-args].u.object)); }else{ mpz_neg(OBTOMPZ(res), OBTOMPZ(res)); } @@ -379,21 +387,17 @@ static void mpzmod_sub(INT32 args) static void mpzmod_div(INT32 args) { INT32 e; - - struct object *res = clone(mpzmod_program, 0); - mpz_set(OBTOMPZ(res), THIS); + struct object *res; for(e=0;e<args;e++) - { - MP_INT *tmp; - tmp=get_mpz(sp+e-args); - if(!mpz_sgn(tmp)) - { - really_free_object(res); - error("Division by zero.\n"); - } - mpz_tdiv_q(OBTOMPZ(res), OBTOMPZ(res), tmp); - } + if (mpz_sgn(get_mpz(sp+e-args))) + error("Division by zero.\n"); + + res = clone(mpzmod_program, 0); + mpz_set(OBTOMPZ(res), THIS); + for(e=0;e<args;e++) + mpz_tdiv_q(OBTOMPZ(res), OBTOMPZ(res), OBTOMPZ(sp[e-args].u.object)); + pop_n_elems(args); push_object(res); } @@ -401,17 +405,17 @@ static void mpzmod_div(INT32 args) static void mpzmod_mod(INT32 args) { INT32 e; - struct object *res = clone(mpzmod_program, 0); + struct object *res; + + for(e=0;e<args;e++) + if (mpz_sgn(get_mpz(sp+e-args))) + error("Division by zero.\n"); + + res = clone(mpzmod_program, 0); mpz_set(OBTOMPZ(res), THIS); + for(e=0;e<args;e++) + mpz_tdiv_r(OBTOMPZ(res), OBTOMPZ(res), OBTOMPZ(sp[e-args].u.object)); - for(e=0;e<args;e++) - { - MP_INT *tmp; - tmp=get_mpz(sp+e-args); - if(!mpz_sgn(tmp)) - error("Modulo by zero.\n"); - mpz_tdiv_r(OBTOMPZ(res), OBTOMPZ(res), tmp); - } pop_n_elems(args); push_object(res); } @@ -459,7 +463,9 @@ static void mpzmod_invert(INT32 args) { MP_INT *modulo; struct object *res; - + + if (args != 1) + error("Gmp.mpz->invert: wrong number of arguments.\n"); modulo = get_mpz(sp-args); if (!mpz_sgn(modulo)) error("divide by zero"); @@ -467,7 +473,7 @@ static void mpzmod_invert(INT32 args) if (mpz_invert(OBTOMPZ(res), THIS, modulo) == 0) { really_free_object(res); - error("not invertible"); + error("Gmp.mpz->invert: not invertible"); } pop_n_elems(args); push_object(res); @@ -592,12 +598,57 @@ static void mpzmod_powm(INT32 args) push_object(res); } +static void mpzmod_pow(INT32 args) +{ + struct object *res; + + if (args != 1) + error("Gmp.mpz->pow: Wrong number of arguments.\n"); + if (sp[-1].type != T_INT) + error("Gmp.mpz->pow: Non int exponent.\n"); + if (sp[-1].u.integer < 0) + error("Gmp.mpz->pow: Negative exponent.\n"); + res = clone(mpzmod_program, 0); + mpz_pow_ui(OBTOMPZ(res), THIS, sp[-1].u.integer); + pop_n_elems(args); + push_object(res); +} + static void mpzmod_not(INT32 args) { pop_n_elems(args); push_int(!mpz_sgn(THIS)); } +static void gmp_pow(INT32 args) +{ + struct object *res; + if (args != 2) + error("Gmp.pow: Wrong number of arguments"); + if ( (sp[-2].type != T_INT) || (sp[-2].u.integer < 0) + || (sp[-1].type != T_INT) || (sp[-1].u.integer < 0)) + error("Gmp.pow: Negative arguments"); + res = clone(mpzmod_program, 0); + mpz_ui_pow_ui(OBTOMPZ(res), sp[-2].u.integer, sp[-1].u.integer); + pop_n_elems(args); + push_object(res); +} + +static void gmp_fac(INT32 args) +{ + struct object *res; + if (args != 1) + error("Gmp.fac: Wrong number of arguments.\n"); + if (sp[-1].type != T_INT) + error("Gmp.fac: Non int argument.\n"); + if (sp[-1].u.integer < 0) + error("Gmp.mpz->pow: Negative exponent.\n"); + res = clone(mpzmod_program, 0); + mpz_fac_ui(OBTOMPZ(res), sp[-1].u.integer); + pop_n_elems(args); + push_object(res); +} + static void init_mpz_glue(struct object *o) { mpz_init(THIS); @@ -677,20 +728,21 @@ void pike_module_init(void) add_function("`~",mpzmod_gcd,"function(:object)",0); add_function("powm",mpzmod_powm, "function(" MPZ_ARG_TYPE "," MPZ_ARG_TYPE ":object)", 0); + add_function("pow", mpzmod_pow, "function(int:object)", 0); #if 0 /* These are not implemented yet */ add_function("squarep", mpzmod_squarep, "function(:int)", 0); add_function("divmod", mpzmod_divmod, "function(" MPZ_ARG_TYPE ":array(object))", 0); - add_function("pow", mpzmod_pow, "function(int:object)", 0); add_function("divm", mpzmod_divm, "function(string|int|float|object, string|int|float|object:object)", 0); - add_function("mpz_pow", mpz_pow, "function(int, int)", 0); - add_function("mpz_fac", mpz_fac, "function(int|object:object)", 0); #endif set_init_callback(init_mpz_glue); set_exit_callback(exit_mpz_glue); add_program_constant("mpz", mpzmod_program=end_program(), 0); + add_function("mpz_pow", gmp_pow, "function(int, int:object)", 0); + add_function("mpz_fac", gmp_fac, "function(int:object)", 0); + #endif } -- GitLab