Skip to content

Commit 80d172d

Browse files
committed
Refactor bc_raise() to get rid of Zend dependencies
This seperates the concerns of throwing exceptions back into the PHP_FUNCTION instead of being the responsability of the library
1 parent d8cea19 commit 80d172d

File tree

4 files changed

+39
-23
lines changed

4 files changed

+39
-23
lines changed

ext/bcmath/bcmath.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ PHP_FUNCTION(bcpow)
501501
zend_string *left, *right;
502502
zend_long scale_param;
503503
bool scale_param_is_null = 1;
504-
bc_num first, second, result;
504+
bc_num first, bc_exponent, result;
505505
int scale = BCG(bc_precision);
506506

507507
ZEND_PARSE_PARAMETERS_START(2, 3)
@@ -521,26 +521,37 @@ PHP_FUNCTION(bcpow)
521521
}
522522

523523
bc_init_num(&first);
524-
bc_init_num(&second);
524+
bc_init_num(&bc_exponent);
525525
bc_init_num(&result);
526526

527527
if (php_str2num(&first, ZSTR_VAL(left)) == FAILURE) {
528528
zend_argument_value_error(1, "is not well-formed");
529529
goto cleanup;
530530
}
531531

532-
if (php_str2num(&second, ZSTR_VAL(right)) == FAILURE) {
532+
if (php_str2num(&bc_exponent, ZSTR_VAL(right)) == FAILURE) {
533533
zend_argument_value_error(2, "is not well-formed");
534534
goto cleanup;
535535
}
536536

537-
bc_raise (first, second, &result, scale);
537+
/* Check the exponent for scale digits and convert to a long. */
538+
if (bc_exponent->n_scale != 0) {
539+
zend_argument_value_error(2, "cannot have a fractional part");
540+
goto cleanup;
541+
}
542+
long exponent = bc_num2long(bc_exponent);
543+
if (exponent == 0 && (bc_exponent->n_len > 1 || bc_exponent->n_value[0] != 0)) {
544+
zend_argument_value_error(2, "is too large");
545+
goto cleanup;
546+
}
547+
548+
bc_raise(first, exponent, &result, scale);
538549

539550
RETVAL_STR(bc_num2str_ex(result, scale));
540551

541552
cleanup: {
542553
bc_free_num(&first);
543-
bc_free_num(&second);
554+
bc_free_num(&bc_exponent);
544555
bc_free_num(&result);
545556
};
546557
}

ext/bcmath/libbcmath/src/bcmath.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ typedef enum {
135135

136136
raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *result, size_t scale);
137137

138-
void bc_raise(bc_num num1, bc_num num2, bc_num *resul, size_t scale);
138+
void bc_raise(bc_num base, long exponent, bc_num *resul, size_t scale);
139+
140+
void bc_raise_bc_exponent(bc_num base, bc_num exponent, bc_num *resul, size_t scale);
139141

140142
bool bc_sqrt(bc_num *num, size_t scale);
141143

ext/bcmath/libbcmath/src/raise.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,23 @@
3030
*************************************************************************/
3131

3232
#include "bcmath.h"
33+
#include <assert.h>
3334
#include <stdbool.h>
3435
#include <stddef.h>
35-
#include "zend_exceptions.h" /* zend_argument_value_error() */
3636

3737

3838
/* Raise NUM1 to the NUM2 power. The result is placed in RESULT.
3939
Maximum exponent is LONG_MAX. If a NUM2 is not an integer,
4040
only the integer part is used. */
4141

42-
void bc_raise(bc_num num1, bc_num num2, bc_num *result, size_t scale)
42+
void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale)
4343
{
4444
bc_num temp, power;
45-
long exponent;
4645
size_t rscale;
4746
size_t pwrscale;
4847
size_t calcscale;
4948
bool is_neg;
5049

51-
/* Check the exponent for scale digits and convert to a long. */
52-
if (num2->n_scale != 0) {
53-
/* 2nd argument from PHP_FUNCTION(bcpow) */
54-
zend_argument_value_error(2, "cannot have a fractional part");
55-
return;
56-
}
57-
exponent = bc_num2long (num2);
58-
if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) {
59-
/* 2nd argument from PHP_FUNCTION(bcpow) */
60-
zend_argument_value_error(2, "is too large");
61-
return;
62-
}
63-
6450
/* Special case if exponent is a zero. */
6551
if (exponent == 0) {
6652
bc_free_num (result);
@@ -114,3 +100,20 @@ void bc_raise(bc_num num1, bc_num num2, bc_num *result, size_t scale)
114100
}
115101
bc_free_num (&power);
116102
}
103+
104+
/* This is used internally by BCMath */
105+
void bc_raise_bc_exponent(bc_num base, bc_num expo, bc_num *result, size_t scale)
106+
{
107+
/* Exponent must not have fractional part */
108+
assert(expo->n_scale == 0);
109+
110+
long exponent = bc_num2long(expo);
111+
/* Exponent must be properly convertable to long */
112+
if (exponent == 0 && (expo->n_len > 1 || expo->n_value[0] != 0)) {
113+
assert(false && "Exponent is not well formed in internal call");
114+
//assert(exponent != 0 || (expo->n_len == 0 && expo->n_value[0] == 0));
115+
}
116+
//assert(exponent != 0 || (expo->n_len == 0 && expo->n_value[0] == 0));
117+
bc_raise(base, exponent, result, scale);
118+
}
119+

ext/bcmath/libbcmath/src/sqrt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ bool bc_sqrt(bc_num *num, size_t scale)
8181
bc_int2num (&guess1,(*num)->n_len);
8282
bc_multiply (guess1, point5, &guess1, 0);
8383
guess1->n_scale = 0;
84-
bc_raise (guess, guess1, &guess, 0);
84+
bc_raise_bc_exponent(guess, guess1, &guess, 0);
8585
bc_free_num (&guess1);
8686
cscale = 3;
8787
}

0 commit comments

Comments
 (0)