55
55
56
56
ZEND_DECLARE_MODULE_GLOBALS (gmp )
57
57
static ZEND_GINIT_FUNCTION (gmp );
58
+ static ZEND_GSHUTDOWN_FUNCTION (gmp );
58
59
59
60
/* {{{ gmp_module_entry */
60
61
zend_module_entry gmp_module_entry = {
@@ -69,7 +70,7 @@ zend_module_entry gmp_module_entry = {
69
70
PHP_GMP_VERSION ,
70
71
ZEND_MODULE_GLOBALS (gmp ),
71
72
ZEND_GINIT (gmp ),
72
- NULL ,
73
+ ZEND_GSHUTDOWN ( gmp ) ,
73
74
NULL ,
74
75
STANDARD_MODULE_PROPERTIES_EX
75
76
};
@@ -179,14 +180,49 @@ if (IS_GMP(zval)) { \
179
180
gmpnumber = temp.num; \
180
181
}
181
182
182
- #define INIT_GMP_RETVAL (gmpnumber ) \
183
- gmp_create(return_value, &gmpnumber)
184
-
185
183
static void gmp_strval (zval * result , mpz_t gmpnum , int base );
186
184
static zend_result convert_zstr_to_gmp (mpz_t gmp_number , const zend_string * val , zend_long base , uint32_t arg_pos );
187
185
static zend_result convert_to_gmp (mpz_t gmpnumber , zval * val , zend_long base , uint32_t arg_pos );
188
186
static void gmp_cmp (zval * return_value , zval * a_arg , zval * b_arg , bool is_operator );
189
187
188
+ static bool gmp_zend_parse_arg_into_mpz (
189
+ zval * arg ,
190
+ mpz_ptr * destination_mpz_ptr ,
191
+ uint32_t arg_num
192
+ ) {
193
+ if (EXPECTED (Z_TYPE_P (arg ) == IS_OBJECT )) {
194
+ if (EXPECTED (instanceof_function (Z_OBJCE_P (arg ), gmp_ce ))) {
195
+ * destination_mpz_ptr = GET_GMP_FROM_ZVAL (arg );
196
+ return true;
197
+ }
198
+ return false;
199
+ }
200
+
201
+ * destination_mpz_ptr = GMPG (zpp_arg [arg_num - 1 ]);
202
+ if (Z_TYPE_P (arg ) == IS_STRING ) {
203
+ return convert_zstr_to_gmp (* destination_mpz_ptr , Z_STR_P (arg ), /* base */ 0 , arg_num ) != FAILURE ;
204
+ }
205
+
206
+ if (Z_TYPE_P (arg ) == IS_LONG ) {
207
+ mpz_set_si (* destination_mpz_ptr , Z_LVAL_P (arg ));
208
+ return true;
209
+ }
210
+ return false;
211
+ }
212
+
213
+ #define GMP_Z_PARAM_INTO_MPZ_PTR (destination_mpz_ptr ) \
214
+ Z_PARAM_PROLOGUE(0, 0); \
215
+ if (UNEXPECTED(!gmp_zend_parse_arg_into_mpz(_arg, &destination_mpz_ptr, _i))) { \
216
+ _error_code = ZPP_ERROR_FAILURE; \
217
+ if (!EG(exception)) { \
218
+ zend_argument_type_error(_i, "must be of type GMP|string|int, %s given", zend_zval_value_name(_arg)); \
219
+ } \
220
+ break; \
221
+ }
222
+
223
+ #define INIT_GMP_RETVAL (gmpnumber ) \
224
+ gmp_create(return_value, &gmpnumber)
225
+
190
226
/*
191
227
* The gmp_*_op functions provide an implementation for several common types
192
228
* of GMP functions. The gmp_zval_(unary|binary)_*_op functions have to be manually
@@ -591,9 +627,19 @@ static ZEND_GINIT_FUNCTION(gmp)
591
627
ZEND_TSRMLS_CACHE_UPDATE ();
592
628
#endif
593
629
gmp_globals -> rand_initialized = 0 ;
630
+ mpz_init (gmp_globals -> zpp_arg [0 ]);
631
+ mpz_init (gmp_globals -> zpp_arg [1 ]);
632
+ mpz_init (gmp_globals -> zpp_arg [2 ]);
594
633
}
595
634
/* }}} */
596
635
636
+ static ZEND_GSHUTDOWN_FUNCTION (gmp )
637
+ {
638
+ mpz_clear (gmp_globals -> zpp_arg [0 ]);
639
+ mpz_clear (gmp_globals -> zpp_arg [1 ]);
640
+ mpz_clear (gmp_globals -> zpp_arg [2 ]);
641
+ }
642
+
597
643
/* {{{ ZEND_MINIT_FUNCTION */
598
644
ZEND_MINIT_FUNCTION (gmp )
599
645
{
0 commit comments