diff --git a/ext/bcmath/libbcmath/src/adapter.h b/ext/bcmath/libbcmath/src/adapter.h new file mode 100644 index 0000000000000..cbfca1b7536e8 --- /dev/null +++ b/ext/bcmath/libbcmath/src/adapter.h @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Saki Takamachi | + +----------------------------------------------------------------------+ +*/ + +/* libbcmath is heavily optimized for PHP. This file consolidates + * the features that libbcmath depends on from PHP. */ + +#ifndef _BCMATH_ADAPTER_H_ +#define _BCMATH_ADAPTER_H_ + +#ifdef HAVE_CONFIG_H +# ifdef PHP_WIN32 +# include "../../../../main/config.w32.h" +# else +# include +# endif +#endif + +#include "zend.h" + +/* Needed for BCG() macro and PHP_ROUND_XXX */ +#include "../../php_bcmath.h" + +typedef zend_string bc_string; +#define BC_STR_VAL(s) ZSTR_VAL(s) +#define BC_STR_LEN(s) ZSTR_LEN(s) +#define bc_string_alloc(len, persistent) zend_string_alloc((len), (persistent)) + +typedef zend_long bc_long; +#define BC_LONG_MIN_DIGITS LONG_MIN_DIGITS +#define BC_L(i) Z_L(i) +#define BC_LONG_MAX ZEND_LONG_MAX +#define BC_LONG_MIN ZEND_LONG_MIN + +#define bc_safe_emalloc(n, size, offset) (safe_emalloc((n), (size), (offset))) +#define bc_efree(ptr) (efree((ptr))) + +#define bc_pemalloc(size, persistent) (pemalloc((size), (persistent))) +#define bc_pefree(ptr, persistent) (pefree((ptr), (persistent))) + +#define bc_safe_address_guarded(n, size, offset) (zend_safe_address_guarded((n), (size), (offset))) +#define BC_MM_ALIGNMENT ZEND_MM_ALIGNMENT + +#define BC_ROUND_HALF_UP PHP_ROUND_HALF_UP +#define BC_ROUND_HALF_DOWN PHP_ROUND_HALF_DOWN +#define BC_ROUND_HALF_EVEN PHP_ROUND_HALF_EVEN +#define BC_ROUND_HALF_ODD PHP_ROUND_HALF_ODD +#define BC_ROUND_CEILING PHP_ROUND_CEILING +#define BC_ROUND_FLOOR PHP_ROUND_FLOOR +#define BC_ROUND_TOWARD_ZERO PHP_ROUND_TOWARD_ZERO +#define BC_ROUND_AWAY_FROM_ZERO PHP_ROUND_AWAY_FROM_ZERO + +#define BC_EMPTY_SWITCH_DEFAULT_CASE() EMPTY_SWITCH_DEFAULT_CASE() + +#ifdef PHP_HAVE_BUILTIN_CTZL +# define BC_HAVE_BUILTIN_CTZL +#endif + +#define BC_ASSERT(cond) ZEND_ASSERT(cond) + +#define BC_BYTES_SWAP64(x) ZEND_BYTES_SWAP64(x) +#define BC_BYTES_SWAP32(x) ZEND_BYTES_SWAP32(x) + +#ifdef WORDS_BIGENDIAN +# define BC_LITTLE_ENDIAN 0 +#else +# define BC_LITTLE_ENDIAN 1 +#endif + +/* SIZEOF_SIZE_T, EXPECTED, UNEXPECTED, and BCG() have clear meanings and + * would not be difficult to modify if needed, so they will not be replaced. */ + +#endif diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index fa335ae404808..0f002c5352fbf 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -32,6 +32,7 @@ #ifndef _BCMATH_H_ #define _BCMATH_H_ +#include #include typedef enum {PLUS, MINUS} sign; @@ -46,16 +47,7 @@ typedef struct bc_struct { sign n_sign; } bc_struct; -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "zend.h" -#include -#include "zend_string.h" - -/* Needed for BCG() macro and PHP_ROUND_XXX */ -#include "../../php_bcmath.h" +#include "adapter.h" /* The base used in storing the numbers in n_value above. Currently, this MUST be 10. */ @@ -97,9 +89,9 @@ void bc_init_num(bc_num *num); bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, size_t *full_scale, bool auto_scale); -bc_num bc_long2num(zend_long lval); +bc_num bc_long2num(bc_long lval); -zend_string *bc_num2str_ex(bc_num num, size_t scale); +bc_string *bc_num2str_ex(bc_num num, size_t scale); void bc_int2num(bc_num *num, int val); @@ -155,7 +147,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quo, bc_num *rem, size_t scale) bc_num bc_floor_or_ceil(bc_num num, bool is_floor); -size_t bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result); +size_t bc_round(bc_num num, bc_long places, bc_long mode, bc_num *result); typedef enum { BC_RAISE_STATUS_OK, diff --git a/ext/bcmath/libbcmath/src/config.h b/ext/bcmath/libbcmath/src/config.h deleted file mode 100644 index 0c7b3c220838b..0000000000000 --- a/ext/bcmath/libbcmath/src/config.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef PHP_WIN32 -#include "../../../../main/config.w32.h" -#else -#include -#endif diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 24ec9a64d77fc..8313c4a109c10 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -35,7 +35,6 @@ #include #include #include -#include "zend_alloc.h" /* * This function should be used when the divisor is not split into multiple chunks, i.e. when the size of the array is one. @@ -267,7 +266,7 @@ static void bc_do_div( if (allocation_arr_size <= BC_STACK_VECTOR_SIZE) { numerator_vectors = stack_vectors; } else { - numerator_vectors = safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0); + numerator_vectors = bc_safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0); } BC_VECTOR *divisor_vectors = numerator_vectors + numerator_arr_size; BC_VECTOR *quot_vectors = divisor_vectors + divisor_arr_size; @@ -296,7 +295,7 @@ static void bc_do_div( bc_convert_vector_to_char(quot_vectors, qptr, qend, quot_real_arr_size); if (allocation_arr_size > BC_STACK_VECTOR_SIZE) { - efree(numerator_vectors); + bc_efree(numerator_vectors); } } diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index beaa14ea8c4d2..3ba48f716f3d5 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -33,12 +33,11 @@ #include #include #include -#include "zend_alloc.h" static bc_num _bc_new_num_nonzeroed_ex_internal(size_t length, size_t scale, bool persistent) { - size_t required_size = zend_safe_address_guarded(1, sizeof(bc_struct) + (ZEND_MM_ALIGNMENT - 1) + length, scale); - required_size &= -ZEND_MM_ALIGNMENT; + size_t required_size = bc_safe_address_guarded(1, sizeof(bc_struct) + (BC_MM_ALIGNMENT - 1) + length, scale); + required_size &= -BC_MM_ALIGNMENT; bc_num temp; if (!persistent && BCG(arena) && required_size <= BC_ARENA_SIZE - BCG(arena_offset)) { @@ -46,8 +45,7 @@ static bc_num _bc_new_num_nonzeroed_ex_internal(size_t length, size_t scale, boo BCG(arena_offset) += required_size; temp->n_refs = 2; /* prevent freeing */ } else { - /* PHP Change: malloc() -> pemalloc(), removed free_list code, merged n_ptr and n_value */ - temp = pemalloc(required_size, persistent); + temp = bc_pemalloc(required_size, persistent); temp->n_refs = 1; } @@ -80,7 +78,7 @@ void _bc_free_num_ex(bc_num *num, bool persistent) } (*num)->n_refs--; if ((*num)->n_refs == 0) { - pefree(*num, persistent); + bc_pefree(*num, persistent); } *num = NULL; } @@ -99,7 +97,7 @@ void bc_init_numbers(void) void bc_force_free_number(bc_num *num) { - pefree(*num, 1); + bc_pefree(*num, 1); *num = NULL; } diff --git a/ext/bcmath/libbcmath/src/long2num.c b/ext/bcmath/libbcmath/src/long2num.c index 7645045b1fa36..0bd5f41d6b231 100644 --- a/ext/bcmath/libbcmath/src/long2num.c +++ b/ext/bcmath/libbcmath/src/long2num.c @@ -18,9 +18,9 @@ #include #include "convert.h" -#define BC_LONG_MAX_DIGITS (sizeof(LONG_MIN_DIGITS) - 1) +#define BC_LONG_MAX_DIGITS (sizeof(BC_LONG_MIN_DIGITS) - 1) -bc_num bc_long2num(zend_long lval) +bc_num bc_long2num(bc_long lval) { bc_num num; @@ -30,9 +30,9 @@ bc_num bc_long2num(zend_long lval) } bool negative = lval < 0; - if (UNEXPECTED(lval == ZEND_LONG_MIN)) { + if (UNEXPECTED(lval == BC_LONG_MIN)) { num = bc_new_num_nonzeroed(BC_LONG_MAX_DIGITS, 0); - const char *ptr = LONG_MIN_DIGITS; + const char *ptr = BC_LONG_MIN_DIGITS; bc_copy_and_toggle_bcd(num->n_value, ptr, ptr + BC_LONG_MAX_DIGITS); num->n_sign = MINUS; return num; @@ -40,7 +40,7 @@ bc_num bc_long2num(zend_long lval) lval = -lval; } - zend_long tmp = lval; + bc_long tmp = lval; size_t len = 0; while (tmp > 0) { tmp /= BASE; diff --git a/ext/bcmath/libbcmath/src/num2str.c b/ext/bcmath/libbcmath/src/num2str.c index 7679ae5d38701..518a0b6e4a9e5 100644 --- a/ext/bcmath/libbcmath/src/num2str.c +++ b/ext/bcmath/libbcmath/src/num2str.c @@ -31,12 +31,11 @@ #include "bcmath.h" #include "convert.h" -#include "zend_string.h" /* Convert a numbers to a string. Base 10 only.*/ -zend_string *bc_num2str_ex(bc_num num, size_t scale) +bc_string *bc_num2str_ex(bc_num num, size_t scale) { - zend_string *str; + bc_string *str; char *sptr; size_t index; bool signch; @@ -46,13 +45,13 @@ zend_string *bc_num2str_ex(bc_num num, size_t scale) signch = num->n_sign != PLUS && !bc_is_zero_for_scale(num, min_scale); /* Allocate the string memory. */ if (scale > 0) { - str = zend_string_alloc(num->n_len + scale + signch + 1, 0); + str = bc_string_alloc(num->n_len + scale + signch + 1, 0); } else { - str = zend_string_alloc(num->n_len + signch, 0); + str = bc_string_alloc(num->n_len + signch, 0); } /* The negative sign if needed. */ - sptr = ZSTR_VAL(str); + sptr = BC_STR_VAL(str); if (signch) *sptr++ = '-'; /* Load the whole number. */ @@ -71,6 +70,6 @@ zend_string *bc_num2str_ex(bc_num num, size_t scale) /* Terminate the string and return it! */ *sptr = '\0'; - ZSTR_LEN(str) = sptr - (char *)ZSTR_VAL(str); + BC_STR_LEN(str) = sptr - (char *)BC_STR_VAL(str); return str; } diff --git a/ext/bcmath/libbcmath/src/private.h b/ext/bcmath/libbcmath/src/private.h index de9045a16c7e5..47b2c80217027 100644 --- a/ext/bcmath/libbcmath/src/private.h +++ b/ext/bcmath/libbcmath/src/private.h @@ -33,7 +33,6 @@ #include #include -#include "zend_portability.h" #ifndef _BCMATH_PRIV_H_ #define _BCMATH_PRIV_H_ @@ -45,25 +44,19 @@ #define SWAR_REPEAT(x) (SWAR_ONES * (x)) #if SIZEOF_SIZE_T >= 8 -# define BC_BSWAP(u) ZEND_BYTES_SWAP64(u) +# define BC_BSWAP(u) BC_BYTES_SWAP64(u) typedef uint64_t BC_VECTOR; # define BC_VECTOR_SIZE 8 /* The boundary number is computed from BASE ** BC_VECTOR_SIZE */ # define BC_VECTOR_BOUNDARY_NUM (BC_VECTOR) 100000000 #else -# define BC_BSWAP(u) ZEND_BYTES_SWAP32(u) +# define BC_BSWAP(u) BC_BYTES_SWAP32(u) typedef uint32_t BC_VECTOR; # define BC_VECTOR_SIZE 4 /* The boundary number is computed from BASE ** BC_VECTOR_SIZE */ # define BC_VECTOR_BOUNDARY_NUM (BC_VECTOR) 10000 #endif -#ifdef WORDS_BIGENDIAN -# define BC_LITTLE_ENDIAN 0 -#else -# define BC_LITTLE_ENDIAN 1 -#endif - /* 64-bytes for 64-bit */ #define BC_STACK_VECTOR_SIZE 8 diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 5df8130c24219..147e6aba233be 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -112,7 +112,7 @@ static bc_num bc_standard_raise( size_t max_power_arr_size = base_arr_size * exponent; /* The allocated memory area is reused on a rotational basis, so the same size is required. */ - BC_VECTOR *buf = safe_emalloc(max_power_arr_size, sizeof(BC_VECTOR) * 3, 0); + BC_VECTOR *buf = bc_safe_emalloc(max_power_arr_size, sizeof(BC_VECTOR) * 3, 0); BC_VECTOR *base_vector = buf; BC_VECTOR *power_vector = base_vector + max_power_arr_size; BC_VECTOR *tmp_result_vector = power_vector + max_power_arr_size; @@ -162,7 +162,7 @@ static bc_num bc_standard_raise( bc_convert_vector_to_char(power_vector, pptr, pend, power_arr_size); - efree(buf); + bc_efree(buf); return power; } diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 5e69fd7eb0336..d48e5170dc04a 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -35,7 +35,6 @@ #include #include "private.h" #include "convert.h" -#include "zend_alloc.h" /* Multiply utility routines */ @@ -135,7 +134,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc * then this sum is <= N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE - 1 * which is equal to N - 1 if BC_VECTOR_SIZE is 4, and N/2 - 1 if BC_VECTOR_SIZE is 8. */ - n1_vector = safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0); + n1_vector = bc_safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0); } BC_VECTOR *n2_vector = n1_vector + n1_arr_size; BC_VECTOR *prod_vector = n2_vector + n2_arr_size; @@ -154,7 +153,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc bc_convert_vector_to_char(prod_vector, pptr, pend, prod_arr_size); if (allocation_arr_size > BC_STACK_VECTOR_SIZE) { - efree(n1_vector); + bc_efree(n1_vector); } } diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c index 44df6036cbe3b..19a136fdab57f 100644 --- a/ext/bcmath/libbcmath/src/round.c +++ b/ext/bcmath/libbcmath/src/round.c @@ -19,7 +19,7 @@ #include /* Returns the scale of the value after rounding. */ -size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) +size_t bc_round(bc_num num, bc_long precision, bc_long mode, bc_num *result) { /* clear result */ bc_free_num(result); @@ -36,34 +36,34 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) */ /* e.g. value is 0.1 and precision is -3, ret is 0 or 1000 */ - if (precision < 0 && num->n_len < (size_t) (-(precision + Z_L(1))) + 1) { + if (precision < 0 && num->n_len < (size_t) (-(precision + BC_L(1))) + 1) { switch (mode) { - case PHP_ROUND_HALF_UP: - case PHP_ROUND_HALF_DOWN: - case PHP_ROUND_HALF_EVEN: - case PHP_ROUND_HALF_ODD: - case PHP_ROUND_TOWARD_ZERO: + case BC_ROUND_HALF_UP: + case BC_ROUND_HALF_DOWN: + case BC_ROUND_HALF_EVEN: + case BC_ROUND_HALF_ODD: + case BC_ROUND_TOWARD_ZERO: *result = bc_copy_num(BCG(_zero_)); return 0; - case PHP_ROUND_CEILING: + case BC_ROUND_CEILING: if (num->n_sign == MINUS) { *result = bc_copy_num(BCG(_zero_)); return 0; } break; - case PHP_ROUND_FLOOR: + case BC_ROUND_FLOOR: if (num->n_sign == PLUS) { *result = bc_copy_num(BCG(_zero_)); return 0; } break; - case PHP_ROUND_AWAY_FROM_ZERO: + case BC_ROUND_AWAY_FROM_ZERO: break; - EMPTY_SWITCH_DEFAULT_CASE() + BC_EMPTY_SWITCH_DEFAULT_CASE() } if (bc_is_zero(num)) { @@ -72,8 +72,8 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) } /* If precision is -3, it becomes 1000. */ - if (UNEXPECTED(precision == ZEND_LONG_MIN)) { - *result = bc_new_num((size_t) ZEND_LONG_MAX + 2, 0); + if (UNEXPECTED(precision == BC_LONG_MIN)) { + *result = bc_new_num((size_t) BC_LONG_MAX + 2, 0); } else { *result = bc_new_num(-precision + 1, 0); } @@ -117,7 +117,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) /* Check cases that can be determined without looping. */ switch (mode) { - case PHP_ROUND_HALF_UP: + case BC_ROUND_HALF_UP: if (*nptr >= 5) { goto up; } else if (*nptr < 5) { @@ -125,9 +125,9 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) } break; - case PHP_ROUND_HALF_DOWN: - case PHP_ROUND_HALF_EVEN: - case PHP_ROUND_HALF_ODD: + case BC_ROUND_HALF_DOWN: + case BC_ROUND_HALF_EVEN: + case BC_ROUND_HALF_ODD: if (*nptr > 5) { goto up; } else if (*nptr < 5) { @@ -136,7 +136,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) /* if *nptr == 5, we need to look-up further digits before making a decision. */ break; - case PHP_ROUND_CEILING: + case BC_ROUND_CEILING: if (num->n_sign != PLUS) { goto check_zero; } else if (*nptr > 0) { @@ -145,7 +145,7 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) /* if *nptr == 0, a loop is required for judgment. */ break; - case PHP_ROUND_FLOOR: + case BC_ROUND_FLOOR: if (num->n_sign != MINUS) { goto check_zero; } else if (*nptr > 0) { @@ -154,17 +154,17 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) /* if *nptr == 0, a loop is required for judgment. */ break; - case PHP_ROUND_TOWARD_ZERO: + case BC_ROUND_TOWARD_ZERO: goto check_zero; - case PHP_ROUND_AWAY_FROM_ZERO: + case BC_ROUND_AWAY_FROM_ZERO: if (*nptr > 0) { goto up; } /* if *nptr == 0, a loop is required for judgment. */ break; - EMPTY_SWITCH_DEFAULT_CASE() + BC_EMPTY_SWITCH_DEFAULT_CASE() } /* Loop through the remaining digits. */ @@ -180,25 +180,25 @@ size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) } switch (mode) { - case PHP_ROUND_HALF_DOWN: - case PHP_ROUND_CEILING: - case PHP_ROUND_FLOOR: - case PHP_ROUND_AWAY_FROM_ZERO: + case BC_ROUND_HALF_DOWN: + case BC_ROUND_CEILING: + case BC_ROUND_FLOOR: + case BC_ROUND_AWAY_FROM_ZERO: goto check_zero; - case PHP_ROUND_HALF_EVEN: + case BC_ROUND_HALF_EVEN: if (rounded_len == 0 || num->n_value[rounded_len - 1] % 2 == 0) { goto check_zero; } break; - case PHP_ROUND_HALF_ODD: + case BC_ROUND_HALF_ODD: if (rounded_len != 0 && num->n_value[rounded_len - 1] % 2 == 1) { goto check_zero; } break; - EMPTY_SWITCH_DEFAULT_CASE() + BC_EMPTY_SWITCH_DEFAULT_CASE() } up: diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c index 945de0cf60003..720100e2bd7a2 100644 --- a/ext/bcmath/libbcmath/src/str2num.c +++ b/ext/bcmath/libbcmath/src/str2num.c @@ -56,7 +56,7 @@ static inline const char *bc_count_digits(const char *str, const char *end) int mask = bc_simd_movemask_8x16(bytes); if (mask != 0xffff) { /* At least one of the bytes is not within range. Move to the first offending byte. */ -#ifdef PHP_HAVE_BUILTIN_CTZL +#ifdef BC_HAVE_BUILTIN_CTZL return str + __builtin_ctz(~mask); #else break; @@ -112,7 +112,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz const char *fractional_end = NULL; bool zero_int = false; - ZEND_ASSERT(*num == NULL); + BC_ASSERT(*num == NULL); /* Check for valid number and count digits. */ if ((*ptr == '+') || (*ptr == '-')) {