From 34b2116eb506c1e4d7ad51a5c8acc9dbe4afe70c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 1 May 2024 21:14:03 +0200 Subject: [PATCH] Avoid unnecessary destruction in bc_mul() --- ext/bcmath/bcmath.c | 6 ++---- ext/bcmath/libbcmath/src/bcmath.h | 8 +++++++- ext/bcmath/libbcmath/src/divmod.c | 2 +- ext/bcmath/libbcmath/src/output.c | 4 ++-- ext/bcmath/libbcmath/src/raise.c | 6 +++--- ext/bcmath/libbcmath/src/raisemod.c | 4 ++-- ext/bcmath/libbcmath/src/recmul.c | 5 ++--- ext/bcmath/libbcmath/src/sqrt.c | 4 ++-- 8 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index d6b8ae4d59e..b353ea0a7b8 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -242,7 +242,7 @@ PHP_FUNCTION(bcmul) zend_string *left, *right; zend_long scale_param; bool scale_param_is_null = 1; - bc_num first = NULL, second = NULL, result; + bc_num first = NULL, second = NULL, result = NULL; int scale; ZEND_PARSE_PARAMETERS_START(2, 3) @@ -261,8 +261,6 @@ PHP_FUNCTION(bcmul) scale = (int) scale_param; } - bc_init_num(&result); - if (php_str2num(&first, ZSTR_VAL(left)) == FAILURE) { zend_argument_value_error(1, "is not well-formed"); goto cleanup; @@ -273,7 +271,7 @@ PHP_FUNCTION(bcmul) goto cleanup; } - bc_multiply (first, second, &result, scale); + result = bc_multiply (first, second, scale); RETVAL_NEW_STR(bc_num2str_ex(result, scale)); diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 83e867546cc..09c1985d2cb 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -131,7 +131,13 @@ bc_num bc_sub(bc_num n1, bc_num n2, size_t scale_min); *(result) = sub_ex; \ } while (0) -void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale); +bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale); + +#define bc_multiply_ex(n1, n2, result, scale_min) do { \ + bc_num mul_ex = bc_multiply(n1, n2, scale_min); \ + bc_free_num (result); \ + *(result) = mul_ex; \ +} while (0) bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale); diff --git a/ext/bcmath/libbcmath/src/divmod.c b/ext/bcmath/libbcmath/src/divmod.c index 3dab0104c87..662e5600cb2 100644 --- a/ext/bcmath/libbcmath/src/divmod.c +++ b/ext/bcmath/libbcmath/src/divmod.c @@ -61,7 +61,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, size_t scale if (quot) { quotient = bc_copy_num(temp); } - bc_multiply(temp, num2, &temp, rscale); + bc_multiply_ex(temp, num2, &temp, rscale); bc_sub_ex(num1, temp, rem, rscale); bc_free_num (&temp); diff --git a/ext/bcmath/libbcmath/src/output.c b/ext/bcmath/libbcmath/src/output.c index 699e2ab3b6a..ee3e726c87c 100644 --- a/ext/bcmath/libbcmath/src/output.c +++ b/ext/bcmath/libbcmath/src/output.c @@ -162,7 +162,7 @@ void bc_out_num(bc_num num, int o_base, void (*out_char)(char), bool leading_zer pre_space = false; t_num = bc_copy_num(BCG(_one_)); while (t_num->n_len <= num->n_scale) { - bc_multiply(frac_part, base, &frac_part, num->n_scale); + bc_multiply_ex(frac_part, base, &frac_part, num->n_scale); fdigit = bc_num2long(frac_part); bc_int2num(&int_part, fdigit); bc_sub_ex(frac_part, int_part, &frac_part, 0); @@ -172,7 +172,7 @@ void bc_out_num(bc_num num, int o_base, void (*out_char)(char), bool leading_zer bc_out_long(fdigit, max_o_digit->n_len, pre_space, out_char); pre_space = true; } - bc_multiply(t_num, base, &t_num, 0); + bc_multiply_ex(t_num, base, &t_num, 0); } bc_free_num (&t_num); } diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 61d64ace947..390f4d6935c 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -69,7 +69,7 @@ void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale) pwrscale = num1->n_scale; while ((exponent & 1) == 0) { pwrscale = 2 * pwrscale; - bc_multiply(power, power, &power, pwrscale); + bc_multiply_ex(power, power, &power, pwrscale); exponent = exponent >> 1; } temp = bc_copy_num(power); @@ -79,10 +79,10 @@ void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale) /* Do the calculation. */ while (exponent > 0) { pwrscale = 2 * pwrscale; - bc_multiply(power, power, &power, pwrscale); + bc_multiply_ex(power, power, &power, pwrscale); if ((exponent & 1) == 1) { calcscale = pwrscale + calcscale; - bc_multiply(temp, power, &temp, calcscale); + bc_multiply_ex(temp, power, &temp, calcscale); } exponent = exponent >> 1; } diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index d4a2d01f3ed..caf1a090f98 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -72,10 +72,10 @@ raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *resul while (!bc_is_zero(exponent)) { (void) bc_divmod(exponent, BCG(_two_), &exponent, &parity, 0); if (!bc_is_zero(parity)) { - bc_multiply(temp, power, &temp, scale); + bc_multiply_ex(temp, power, &temp, scale); (void) bc_modulo(temp, modulus, &temp, scale); } - bc_multiply(power, power, &power, scale); + bc_multiply_ex(power, power, &power, scale); (void) bc_modulo(power, modulus, &power, scale); } } diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index ea4c64300f0..127330ba3ae 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -253,7 +253,7 @@ static void _bc_rec_mul(bc_num u, size_t ulen, bc_num v, size_t vlen, bc_num *pr the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)). */ -void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale) +bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale) { bc_num pval; size_t len1, len2; @@ -276,6 +276,5 @@ void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale) if (bc_is_zero(pval)) { pval->n_sign = PLUS; } - bc_free_num(prod); - *prod = pval; + return pval; } diff --git a/ext/bcmath/libbcmath/src/sqrt.c b/ext/bcmath/libbcmath/src/sqrt.c index 6be595deb4f..995bf076b54 100644 --- a/ext/bcmath/libbcmath/src/sqrt.c +++ b/ext/bcmath/libbcmath/src/sqrt.c @@ -79,7 +79,7 @@ bool bc_sqrt(bc_num *num, size_t scale) bc_int2num(&guess, 10); bc_int2num(&guess1, (*num)->n_len); - bc_multiply(guess1, point5, &guess1, 0); + bc_multiply_ex(guess1, point5, &guess1, 0); guess1->n_scale = 0; bc_raise_bc_exponent(guess, guess1, &guess, 0); bc_free_num (&guess1); @@ -93,7 +93,7 @@ bool bc_sqrt(bc_num *num, size_t scale) guess1 = bc_copy_num(guess); bc_divide(*num, guess, &guess, cscale); bc_add_ex(guess, guess1, &guess, 0); - bc_multiply(guess, point5, &guess, cscale); + bc_multiply_ex(guess, point5, &guess, cscale); bc_sub_ex(guess, guess1, &diff, cscale + 1); if (bc_is_near_zero(diff, cscale)) { if (cscale < rscale + 1) {