Exemple #1
0
/* {{{ gmp_zval_binary_ui_op2_ex
   Execute GMP binary operation which returns 2 values.
   May return GMP resources or longs if operation allows this.
*/
static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC)
{
	mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result1, *gmpnum_result2;
	zval r;
	int use_ui = 0;
	unsigned long long_result = 0;
	int arga_tmp = 0, argb_tmp = 0;

	FETCH_GMP_ZVAL(gmpnum_a, a_arg, arga_tmp);

	if (gmp_ui_op && Z_TYPE_PP(b_arg) == IS_LONG && Z_LVAL_PP(b_arg) >= 0) {
		/* use _ui function */
		use_ui = 1;
	} else {
		FETCH_GMP_ZVAL(gmpnum_b, b_arg, argb_tmp);
	}

	if(check_b_zero) {
		int b_is_zero = 0;
		if(use_ui) {
			b_is_zero = (Z_LVAL_PP(b_arg) == 0);
		} else {
			b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0);
		}

		if(b_is_zero) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed");
			FREE_GMP_TEMP(arga_tmp);
			FREE_GMP_TEMP(argb_tmp);
			RETURN_FALSE;
		}
	}

	INIT_GMP_NUM(gmpnum_result1);
	INIT_GMP_NUM(gmpnum_result2);

	if (use_ui && gmp_ui_op) {
		if (allow_ui_return) {
			long_result = gmp_ui_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg));
		} else {
			gmp_ui_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg));
		}
	} else {
		gmp_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, *gmpnum_b);
	}

	FREE_GMP_TEMP(arga_tmp);
	FREE_GMP_TEMP(argb_tmp);

	array_init(return_value);
	ZEND_REGISTER_RESOURCE(&r, gmpnum_result1, le_gmp);
	add_index_resource(return_value, 0, Z_LVAL(r));
	if (use_ui && allow_ui_return) {
		mpz_clear(*gmpnum_result2);
		add_index_long(return_value, 1, long_result);
	} else {
		ZEND_REGISTER_RESOURCE(&r, gmpnum_result2, le_gmp);
		add_index_resource(return_value, 1, Z_LVAL(r));
	}
}
Exemple #2
0
/* {{{ gmp_zval_binary_ui_op_ex
   Execute GMP binary operation.
   May return GMP resource or long if operation allows this
*/
static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return, int check_b_zero, int use_sign TSRMLS_DC) 
{
	mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result;
	unsigned long long_result = 0;
	int use_ui = 0;
	int arga_tmp = 0, argb_tmp = 0;

	FETCH_GMP_ZVAL(gmpnum_a, a_arg, arga_tmp);
	
	if (gmp_ui_op && Z_TYPE_PP(b_arg) == IS_LONG && Z_LVAL_PP(b_arg) >= 0) {
		use_ui = 1;
	} else {
		FETCH_GMP_ZVAL(gmpnum_b, b_arg, argb_tmp);
	}

	if(check_b_zero) {
		int b_is_zero = 0;
		if(use_ui) {
			b_is_zero = (Z_LVAL_PP(b_arg) == 0);
		} else {
			b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0);
		}

		if(b_is_zero) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed");
			FREE_GMP_TEMP(arga_tmp);
			FREE_GMP_TEMP(argb_tmp);
			RETURN_FALSE;
		}
	}

	INIT_GMP_NUM(gmpnum_result);

	if (use_ui && gmp_ui_op) {
		if (allow_ui_return) {
			long_result = gmp_ui_op(*gmpnum_result, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg));
			if (use_sign && mpz_sgn(*gmpnum_a) == -1) {
				long_result = -long_result;
			}
		} else {
			gmp_ui_op(*gmpnum_result, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg));
		}
	} else {
		gmp_op(*gmpnum_result, *gmpnum_a, *gmpnum_b);
	}

	FREE_GMP_TEMP(arga_tmp);
	FREE_GMP_TEMP(argb_tmp);

	if (use_ui && allow_ui_return) {
		FREE_GMP_NUM(gmpnum_result);
		RETURN_LONG((long)long_result);
	} else {
		ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
	}
}
Exemple #3
0
/* {{{ gmp_zval_unary_ui_op
 */
static inline void gmp_zval_unary_ui_op(zval *return_value, zval **a_arg, gmp_unary_ui_op_t gmp_op TSRMLS_DC)
{
	mpz_t *gmpnum_result;

	convert_to_long_ex(a_arg);

	INIT_GMP_NUM(gmpnum_result);
	gmp_op(*gmpnum_result, Z_LVAL_PP(a_arg));

	ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
}
Exemple #4
0
/* {{{ gmp_zval_unary_op
 */
static inline void gmp_zval_unary_op(zval *return_value, zval **a_arg, gmp_unary_op_t gmp_op TSRMLS_DC) 
{
	mpz_t *gmpnum_a, *gmpnum_result;
	int temp_a;
	
	FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a);

	INIT_GMP_NUM(gmpnum_result);
	gmp_op(*gmpnum_result, *gmpnum_a);

	FREE_GMP_TEMP(temp_a);
	ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
}