From 039344cf70f52086c9d3b486ea035745b3aaa8c0 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 1 May 2024 21:23:39 +0200 Subject: [PATCH] Avoid extra inits while flooring or ceiling --- ext/bcmath/bcmath.c | 6 ++---- ext/bcmath/libbcmath/src/bcmath.h | 2 +- ext/bcmath/libbcmath/src/floor_or_ceil.c | 25 +++++++++++------------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index b353ea0a7b8..7eae0729d85 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -611,20 +611,18 @@ PHP_FUNCTION(bccomp) static void bcfloor_or_bcceil(INTERNAL_FUNCTION_PARAMETERS, bool is_floor) { zend_string *numstr; - bc_num num = NULL, result; + bc_num num = NULL, result = NULL; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(numstr) ZEND_PARSE_PARAMETERS_END(); - bc_init_num(&result); - if (php_str2num(&num, ZSTR_VAL(numstr)) == FAILURE) { zend_argument_value_error(1, "is not well-formed"); goto cleanup; } - bc_floor_or_ceil(num, is_floor, &result); + result = bc_floor_or_ceil(num, is_floor); RETVAL_NEW_STR(bc_num2str_ex(result, 0)); cleanup: { diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 09c1985d2cb..6b3b14bd159 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -145,7 +145,7 @@ bool bc_modulo(bc_num num1, bc_num num2, bc_num *resul, size_t scale); bool bc_divmod(bc_num num1, bc_num num2, bc_num *quo, bc_num *rem, size_t scale); -void bc_floor_or_ceil(bc_num num, bool is_floor, bc_num *result); +bc_num bc_floor_or_ceil(bc_num num, bool is_floor); void bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result); diff --git a/ext/bcmath/libbcmath/src/floor_or_ceil.c b/ext/bcmath/libbcmath/src/floor_or_ceil.c index 5c3b17c01b6..95c1d60e1b3 100644 --- a/ext/bcmath/libbcmath/src/floor_or_ceil.c +++ b/ext/bcmath/libbcmath/src/floor_or_ceil.c @@ -18,22 +18,19 @@ #include "private.h" #include -void bc_floor_or_ceil(bc_num num, bool is_floor, bc_num *result) +bc_num bc_floor_or_ceil(bc_num num, bool is_floor) { - /* clear result */ - bc_free_num(result); - /* Initialize result */ - *result = bc_new_num(num->n_len, 0); - (*result)->n_sign = num->n_sign; + bc_num result = bc_new_num(num->n_len, 0); + result->n_sign = num->n_sign; /* copy integer part */ - memcpy((*result)->n_value, num->n_value, num->n_len); + memcpy(result->n_value, num->n_value, num->n_len); /* If the number is positive and we are flooring, then nothing else needs to be done. * Similarly, if the number is negative and we are ceiling, then nothing else needs to be done. */ - if (num->n_scale == 0 || (*result)->n_sign == (is_floor ? PLUS : MINUS)) { - return; + if (num->n_scale == 0 || result->n_sign == (is_floor ? PLUS : MINUS)) { + return result; } /* check fractional part. */ @@ -46,12 +43,12 @@ void bc_floor_or_ceil(bc_num num, bool is_floor, bc_num *result) /* If all digits past the decimal point are 0 */ if (count == 0) { - return; + return result; } /* Increment the absolute value of the result by 1 and add sign information */ - bc_num tmp = _bc_do_add(*result, BCG(_one_), 0); - tmp->n_sign = (*result)->n_sign; - bc_free_num(result); - *result = tmp; + bc_num tmp = _bc_do_add(result, BCG(_one_), 0); + tmp->n_sign = result->n_sign; + bc_free_num(&result); + return tmp; }