@@ -90,11 +90,6 @@ PHP_GMP_API zend_class_entry *php_gmp_class_entry(void) {
90
90
return gmp_ce ;
91
91
}
92
92
93
- typedef struct _gmp_temp {
94
- mpz_t num ;
95
- bool is_used ;
96
- } gmp_temp_t ;
97
-
98
93
#define GMP_MAX_BASE 62
99
94
100
95
#define GMP_51_OR_NEWER \
@@ -111,63 +106,8 @@ typedef struct _gmp_temp {
111
106
#define GET_GMP_FROM_ZVAL (zval ) \
112
107
GET_GMP_OBJECT_FROM_OBJ(Z_OBJ_P(zval))->num
113
108
114
- /* The FETCH_GMP_ZVAL_* family of macros is used to fetch a gmp number
115
- * (mpz_ptr) from a zval. If the zval is not a GMP instance, then we
116
- * try to convert the value to a temporary gmp number using convert_to_gmp.
117
- * This temporary number is stored in the temp argument, which is of type
118
- * gmp_temp_t. This temporary value needs to be freed lateron using the
119
- * FREE_GMP_TEMP macro.
120
- *
121
- * If the conversion to a gmp number fails, the macros RETURN_THROWS() due to TypeError.
122
- * The _DEP / _DEP_DEP variants additionally free the temporary values
123
- * passed in the last / last two arguments.
124
- *
125
- * If one zval can sometimes be fetched as a long you have to set the
126
- * is_used member of the corresponding gmp_temp_t value to 0, otherwise
127
- * the FREE_GMP_TEMP and *_DEP macros will not work properly.
128
- *
129
- * The three FETCH_GMP_ZVAL_* macros below are mostly copy & paste code
130
- * as I couldn't find a way to combine them.
131
- */
132
-
133
- #define FREE_GMP_TEMP (temp ) \
134
- if (temp.is_used) { \
135
- mpz_clear(temp.num); \
136
- }
137
-
138
- #define FETCH_GMP_ZVAL_DEP (gmpnumber , zval , temp , dep , arg_pos ) \
139
- if (IS_GMP(zval)) { \
140
- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
141
- temp.is_used = 0; \
142
- } else { \
143
- mpz_init(temp.num); \
144
- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
145
- mpz_clear(temp.num); \
146
- FREE_GMP_TEMP(dep); \
147
- RETURN_THROWS(); \
148
- } \
149
- temp.is_used = 1; \
150
- gmpnumber = temp.num; \
151
- }
152
-
153
- #define FETCH_GMP_ZVAL (gmpnumber , zval , temp , arg_pos ) \
154
- if (IS_GMP(zval)) { \
155
- gmpnumber = GET_GMP_FROM_ZVAL(zval); \
156
- temp.is_used = 0; \
157
- } else { \
158
- mpz_init(temp.num); \
159
- if (convert_to_gmp(temp.num, zval, 0, arg_pos) == FAILURE) { \
160
- mpz_clear(temp.num); \
161
- RETURN_THROWS(); \
162
- } \
163
- temp.is_used = 1; \
164
- gmpnumber = temp.num; \
165
- }
166
-
167
109
static void gmp_strval (zval * result , mpz_t gmpnum , int base );
168
110
static zend_result convert_zstr_to_gmp (mpz_t gmp_number , const zend_string * val , zend_long base , uint32_t arg_pos );
169
- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos );
170
- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator );
171
111
172
112
static bool gmp_zend_parse_arg_into_mpz_ex (
173
113
zval * arg ,
@@ -524,18 +464,24 @@ static zend_result gmp_do_operation(uint8_t opcode, zval *result, zval *op1, zva
524
464
525
465
static int gmp_compare (zval * op1 , zval * op2 ) /* {{{ */
526
466
{
527
- zval result ;
528
-
529
- gmp_cmp (& result , op1 , op2 , /* is_operator */ true);
467
+ mpz_ptr gmp_op1 , gmp_op2 ;
468
+ bool status = false;
530
469
531
- /* An error/exception occurs if one of the operands is not a numeric string
532
- * or an object which is different from GMP */
533
- if (EG (exception )) {
534
- return 1 ;
470
+ status = gmp_zend_parse_arg_into_mpz_ex (op1 , & gmp_op1 , 1 , true);
471
+ if (!status ) {
472
+ if (!EG (exception )) {
473
+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op1 ));
474
+ }
475
+ return ZEND_UNCOMPARABLE ;
476
+ }
477
+ status = gmp_zend_parse_arg_into_mpz_ex (op2 , & gmp_op2 , 2 , true);
478
+ if (!status ) {
479
+ if (!EG (exception )) {
480
+ zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_value_name (op2 ));
481
+ }
482
+ return ZEND_UNCOMPARABLE ;
535
483
}
536
- /* result can only be a zend_long if gmp_cmp hasn't thrown an Error */
537
- ZEND_ASSERT (Z_TYPE (result ) == IS_LONG );
538
- return Z_LVAL (result );
484
+ return mpz_cmp (gmp_op1 , gmp_op2 );
539
485
}
540
486
/* }}} */
541
487
@@ -719,44 +665,6 @@ static zend_result convert_zstr_to_gmp(mpz_t gmp_number, const zend_string *val,
719
665
return SUCCESS ;
720
666
}
721
667
722
- /* {{{ convert_to_gmp
723
- * Convert zval to be gmp number */
724
- static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos )
725
- {
726
- switch (Z_TYPE_P (val )) {
727
- case IS_LONG :
728
- mpz_set_si (gmpnumber , Z_LVAL_P (val ));
729
- return SUCCESS ;
730
- case IS_STRING : {
731
- return convert_zstr_to_gmp (gmpnumber , Z_STR_P (val ), base , arg_pos );
732
- }
733
- case IS_NULL :
734
- /* Just reject null for operator overloading */
735
- if (arg_pos == 0 ) {
736
- zend_type_error ("Number must be of type GMP|string|int, %s given" , zend_zval_type_name (val ));
737
- return FAILURE ;
738
- }
739
- ZEND_FALLTHROUGH ;
740
- default : {
741
- zend_long lval ;
742
- if (!zend_parse_arg_long_slow (val , & lval , arg_pos )) {
743
- if (arg_pos == 0 ) {
744
- zend_type_error (
745
- "Number must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
746
- } else {
747
- zend_argument_type_error (arg_pos ,
748
- "must be of type GMP|string|int, %s given" , zend_zval_value_name (val ));
749
- }
750
- return FAILURE ;
751
- }
752
-
753
- mpz_set_si (gmpnumber , lval );
754
- return SUCCESS ;
755
- }
756
- }
757
- }
758
- /* }}} */
759
-
760
668
static void gmp_strval (zval * result , mpz_t gmpnum , int base ) /* {{{ */
761
669
{
762
670
size_t num_len ;
@@ -788,35 +696,6 @@ static void gmp_strval(zval *result, mpz_t gmpnum, int base) /* {{{ */
788
696
}
789
697
/* }}} */
790
698
791
- static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator ) /* {{{ */
792
- {
793
- mpz_ptr gmpnum_a , gmpnum_b ;
794
- gmp_temp_t temp_a , temp_b ;
795
- bool use_si = 0 ;
796
- zend_long res ;
797
-
798
- FETCH_GMP_ZVAL (gmpnum_a , a_arg , temp_a , is_operator ? 0 : 1 );
799
-
800
- if (Z_TYPE_P (b_arg ) == IS_LONG ) {
801
- use_si = 1 ;
802
- temp_b .is_used = 0 ;
803
- } else {
804
- FETCH_GMP_ZVAL_DEP (gmpnum_b , b_arg , temp_b , temp_a , is_operator ? 0 : 2 );
805
- }
806
-
807
- if (use_si ) {
808
- res = mpz_cmp_si (gmpnum_a , Z_LVAL_P (b_arg ));
809
- } else {
810
- res = mpz_cmp (gmpnum_a , gmpnum_b );
811
- }
812
-
813
- FREE_GMP_TEMP (temp_a );
814
- FREE_GMP_TEMP (temp_b );
815
-
816
- RETURN_LONG (res );
817
- }
818
- /* }}} */
819
-
820
699
static bool gmp_verify_base (zend_long base , uint32_t arg_num )
821
700
{
822
701
if (base && (base < 2 || base > GMP_MAX_BASE )) {
0 commit comments