Skip to content

Commit d7e13f6

Browse files
committed
ext/gmp: Refactor gmp_div_qr() to use new ZPP specifier
1 parent a292342 commit d7e13f6

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
@@ -262,7 +262,6 @@ typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
262262
typedef gmp_ulong (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, gmp_ulong);
263263

264264
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);
265-
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);
266265
static inline void gmp_zval_unary_op(zval *return_value, zval *a_arg, gmp_unary_op_t gmp_op);
267266

268267
static void gmp_mpz_tdiv_q_ui(mpz_ptr a, mpz_srcptr b, gmp_ulong c) {
@@ -890,58 +889,6 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *
890889
}
891890
/* }}} */
892891

893-
/* {{{ gmp_zval_binary_ui_op2
894-
Execute GMP binary operation which returns 2 values.
895-
*/
896-
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)
897-
{
898-
mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result1, gmpnum_result2;
899-
gmp_temp_t temp_a, temp_b;
900-
zval result1, result2;
901-
902-
FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a, 1);
903-
904-
if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) {
905-
gmpnum_b = NULL;
906-
temp_b.is_used = 0;
907-
} else {
908-
FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a, 2);
909-
}
910-
911-
if (check_b_zero) {
912-
int b_is_zero = 0;
913-
if (!gmpnum_b) {
914-
b_is_zero = (Z_LVAL_P(b_arg) == 0);
915-
} else {
916-
b_is_zero = !mpz_cmp_ui(gmpnum_b, 0);
917-
}
918-
919-
if (b_is_zero) {
920-
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
921-
FREE_GMP_TEMP(temp_a);
922-
FREE_GMP_TEMP(temp_b);
923-
RETURN_THROWS();
924-
}
925-
}
926-
927-
gmp_create(&result1, &gmpnum_result1);
928-
gmp_create(&result2, &gmpnum_result2);
929-
930-
array_init(return_value);
931-
add_next_index_zval(return_value, &result1);
932-
add_next_index_zval(return_value, &result2);
933-
934-
if (!gmpnum_b) {
935-
gmp_ui_op(gmpnum_result1, gmpnum_result2, gmpnum_a, (gmp_ulong) Z_LVAL_P(b_arg));
936-
} else {
937-
gmp_op(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
938-
}
939-
940-
FREE_GMP_TEMP(temp_a);
941-
FREE_GMP_TEMP(temp_b);
942-
}
943-
/* }}} */
944-
945892
/* {{{ _gmp_binary_ui_op */
946893
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)
947894
{
@@ -1170,32 +1117,48 @@ ZEND_FUNCTION(gmp_strval)
11701117
/* {{{ Divide a by b, returns quotient and reminder */
11711118
ZEND_FUNCTION(gmp_div_qr)
11721119
{
1173-
zval *a_arg, *b_arg;
1120+
mpz_ptr gmpnum_a, gmpnum_b;
11741121
zend_long round = GMP_ROUND_ZERO;
11751122

11761123
ZEND_PARSE_PARAMETERS_START(2, 3)
1177-
Z_PARAM_ZVAL(a_arg)
1178-
Z_PARAM_ZVAL(b_arg)
1124+
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_a)
1125+
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_b)
11791126
Z_PARAM_OPTIONAL
11801127
Z_PARAM_LONG(round)
11811128
ZEND_PARSE_PARAMETERS_END();
11821129

1183-
switch (round) {
1184-
case GMP_ROUND_ZERO:
1185-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_tdiv_qr, mpz_tdiv_qr_ui, 1);
1186-
break;
1187-
case GMP_ROUND_PLUSINF:
1188-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_cdiv_qr, mpz_cdiv_qr_ui, 1);
1189-
break;
1190-
case GMP_ROUND_MINUSINF:
1191-
gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_fdiv_qr, mpz_fdiv_qr_ui, 1);
1192-
break;
1193-
default:
1130+
if (mpz_cmp_ui(gmpnum_b, 0) == 0) {
1131+
zend_argument_error(zend_ce_division_by_zero_error, 2, "Division by zero");
1132+
RETURN_THROWS();
1133+
}
1134+
1135+
if (round != GMP_ROUND_ZERO && round != GMP_ROUND_PLUSINF && round != GMP_ROUND_MINUSINF) {
11941136
zend_argument_value_error(3, "must be one of GMP_ROUND_ZERO, GMP_ROUND_PLUSINF, or GMP_ROUND_MINUSINF");
11951137
RETURN_THROWS();
11961138
}
1139+
1140+
zval result1, result2;
1141+
mpz_ptr gmpnum_result1, gmpnum_result2;
1142+
gmp_create(&result1, &gmpnum_result1);
1143+
gmp_create(&result2, &gmpnum_result2);
1144+
1145+
array_init(return_value);
1146+
add_next_index_zval(return_value, &result1);
1147+
add_next_index_zval(return_value, &result2);
1148+
1149+
switch (round) {
1150+
case GMP_ROUND_ZERO:
1151+
mpz_tdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1152+
break;
1153+
case GMP_ROUND_PLUSINF:
1154+
mpz_cdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1155+
break;
1156+
case GMP_ROUND_MINUSINF:
1157+
mpz_fdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b);
1158+
break;
1159+
EMPTY_SWITCH_DEFAULT_CASE()
1160+
}
11971161
}
1198-
/* }}} */
11991162

12001163
/* {{{ Divide a by b, returns reminder only */
12011164
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)