mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Reapply memory leak fixes to zmod.c
Revert previously applied zmod.c mods and then apply better mods to fix zmod memory leaks.
This commit is contained in:
72
zmod.c
72
zmod.c
@@ -480,7 +480,7 @@ zmod6(ZVALUE z1, ZVALUE *res)
|
||||
* slightly faster.
|
||||
*/
|
||||
void
|
||||
zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
{
|
||||
HALF *hp; /* pointer to current word of the power */
|
||||
REDC *rp; /* REDC information to be used */
|
||||
@@ -488,11 +488,12 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
ZVALUE ans, temp; /* calculation values */
|
||||
ZVALUE modpow; /* current small power */
|
||||
ZVALUE lowpowers[POWNUMS]; /* low powers */
|
||||
ZVALUE z1;
|
||||
ZVALUE ztmp;
|
||||
int curshift; /* shift value for word of power */
|
||||
HALF curhalf; /* current word of power */
|
||||
unsigned int curpow; /* current low power */
|
||||
unsigned int curbit; /* current bit of low power */
|
||||
BOOL free_z1; /* TRUE => need to free z1 */
|
||||
int i;
|
||||
|
||||
if (zisneg(z3) || ziszero(z3)) {
|
||||
@@ -508,7 +509,7 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
/*
|
||||
* Check easy cases first.
|
||||
*/
|
||||
if ((ziszero(z1_arg) && !ziszero(z2)) || zisunit(z3)) {
|
||||
if ((ziszero(z1) && !ziszero(z2)) || zisunit(z3)) {
|
||||
/* 0^(non_zero) or x^y mod 1 always produces zero */
|
||||
*res = _zero_;
|
||||
return;
|
||||
@@ -518,13 +519,13 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
return;
|
||||
}
|
||||
if (zistwo(z3)) { /* mod 2 */
|
||||
if (zisodd(z1_arg))
|
||||
if (zisodd(z1))
|
||||
*res = _one_;
|
||||
else
|
||||
*res = _zero_;
|
||||
return;
|
||||
}
|
||||
if (zisunit(z1_arg) && (!z1_arg.sign || ziseven(z2))) {
|
||||
if (zisunit(z1) && (!z1.sign || ziseven(z2))) {
|
||||
/* 1^x or (-1)^(2x) */
|
||||
*res = _one_;
|
||||
return;
|
||||
@@ -534,18 +535,25 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
* Normalize the number being raised to be non-negative and to lie
|
||||
* within the modulo range. Then check for zero or one specially.
|
||||
*/
|
||||
if (zisneg(z1_arg) || zrel(z1_arg, z3) >= 0) {
|
||||
zmod(z1_arg, z3, &z1, 0);
|
||||
} else {
|
||||
zcopy(z1_arg, &z1);
|
||||
ztmp.len = 0;
|
||||
free_z1 = FALSE;
|
||||
if (zisneg(z1) || zrel(z1, z3) >= 0) {
|
||||
zmod(z1, z3, &ztmp, 0);
|
||||
zfree(z1);
|
||||
z1 = ztmp;
|
||||
free_z1 = TRUE;
|
||||
}
|
||||
if (ziszero(z1)) {
|
||||
zfree(z1);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
*res = _zero_;
|
||||
return;
|
||||
}
|
||||
if (zisone(z1)) {
|
||||
zfree(z1);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
*res = _one_;
|
||||
return;
|
||||
}
|
||||
@@ -573,7 +581,7 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
pp->v = NULL;
|
||||
}
|
||||
lowpowers[0] = _one_;
|
||||
zcopy(z1, &lowpowers[1]);
|
||||
lowpowers[1] = z1;
|
||||
ans = _one_;
|
||||
|
||||
hp = &z2.v[z2.len - 1];
|
||||
@@ -596,10 +604,12 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
* future use.
|
||||
*/
|
||||
if (pp->v == NULL) {
|
||||
if (curpow & 0x1)
|
||||
if (curpow & 0x1) {
|
||||
zcopy(z1, &modpow);
|
||||
else
|
||||
free_z1 = FALSE;
|
||||
} else {
|
||||
modpow = _one_;
|
||||
}
|
||||
|
||||
for (curbit = 0x2;
|
||||
curbit <= curpow;
|
||||
@@ -664,11 +674,12 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
}
|
||||
}
|
||||
|
||||
for (pp = &lowpowers[1]; pp <= &lowpowers[POWNUMS-1]; pp++) {
|
||||
for (pp = &lowpowers[2]; pp <= &lowpowers[POWNUMS-1]; pp++) {
|
||||
zfree(*pp);
|
||||
}
|
||||
*res = ans;
|
||||
zfree(z1);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -685,7 +696,9 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
powermodredc = zredcalloc(z3);
|
||||
rp = powermodredc;
|
||||
zredcencode(rp, z1, &temp);
|
||||
if (free_z1 == TRUE) {
|
||||
zfree(z1);
|
||||
}
|
||||
zredcpower(rp, temp, z2, &z1);
|
||||
zfree(temp);
|
||||
zredcdecode(rp, z1, res);
|
||||
@@ -702,7 +715,7 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
pp->v = NULL;
|
||||
}
|
||||
lowpowers[0] = _one_;
|
||||
zcopy(z1, &lowpowers[1]);
|
||||
lowpowers[1] = z1;
|
||||
ans = _one_;
|
||||
|
||||
hp = &z2.v[z2.len - 1];
|
||||
@@ -724,10 +737,12 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
* calculate it and remember it in the table for future use.
|
||||
*/
|
||||
if (pp->v == NULL) {
|
||||
if (curpow & 0x1)
|
||||
if (curpow & 0x1) {
|
||||
zcopy(z1, &modpow);
|
||||
else
|
||||
free_z1 = FALSE;
|
||||
} else {
|
||||
modpow = _one_;
|
||||
}
|
||||
|
||||
for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
|
||||
pp = &lowpowers[curbit];
|
||||
@@ -744,7 +759,9 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
}
|
||||
}
|
||||
pp = &lowpowers[curpow];
|
||||
if (pp->v != NULL) {
|
||||
zfree(*pp);
|
||||
}
|
||||
*pp = modpow;
|
||||
}
|
||||
|
||||
@@ -783,12 +800,15 @@ zpowermod(ZVALUE z1_arg, ZVALUE z2, ZVALUE z3, ZVALUE *res)
|
||||
}
|
||||
}
|
||||
|
||||
for (pp = &lowpowers[1]; pp <= &lowpowers[POWNUMS-1]; pp++) {
|
||||
for (pp = &lowpowers[2]; pp <= &lowpowers[POWNUMS-1]; pp++) {
|
||||
zfree(*pp);
|
||||
}
|
||||
*res = ans;
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
if (free_z1 == TRUE) {
|
||||
zfree(z1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1129,6 +1149,7 @@ zredcdecode(REDC *rp, ZVALUE z1, ZVALUE *res)
|
||||
if (ztop.len) {
|
||||
zadd(*res, ztop, &tmp1);
|
||||
zfree(*res);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
*res = tmp1;
|
||||
}
|
||||
@@ -1497,12 +1518,14 @@ zredcsquare(REDC *rp, ZVALUE z1, ZVALUE *res)
|
||||
}
|
||||
if (ziszero(z1)) {
|
||||
*res = _zero_;
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
|
||||
(zcmp(z1, rp->one) == 0)) {
|
||||
zcopy(z1, res);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1518,6 +1541,7 @@ zredcsquare(REDC *rp, ZVALUE z1, ZVALUE *res)
|
||||
zsquare(z1, &tmp);
|
||||
zredcdecode(rp, tmp, res);
|
||||
zfree(tmp);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1623,6 +1647,7 @@ zredcsquare(REDC *rp, ZVALUE z1, ZVALUE *res)
|
||||
}
|
||||
res->len = len;
|
||||
if (zrel(*res, rp->mod) < 0) {
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1646,6 +1671,7 @@ zredcsquare(REDC *rp, ZVALUE z1, ZVALUE *res)
|
||||
len--;
|
||||
}
|
||||
res->len = len;
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
}
|
||||
|
||||
@@ -1705,6 +1731,7 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
|
||||
*res = _one_;
|
||||
else
|
||||
*res = _zero_;
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1713,6 +1740,7 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
|
||||
zsub(rp->mod, rp->one, res);
|
||||
else
|
||||
zcopy(rp->one, res);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1727,11 +1755,13 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
|
||||
if (zcmp(z1, temp) == 0) {
|
||||
if (zisodd(z2) ^ sign) {
|
||||
*res = temp;
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
zfree(temp);
|
||||
zcopy(rp->one, res);
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
return;
|
||||
}
|
||||
@@ -1820,8 +1850,7 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
|
||||
}
|
||||
|
||||
for (pp = lowpowers; pp < &lowpowers[POWNUMS]; pp++) {
|
||||
if (pp->len)
|
||||
freeh(pp->v);
|
||||
zfree(*pp);
|
||||
}
|
||||
if (sign && !ziszero(ans)) {
|
||||
zsub(rp->mod, ans, res);
|
||||
@@ -1829,6 +1858,7 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
|
||||
} else {
|
||||
*res = ans;
|
||||
}
|
||||
if (ztmp.len)
|
||||
zfree(ztmp);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user