Skip to content

Commit 1f5ba59

Browse files
committed
ext/gmp: Refactor gmp_div_qr() to use new ZPP specifier
1 parent 376c148 commit 1f5ba59

File tree

3 files changed

+34
-71
lines changed

3 files changed

+34
-71
lines changed

ext/gmp/gmp.c

Lines changed: 31 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,6 @@ typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
266266
typedef gmp_ulong (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, gmp_ulong);
267267

268268
static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, bool check_b_zero, bool is_operator);
269-
static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int check_b_zero);
270269
static inline void gmp_zval_unary_op(zval *return_value, zval *a_arg, gmp_unary_op_t gmp_op);
271270

272271
static void gmp_mpz_tdiv_q_ui(mpz_ptr a, mpz_srcptr b, gmp_ulong c) {
@@ -894,58 +893,6 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *
894893
}
895894
/* }}} */
896895

897-
/* {{{ gmp_zval_binary_ui_op2
898-
Execute GMP binary operation which returns 2 values.
899-
*/
900-
static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int check_b_zero)
901-
{
902-
mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result1, gmpnum_result2;
903-
gmp_temp_t temp_a, temp_b;
904-
zval result1, result2;
905-
906-
FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a, 1);
907-
908-
if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) {
909-
gmpnum_b = NULL;
910-
temp_b.is_used = 0;
911-
} else {
912-
FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a, 2);
913-
}
914-
915-
if (check_b_zero) {
916-
int b_is_zero = 0;
917-
if (!gmpnum_b) {
918-
b_is_zero = (Z_LVAL_P(b_arg) == 0);
919-
} else {
920-
b_is_zero = !mpz_cmp_ui(gmpnum_b, 0);
921-
}
922-
923-
if (b_is_zero) {
924-
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
925-
FREE_GMP_TEMP(temp_a);
926-
FREE_GMP_TEMP(temp_b);
927-
RETURN_THROWS();
928-
}
929-
}
930-
931-
gmp_create(&result1, &gmpnum_result1);
932-
gmp_create(&result2, &gmpnum_result2);
933-
934-
array_init(return_value);
935-
add_next_index_zval(return_value, &result1);
936-
add_next_index_zval(return_value, &result2);
937-
938-
if (!gmpnum_b) {
939-
gmp_ui_op(gmpnum_result1, gmpnum_result2, gmpnum_a, (gmp_ulong) Z_LVAL_P(b_arg));
940-
} else {
941-
gmp_op(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
942-
}
943-
944-
FREE_GMP_TEMP(temp_a);
945-
FREE_GMP_TEMP(temp_b);
946-
}
947-
/* }}} */
948-
949896
/* {{{ _gmp_binary_ui_op */
950897
static inline void _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int check_b_zero)
951898
{
@@ -1174,32 +1121,48 @@ ZEND_FUNCTION(gmp_strval)
11741121
/* {{{ Divide a by b, returns quotient and reminder */
11751122
ZEND_FUNCTION(gmp_div_qr)
11761123
{
1177-
zval *a_arg, *b_arg;
1124+
mpz_ptr gmpnum_a, gmpnum_b;
11781125
zend_long round = GMP_ROUND_ZERO;
11791126

11801127
ZEND_PARSE_PARAMETERS_START(2, 3)
1181-
Z_PARAM_ZVAL(a_arg)
1182-
Z_PARAM_ZVAL(b_arg)
1128+
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_a)
1129+
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_b)
11831130
Z_PARAM_OPTIONAL
11841131
Z_PARAM_LONG(round)
11851132
ZEND_PARSE_PARAMETERS_END();
11861133

1187-
switch (round) {
1188-
case GMP_ROUND_ZERO:
1189-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_tdiv_qr, mpz_tdiv_qr_ui, 1);
1190-
break;
1191-
case GMP_ROUND_PLUSINF:
1192-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_cdiv_qr, mpz_cdiv_qr_ui, 1);
1193-
break;
1194-
case GMP_ROUND_MINUSINF:
1195-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_fdiv_qr, mpz_fdiv_qr_ui, 1);
1196-
break;
1197-
default:
1134+
if (mpz_cmp_ui(gmpnum_b, 0) == 0) {
1135+
zend_argument_error(zend_ce_division_by_zero_error, 2, "Division by zero");
1136+
RETURN_THROWS();
1137+
}
1138+
1139+
if (round != GMP_ROUND_ZERO && round != GMP_ROUND_PLUSINF && round != GMP_ROUND_MINUSINF) {
11981140
zend_argument_value_error(3, "must be one of GMP_ROUND_ZERO, GMP_ROUND_PLUSINF, or GMP_ROUND_MINUSINF");
11991141
RETURN_THROWS();
12001142
}
1143+
1144+
zval result1, result2;
1145+
mpz_ptr gmpnum_result1, gmpnum_result2;
1146+
gmp_create(&result1, &gmpnum_result1);
1147+
gmp_create(&result2, &gmpnum_result2);
1148+
1149+
array_init(return_value);
1150+
add_next_index_zval(return_value, &result1);
1151+
add_next_index_zval(return_value, &result2);
1152+
1153+
switch (round) {
1154+
case GMP_ROUND_ZERO:
1155+
mpz_tdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1156+
break;
1157+
case GMP_ROUND_PLUSINF:
1158+
mpz_cdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1159+
break;
1160+
case GMP_ROUND_MINUSINF:
1161+
mpz_fdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1162+
break;
1163+
EMPTY_SWITCH_DEFAULT_CASE()
1164+
}
12011165
}
1202-
/* }}} */
12031166

12041167
/* {{{ Divide a by b, returns reminder only */
12051168
ZEND_FUNCTION(gmp_div_r)

ext/gmp/tests/bug32773.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ try {
2323
10 + 0 = 10
2424
10 + "0" = 10
2525
Division by zero
26-
Division by zero
26+
gmp_div_qr(): Argument #2 ($num2) Division by zero

ext/gmp/tests/gmp_div_qr.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ array(2) {
6060
string(1) "0"
6161
}
6262
}
63-
Division by zero
64-
Division by zero
63+
gmp_div_qr(): Argument #2 ($num2) Division by zero
64+
gmp_div_qr(): Argument #2 ($num2) Division by zero
6565
array(2) {
6666
[0]=>
6767
object(GMP)#2 (1) {

0 commit comments

Comments
 (0)