@@ -85,11 +85,6 @@ PHP_GMP_API zend_class_entry *php_gmp_class_entry(void) {
8585 return gmp_ce ;
8686}
8787
88- typedef struct _gmp_temp {
89- mpz_t num ;
90- bool is_used ;
91- } gmp_temp_t ;
92-
9388#define GMP_MAX_BASE 62
9489
9590#define GMP_51_OR_NEWER \
@@ -106,63 +101,8 @@ typedef struct _gmp_temp {
106101#define GET_GMP_FROM_ZVAL (zval ) \
107102 GET_GMP_OBJECT_FROM_OBJ(Z_OBJ_P(zval))->num
108103
109- /* The FETCH_GMP_ZVAL_* family of macros is used to fetch a gmp number
110- * (mpz_ptr) from a zval. If the zval is not a GMP instance, then we
111- * try to convert the value to a temporary gmp number using convert_to_gmp.
112- * This temporary number is stored in the temp argument, which is of type
113- * gmp_temp_t. This temporary value needs to be freed lateron using the
114- * FREE_GMP_TEMP macro.
115- *
116- * If the conversion to a gmp number fails, the macros RETURN_THROWS() due to TypeError.
117- * The _DEP / _DEP_DEP variants additionally free the temporary values
118- * passed in the last / last two arguments.
119- *
120- * If one zval can sometimes be fetched as a long you have to set the
121- * is_used member of the corresponding gmp_temp_t value to 0, otherwise
122- * the FREE_GMP_TEMP and *_DEP macros will not work properly.
123- *
124- * The three FETCH_GMP_ZVAL_* macros below are mostly copy & paste code
125- * as I couldn't find a way to combine them.
126- */
127-
128- #define FREE_GMP_TEMP (temp ) \
129- if (temp.is_used) { \
130- mpz_clear(temp.num); \
131- }
132-
133- #define FETCH_GMP_ZVAL_DEP (gmpnumber , zval , temp , dep , arg_pos ) \
134- if (IS_GMP(zval)) { \
135- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
136- temp.is_used = 0; \
137- } else { \
138- mpz_init(temp.num); \
139- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
140- mpz_clear(temp.num); \
141- FREE_GMP_TEMP(dep); \
142- RETURN_THROWS(); \
143- } \
144- temp.is_used = 1; \
145- gmpnumber = temp.num; \
146- }
147-
148- #define FETCH_GMP_ZVAL (gmpnumber , zval , temp , arg_pos ) \
149- if (IS_GMP(zval)) { \
150- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
151- temp.is_used = 0; \
152- } else { \
153- mpz_init(temp.num); \
154- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
155- mpz_clear(temp.num); \
156- RETURN_THROWS(); \
157- } \
158- temp.is_used = 1; \
159- gmpnumber = temp.num; \
160- }
161-
162104static void gmp_strval (zval * result , mpz_t gmpnum , int base );
163105static zend_result convert_zstr_to_gmp (mpz_t gmp_number , const zend_string * val , zend_long base , uint32_t arg_pos );
164- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos );
165- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator );
166106
167107static bool gmp_zend_parse_arg_into_mpz_ex (
168108 zval * arg ,
@@ -516,18 +456,24 @@ static zend_result gmp_do_operation(uint8_t opcode, zval *result, zval *op1, zva
516456
517457static int gmp_compare (zval * op1 , zval * op2 ) /* {{{ */
518458{
519- zval result ;
520-
521- gmp_cmp (& result , op1 , op2 , /* is_operator */ true);
459+ mpz_ptr gmp_op1 , gmp_op2 ;
460+ bool status = false;
522461
523- /* An error/exception occurs if one of the operands is not a numeric string
524- * or an object which is different from GMP */
525- if (EG (exception )) {
526- return 1 ;
462+ status = gmp_zend_parse_arg_into_mpz_ex (op1 , & gmp_op1 , 1 , true);
463+ if (!status ) {
464+ if (!EG (exception )) {
465+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op1 ));
466+ }
467+ return ZEND_UNCOMPARABLE ;
468+ }
469+ status = gmp_zend_parse_arg_into_mpz_ex (op2 , & gmp_op2 , 2 , true);
470+ if (!status ) {
471+ if (!EG (exception )) {
472+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op2 ));
473+ }
474+ return ZEND_UNCOMPARABLE ;
527475 }
528- /* result can only be a zend_long if gmp_cmp hasn't thrown an Error */
529- ZEND_ASSERT (Z_TYPE (result ) == IS_LONG );
530- return Z_LVAL (result );
476+ return mpz_cmp (gmp_op1 , gmp_op2 );
531477}
532478/* }}} */
533479
@@ -707,44 +653,6 @@ static zend_result convert_zstr_to_gmp(mpz_t gmp_number, const zend_string *val,
707653 return SUCCESS ;
708654}
709655
710- /* {{{ convert_to_gmp
711- * Convert zval to be gmp number */
712- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos )
713- {
714- switch (Z_TYPE_P (val )) {
715- case IS_LONG :
716- mpz_set_si (gmpnumber , Z_LVAL_P (val ));
717- return SUCCESS ;
718- case IS_STRING : {
719- return convert_zstr_to_gmp (gmpnumber , Z_STR_P (val ), base , arg_pos );
720- }
721- case IS_NULL :
722- /* Just reject null for operator overloading */
723- if (arg_pos == 0 ) {
724- zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_type_name (val ));
725- return FAILURE ;
726- }
727- ZEND_FALLTHROUGH ;
728- default : {
729- zend_long lval ;
730- if (!zend_parse_arg_long_slow (val , & lval , arg_pos )) {
731- if (arg_pos == 0 ) {
732- zend_type_error (
733- "Number must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
734- } else {
735- zend_argument_type_error (arg_pos ,
736- "must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
737- }
738- return FAILURE ;
739- }
740-
741- mpz_set_si (gmpnumber , lval );
742- return SUCCESS ;
743- }
744- }
745- }
746- /* }}} */
747-
748656static void gmp_strval (zval * result , mpz_t gmpnum , int base ) /* {{{ */
749657{
750658 size_t num_len ;
@@ -776,35 +684,6 @@ static void gmp_strval(zval *result, mpz_t gmpnum, int base) /* {{{ */
776684}
777685/* }}} */
778686
779- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator ) /* {{{ */
780- {
781- mpz_ptr gmpnum_a , gmpnum_b ;
782- gmp_temp_t temp_a , temp_b ;
783- bool use_si = 0 ;
784- zend_long res ;
785-
786- FETCH_GMP_ZVAL (gmpnum_a , a_arg , temp_a , is_operator ? 0 : 1 );
787-
788- if (Z_TYPE_P (b_arg ) == IS_LONG ) {
789- use_si = 1 ;
790- temp_b .is_used = 0 ;
791- } else {
792- FETCH_GMP_ZVAL_DEP (gmpnum_b , b_arg , temp_b , temp_a , is_operator ? 0 : 2 );
793- }
794-
795- if (use_si ) {
796- res = mpz_cmp_si (gmpnum_a , Z_LVAL_P (b_arg ));
797- } else {
798- res = mpz_cmp (gmpnum_a , gmpnum_b );
799- }
800-
801- FREE_GMP_TEMP (temp_a );
802- FREE_GMP_TEMP (temp_b );
803-
804- RETURN_LONG (res );
805- }
806- /* }}} */
807-
808687static bool gmp_verify_base (zend_long base , uint32_t arg_num )
809688{
810689 if (base && (base < 2 || base > GMP_MAX_BASE )) {
0 commit comments