@@ -86,11 +86,6 @@ PHP_GMP_API zend_class_entry *php_gmp_class_entry(void) {
8686 return gmp_ce ;
8787}
8888
89- typedef struct _gmp_temp {
90- mpz_t num ;
91- bool is_used ;
92- } gmp_temp_t ;
93-
9489#define GMP_MAX_BASE 62
9590
9691#define GMP_51_OR_NEWER \
@@ -107,63 +102,8 @@ typedef struct _gmp_temp {
107102#define GET_GMP_FROM_ZVAL (zval ) \
108103 GET_GMP_OBJECT_FROM_OBJ(Z_OBJ_P(zval))->num
109104
110- /* The FETCH_GMP_ZVAL_* family of macros is used to fetch a gmp number
111- * (mpz_ptr) from a zval. If the zval is not a GMP instance, then we
112- * try to convert the value to a temporary gmp number using convert_to_gmp.
113- * This temporary number is stored in the temp argument, which is of type
114- * gmp_temp_t. This temporary value needs to be freed lateron using the
115- * FREE_GMP_TEMP macro.
116- *
117- * If the conversion to a gmp number fails, the macros RETURN_THROWS() due to TypeError.
118- * The _DEP / _DEP_DEP variants additionally free the temporary values
119- * passed in the last / last two arguments.
120- *
121- * If one zval can sometimes be fetched as a long you have to set the
122- * is_used member of the corresponding gmp_temp_t value to 0, otherwise
123- * the FREE_GMP_TEMP and *_DEP macros will not work properly.
124- *
125- * The three FETCH_GMP_ZVAL_* macros below are mostly copy & paste code
126- * as I couldn't find a way to combine them.
127- */
128-
129- #define FREE_GMP_TEMP (temp ) \
130- if (temp.is_used) { \
131- mpz_clear(temp.num); \
132- }
133-
134- #define FETCH_GMP_ZVAL_DEP (gmpnumber , zval , temp , dep , arg_pos ) \
135- if (IS_GMP(zval)) { \
136- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
137- temp.is_used = 0; \
138- } else { \
139- mpz_init(temp.num); \
140- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
141- mpz_clear(temp.num); \
142- FREE_GMP_TEMP(dep); \
143- RETURN_THROWS(); \
144- } \
145- temp.is_used = 1; \
146- gmpnumber = temp.num; \
147- }
148-
149- #define FETCH_GMP_ZVAL (gmpnumber , zval , temp , arg_pos ) \
150- if (IS_GMP(zval)) { \
151- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
152- temp.is_used = 0; \
153- } else { \
154- mpz_init(temp.num); \
155- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
156- mpz_clear(temp.num); \
157- RETURN_THROWS(); \
158- } \
159- temp.is_used = 1; \
160- gmpnumber = temp.num; \
161- }
162-
163105static void gmp_strval (zval * result , mpz_t gmpnum , int base );
164106static zend_result convert_zstr_to_gmp (mpz_t gmp_number , const zend_string * val , zend_long base , uint32_t arg_pos );
165- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos );
166- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator );
167107
168108static bool gmp_zend_parse_arg_into_mpz_ex (
169109 zval * arg ,
@@ -520,18 +460,24 @@ static zend_result gmp_do_operation(uint8_t opcode, zval *result, zval *op1, zva
520460
521461static int gmp_compare (zval * op1 , zval * op2 ) /* {{{ */
522462{
523- zval result ;
524-
525- gmp_cmp (& result , op1 , op2 , /* is_operator */ true);
463+ mpz_ptr gmp_op1 , gmp_op2 ;
464+ bool status = false;
526465
527- /* An error/exception occurs if one of the operands is not a numeric string
528- * or an object which is different from GMP */
529- if (EG (exception )) {
530- return 1 ;
466+ status = gmp_zend_parse_arg_into_mpz_ex (op1 , & gmp_op1 , 1 , true);
467+ if (!status ) {
468+ if (!EG (exception )) {
469+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op1 ));
470+ }
471+ return ZEND_UNCOMPARABLE ;
472+ }
473+ status = gmp_zend_parse_arg_into_mpz_ex (op2 , & gmp_op2 , 2 , true);
474+ if (!status ) {
475+ if (!EG (exception )) {
476+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op2 ));
477+ }
478+ return ZEND_UNCOMPARABLE ;
531479 }
532- /* result can only be a zend_long if gmp_cmp hasn't thrown an Error */
533- ZEND_ASSERT (Z_TYPE (result ) == IS_LONG );
534- return Z_LVAL (result );
480+ return mpz_cmp (gmp_op1 , gmp_op2 );
535481}
536482/* }}} */
537483
@@ -715,44 +661,6 @@ static zend_result convert_zstr_to_gmp(mpz_t gmp_number, const zend_string *val,
715661 return SUCCESS ;
716662}
717663
718- /* {{{ convert_to_gmp
719- * Convert zval to be gmp number */
720- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos )
721- {
722- switch (Z_TYPE_P (val )) {
723- case IS_LONG :
724- mpz_set_si (gmpnumber , Z_LVAL_P (val ));
725- return SUCCESS ;
726- case IS_STRING : {
727- return convert_zstr_to_gmp (gmpnumber , Z_STR_P (val ), base , arg_pos );
728- }
729- case IS_NULL :
730- /* Just reject null for operator overloading */
731- if (arg_pos == 0 ) {
732- zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_type_name (val ));
733- return FAILURE ;
734- }
735- ZEND_FALLTHROUGH ;
736- default : {
737- zend_long lval ;
738- if (!zend_parse_arg_long_slow (val , & lval , arg_pos )) {
739- if (arg_pos == 0 ) {
740- zend_type_error (
741- "Number must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
742- } else {
743- zend_argument_type_error (arg_pos ,
744- "must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
745- }
746- return FAILURE ;
747- }
748-
749- mpz_set_si (gmpnumber , lval );
750- return SUCCESS ;
751- }
752- }
753- }
754- /* }}} */
755-
756664static void gmp_strval (zval * result , mpz_t gmpnum , int base ) /* {{{ */
757665{
758666 size_t num_len ;
@@ -784,35 +692,6 @@ static void gmp_strval(zval *result, mpz_t gmpnum, int base) /* {{{ */
784692}
785693/* }}} */
786694
787- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator ) /* {{{ */
788- {
789- mpz_ptr gmpnum_a , gmpnum_b ;
790- gmp_temp_t temp_a , temp_b ;
791- bool use_si = 0 ;
792- zend_long res ;
793-
794- FETCH_GMP_ZVAL (gmpnum_a , a_arg , temp_a , is_operator ? 0 : 1 );
795-
796- if (Z_TYPE_P (b_arg ) == IS_LONG ) {
797- use_si = 1 ;
798- temp_b .is_used = 0 ;
799- } else {
800- FETCH_GMP_ZVAL_DEP (gmpnum_b , b_arg , temp_b , temp_a , is_operator ? 0 : 2 );
801- }
802-
803- if (use_si ) {
804- res = mpz_cmp_si (gmpnum_a , Z_LVAL_P (b_arg ));
805- } else {
806- res = mpz_cmp (gmpnum_a , gmpnum_b );
807- }
808-
809- FREE_GMP_TEMP (temp_a );
810- FREE_GMP_TEMP (temp_b );
811-
812- RETURN_LONG (res );
813- }
814- /* }}} */
815-
816695static bool gmp_verify_base (zend_long base , uint32_t arg_num )
817696{
818697 if (base && (base < 2 || base > GMP_MAX_BASE )) {
0 commit comments